mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-09 21:44:28 +00:00
Merge branch 'development' of https://github.com/Mbed-TLS/mbedtls into random_bye_on_hrr
This commit is contained in:
commit
368debd384
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "framework"]
|
||||
path = framework
|
||||
url = https://github.com/Mbed-TLS/mbedtls-framework
|
@ -5,6 +5,11 @@
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Include the framework submodule in the build
|
||||
submodules:
|
||||
include:
|
||||
- framework
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
|
@ -34,9 +34,15 @@ cmake_policy(SET CMP0011 NEW)
|
||||
cmake_policy(SET CMP0012 NEW)
|
||||
|
||||
if(TEST_CPP)
|
||||
project("Mbed TLS" LANGUAGES C CXX)
|
||||
project("Mbed TLS"
|
||||
LANGUAGES C CXX
|
||||
VERSION 3.5.2
|
||||
)
|
||||
else()
|
||||
project("Mbed TLS" LANGUAGES C)
|
||||
project("Mbed TLS"
|
||||
LANGUAGES C
|
||||
VERSION 3.5.2
|
||||
)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
@ -277,12 +283,19 @@ if(LIB_INSTALL_DIR)
|
||||
set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt")
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.")
|
||||
endif()
|
||||
add_subdirectory(framework)
|
||||
|
||||
add_subdirectory(include)
|
||||
|
||||
add_subdirectory(3rdparty)
|
||||
|
||||
add_subdirectory(library)
|
||||
|
||||
add_subdirectory(pkgconfig)
|
||||
|
||||
#
|
||||
# The C files in tests/src directory contain test code shared among test suites
|
||||
# and programs. This shared test code is compiled and linked to test suites and
|
||||
|
4
ChangeLog.d/8709.txt
Normal file
4
ChangeLog.d/8709.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Features
|
||||
* The new functions mbedtls_pk_copy_from_psa() and
|
||||
mbedtls_pk_copy_public_from_psa() provide ways to set up a PK context
|
||||
with the same content as a PSA key.
|
3
ChangeLog.d/8799.txt
Normal file
3
ChangeLog.d/8799.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* mbedtls_pem_read_buffer() now performs a check on the padding data of
|
||||
decrypted keys and it rejects invalid ones.
|
8
ChangeLog.d/8824.txt
Normal file
8
ChangeLog.d/8824.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Bugfix
|
||||
* Fix mbedtls_pk_sign(), mbedtls_pk_verify(), mbedtls_pk_decrypt() and
|
||||
mbedtls_pk_encrypt() on non-opaque RSA keys to honor the padding mode in
|
||||
the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled and the
|
||||
RSA context was configured for PKCS#1 v2.1 (PSS/OAEP), the sign/verify
|
||||
functions performed a PKCS#1 v1.5 signature instead and the
|
||||
encrypt/decrypt functions returned an error. Fixes #8824.
|
||||
|
6
ChangeLog.d/8825.txt
Normal file
6
ChangeLog.d/8825.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Features
|
||||
* mbedtls_psa_get_random() is always available as soon as
|
||||
MBEDTLS_PSA_CRYPTO_CLIENT is enabled at build time and psa_crypto_init() is
|
||||
called at runtime. This together with MBEDTLS_PSA_RANDOM_STATE can be
|
||||
used as random number generator function (f_rng) and context (p_rng) in
|
||||
legacy functions.
|
6
ChangeLog.d/8848.txt
Normal file
6
ChangeLog.d/8848.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Removals
|
||||
* Temporary function mbedtls_pk_wrap_as_opaque() is removed. To mimic the
|
||||
same behavior mbedtls_pk_get_psa_attributes() and
|
||||
mbedtls_pk_import_into_psa() can be used to import a PK key into PSA,
|
||||
while mbedtls_pk_setup_opaque() can be used to wrap a PSA key into a opaque
|
||||
PK context.
|
3
ChangeLog.d/add_get_ecp_group_id.txt
Normal file
3
ChangeLog.d/add_get_ecp_group_id.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Add new accessor to expose the private group id member of
|
||||
`mbedtls_ecdh_context` structure.
|
6
ChangeLog.d/add_ssl_session_accessors.txt
Normal file
6
ChangeLog.d/add_ssl_session_accessors.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Features
|
||||
* Add new accessors to expose the private session-id,
|
||||
session-id length, and ciphersuite-id members of
|
||||
`mbedtls_ssl_session` structure.
|
||||
Add new accessor to expose the ciphersuite-id of
|
||||
`mbedtls_ssl_ciphersuite_t` structure.Design ref: #8529
|
3
ChangeLog.d/benchmark-ecdh.txt
Normal file
3
ChangeLog.d/benchmark-ecdh.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* The benchmark program now reports times for both ephemeral and static
|
||||
ECDH in all ECDH configurations.
|
9
ChangeLog.d/domain_parameters.txt
Normal file
9
ChangeLog.d/domain_parameters.txt
Normal file
@ -0,0 +1,9 @@
|
||||
New deprecations
|
||||
* In the PSA API, domain parameters are no longer used for anything.
|
||||
They are deprecated and will be removed in a future version of the
|
||||
library.
|
||||
|
||||
Removals
|
||||
* In the PSA API, the experimental way to encode the public exponent of
|
||||
an RSA key as a domain parameter is no longer supported. Use
|
||||
psa_generate_key_ext() instead.
|
8
ChangeLog.d/ecp_write_key.txt
Normal file
8
ChangeLog.d/ecp_write_key.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Features
|
||||
* The new function mbedtls_ecp_write_key_ext() is similar to
|
||||
mbedtls_ecp_write_key(), but can be used without separately calculating
|
||||
the output length.
|
||||
|
||||
New deprecations
|
||||
* mbedtls_ecp_write_key() is deprecated in favor of
|
||||
mbedtls_ecp_write_key_ext().
|
4
ChangeLog.d/fix-ssl-session-serialization-config.txt
Normal file
4
ChangeLog.d/fix-ssl-session-serialization-config.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Bugfix
|
||||
* Fix missing bitflags in SSL session serialization headers. Their absence
|
||||
allowed SSL sessions saved in one configuration to be loaded in a
|
||||
different, incompatible configuration.
|
4
ChangeLog.d/gcm-large-tables.txt
Normal file
4
ChangeLog.d/gcm-large-tables.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Features
|
||||
* Add support for 8-bit GCM tables for Shoup's algorithm to speedup GCM
|
||||
operations when hardware accelerated AES is not present. Improves
|
||||
performance by around 30% on 64-bit Intel; 125% on Armv7-M.
|
3
ChangeLog.d/get_ticket_creation_time.txt
Normal file
3
ChangeLog.d/get_ticket_creation_time.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Add getter (mbedtls_ssl_session_get_ticket_creation_time()) to access
|
||||
`mbedtls_ssl_session.ticket_creation_time`.
|
4
ChangeLog.d/mbedtls_pk_import_into_psa.txt
Normal file
4
ChangeLog.d/mbedtls_pk_import_into_psa.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Features
|
||||
* The new functions mbedtls_pk_get_psa_attributes() and
|
||||
mbedtls_pk_import_into_psa() provide a uniform way to create a PSA
|
||||
key from a PK key.
|
4
ChangeLog.d/pkg-config-files-addition.txt
Normal file
4
ChangeLog.d/pkg-config-files-addition.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Features
|
||||
* Add pc files for pkg-config, e.g.:
|
||||
pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509)
|
||||
|
3
ChangeLog.d/psa_generate_key_ext.txt
Normal file
3
ChangeLog.d/psa_generate_key_ext.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* The new function psa_generate_key_ext() allows generating an RSA
|
||||
key pair with a custom public exponent.
|
6
ChangeLog.d/use_exp_mod_core.txt
Normal file
6
ChangeLog.d/use_exp_mod_core.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Changes
|
||||
* mbedtls_mpi_exp_mod and code that uses it, notably RSA and DHM operations,
|
||||
have changed their speed/memory compromise as part of a proactive security
|
||||
improvement. The new default value of MBEDTLS_MPI_WINDOW_SIZE roughly
|
||||
preserves the current speed, at the expense of increasing memory
|
||||
consumption.
|
5
ChangeLog.d/x509-add-ca_istrue.txt
Normal file
5
ChangeLog.d/x509-add-ca_istrue.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Features
|
||||
* Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of
|
||||
`mbedtls_x509_crt` structure. This requires setting
|
||||
the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's
|
||||
ext_types field.
|
14
Makefile
14
Makefile
@ -2,6 +2,20 @@ DESTDIR=/usr/local
|
||||
PREFIX=mbedtls_
|
||||
PERL ?= perl
|
||||
|
||||
ifneq (,$(filter-out lib library/%,$(or $(MAKECMDGOALS),all)))
|
||||
ifeq (,$(wildcard framework/exported.make))
|
||||
# Use the define keyword to get a multi-line message.
|
||||
# GNU make appends ". Stop.", so tweak the ending of our message accordingly.
|
||||
define error_message
|
||||
$(MBEDTLS_PATH)/framework/exported.make not found.
|
||||
Run `git submodule update --init` to fetch the submodule contents.
|
||||
This is a fatal error
|
||||
endef
|
||||
$(error $(error_message))
|
||||
endif
|
||||
include framework/exported.make
|
||||
endif
|
||||
|
||||
.SILENT:
|
||||
|
||||
.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
|
||||
|
@ -54,6 +54,10 @@ You need the following tools to build the library with the provided makefiles:
|
||||
* Microsoft Visual Studio 2013 or later (if using Visual Studio).
|
||||
* Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work).
|
||||
|
||||
### Git usage
|
||||
|
||||
The `development` branch and the `mbedtls-3.6` long-term support branch of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar).
|
||||
|
||||
### Generated source files in the development branch
|
||||
|
||||
The source code of Mbed TLS includes some files that are automatically generated by scripts and whose content depends only on the Mbed TLS source, not on the platform or on the library configuration. These files are not included in the development branch of Mbed TLS, but the generated files are included in official releases. This section explains how to generate the missing files in the development branch.
|
||||
|
@ -157,11 +157,11 @@ The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all fou
|
||||
|
||||
```
|
||||
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
|
||||
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
|
||||
PSA_ALG_IS_ECDSA(alg) &&
|
||||
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
|
||||
attributes->core.bits == 256 )
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
|
||||
psa_get_key_bits(attributes) == 256 )
|
||||
{
|
||||
status = p256_transparent_sign_hash( attributes,
|
||||
key_buffer,
|
||||
|
@ -50,7 +50,7 @@ Then use the [summary of API modules](#summary-of-api-modules), the table of con
|
||||
|
||||
To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled. (It is enabled in the default configuration.)
|
||||
|
||||
You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood.
|
||||
|
||||
By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API (configured by `MBEDTLS_XXX` macros). The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”.
|
||||
|
||||
@ -779,9 +779,9 @@ A finite-field Diffie-Hellman key can be used for key agreement with the algorit
|
||||
|
||||
The easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted.
|
||||
|
||||
For RSA keys, `psa_generate_key` always uses 65537 as the public exponent. If you need a different public exponent, use the legacy interface to create the key then import it as described in “[Importing legacy keys via the PK module](#importing-legacy-keys-via-the-pk-module)”.
|
||||
For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers.
|
||||
|
||||
To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of one of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
|
||||
To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). This function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), but only supports a single format that just contains the number(s) that make up the key, with very little metadata. The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details.
|
||||
|
||||
| Key type | PSA import/export format |
|
||||
| -------- | ------------------------ |
|
||||
@ -795,95 +795,45 @@ To create a key object from existing material, use [`psa_import_key`](https://mb
|
||||
|
||||
There is no equivalent of `mbedtls_pk_parse_keyfile` and `mbedtls_pk_parse_public_keyfile`. Either call the legacy function or load the file data manually.
|
||||
|
||||
A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsections for ways to use the PK module for key parsing and construct a PSA key object from the PK object.
|
||||
A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsection for how to use the PK module for key parsing and construct a PSA key object from the PK object.
|
||||
|
||||
#### Importing legacy keys via the PK module
|
||||
### Creating a PSA key via PK
|
||||
|
||||
You can use glue functions in the PK module to create a key object using the legacy API, then import that object into the PSA subsystem. This is useful for use cases that the PSA API does not currently cover, such as:
|
||||
You can use the PK module as an intermediate step to create an RSA or ECC key for use with PSA. This is useful for use cases that the PSA API does not currently cover, such as:
|
||||
|
||||
* Parsing a key in a format with metadata without knowing its type ahead of time.
|
||||
* Parsing a key in a format that the PK module supports, but `psa_import_key` doesn't.
|
||||
* Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`.
|
||||
* Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters.
|
||||
* Generating an RSA key with $e \ne 65537$.
|
||||
|
||||
#### Importing a PK key by wrapping
|
||||
For such use cases:
|
||||
|
||||
If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this workflow is useful are:
|
||||
1. First create a PK object with the desired key material.
|
||||
2. Call [`mbedtls_pk_get_psa_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a7aa7b33cffb6981d95d1632631de9244) to fill PSA attributes corresponding to the PK key. Pass one of the following values as the `usage` parameter:
|
||||
* `PSA_KEY_USAGE_SIGN_HASH` or `PSA_KEY_USAGE_SIGN_MESSAGE` for a key pair used for signing.
|
||||
* `PSA_KEY_USAGE_DECRYPT` for a key pair used for decryption.
|
||||
* `PSA_KEY_USAGE_DERIVE` for a key pair used for key agreement.
|
||||
* `PSA_KEY_USAGE_VERIFY_HASH` or `PSA_KEY_USAGE_VERIFY_MESSAGE` for a public key pair used for signature verification.
|
||||
* `PSA_KEY_USAGE_ENCRYPT` for a key pair used for encryption.
|
||||
3. Optionally, tweak the attributes (this is rarely necessary). For example:
|
||||
* Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de), [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) and/or [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to change the key's policy (by default, it allows what can be done through the PK module).
|
||||
· Call [`psa_set_key_id`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae48fcfdc72a23e7499957d7f54ff5a64) and perhaps [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to create a PSA persistent key.
|
||||
4. Call [`mbedtls_pk_import_into_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ad59835d14832daf0f4b4bd0a4555abb9) to import the key into the PSA key store.
|
||||
5. You can now free the PK object with `mbedtls_pk_free`.
|
||||
|
||||
* You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object.
|
||||
* You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent.
|
||||
|
||||
You can use this workflow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object:
|
||||
|
||||
1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`).
|
||||
2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context.
|
||||
3. Call `mbedtls_rsa_xxx` or `mbedtls_ecp_xxx` functions to construct the desired key. For example:
|
||||
* `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete` to create an RSA private key without all the parameters required by the PSA API.
|
||||
* `mbedtls_rsa_gen_key` to generate an RSA private key with a custom public exponent.
|
||||
4. Call `mbedtls_pk_wrap_as_opaque` as described above to create a corresponding PSA key object.
|
||||
5. Call `mbedtls_pk_free` to free the resources associated with the PK object.
|
||||
|
||||
#### Importing a PK key by export-import
|
||||
|
||||
This section explains how to export a PK object in the PSA import format. The process depends on the key type. You can use `mbedtls_pk_get_type` or `mbedtls_pk_can_do` to distinguish between RSA and ECC keys. The snippets below assume that the key is in an `mbedtls_pk_context pk`, and omit error checking.
|
||||
|
||||
For an RSA private key:
|
||||
Here is some sample code illustrating the above process, with error checking omitted.
|
||||
|
||||
```
|
||||
unsigned char buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
|
||||
size_t length = mbedtls_pk_write_key_der(&pk, buf, sizeof(buf));
|
||||
mbedtls_pk_context pk;
|
||||
mbedtls_pk_init(&pk);
|
||||
mbedtls_pk_parse_key(&pk, key_buffer, key_buffer_length, NULL, 0,
|
||||
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_attributes(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id);
|
||||
mbedtls_pk_free(&pk);
|
||||
```
|
||||
|
||||
For an ECC private key (a future version of Mbed TLS [will provide a more direct way to find the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)):
|
||||
|
||||
```
|
||||
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk);
|
||||
psa_ecc_curve_t curve;
|
||||
{
|
||||
mbedtls_ecp_group grp;
|
||||
mbedtls_ecp_group_init(&grp);
|
||||
mbedtls_ecp_point Q;
|
||||
mbedtls_ecp_point_init(&Q);
|
||||
mbedtls_mpi d;
|
||||
mbedtls_mpi_init(&d);
|
||||
mbedtls_ecp_export(ec, &grp, &d, &Q);
|
||||
size_t bits;
|
||||
curve = mbedtls_ecc_group_to_psa(grp.id, &bits);
|
||||
mbedtls_ecp_group_free(&grp);
|
||||
mbedtls_ecp_point_free(&Q);
|
||||
mbedtls_mpi_free(&d);
|
||||
}
|
||||
mbedtls_ecp_write_key(ec, buf, length);
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_import_key(&attributes, buf, length, &key_id);
|
||||
mbedtls_pk_free(&pk);
|
||||
```
|
||||
|
||||
For an RSA or ECC public key:
|
||||
|
||||
```
|
||||
unsigned char buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
|
||||
size_t length = mbedtls_pk_write_pubkey(&pk, buf, sizeof(buf));
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_attributes(&attributes, ...); // need to determine the type manually
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...);
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id);
|
||||
mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes);
|
||||
psa_key_id_t key_id;
|
||||
mbedtls_pk_import_into_psa(&pk, &attributes, &key_id);
|
||||
mbedtls_pk_free(&pk);
|
||||
psa_sign_hash(key_id, ...);
|
||||
```
|
||||
|
||||
#### Importing an elliptic curve key from ECP
|
||||
@ -900,8 +850,8 @@ mbedtls_ecp_keypair_init(&ec);
|
||||
// Omitted: fill ec with key material
|
||||
// (the public key will not be used and does not need to be set)
|
||||
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
|
||||
mbedtls_ecp_write_key(&ec, buf, length);
|
||||
size_t length;
|
||||
mbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf));
|
||||
psa_ecc_curve_t curve = ...; // need to determine the curve family manually
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
@ -952,11 +902,33 @@ To export a PSA public key or to export the public key of a PSA key pair object,
|
||||
|
||||
The export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above.
|
||||
|
||||
A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exporting a PK key by wrapping](#exporting-a-pk-key-by-wrapping)” for ways to use the PK module to format a PSA key.
|
||||
A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exposing a PSA key via PK](#exposing-a-psa-key-via-pk)” for ways to use the PK module to format a PSA key.
|
||||
|
||||
#### Exporting a PK key by wrapping
|
||||
#### Exposing a PSA key via PK
|
||||
|
||||
You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque`. This allows you to call functions such as `mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey` to export the key data in various formats.
|
||||
This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that:
|
||||
|
||||
* [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed.
|
||||
* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies the public part of a PSA key into a PK object. The PK object remains valid even if the PSA key is destroyed.
|
||||
* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. This functionality is only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. The PK object has the type `MBEDTLS_PK_OPAQUE` regardless of whether the key is an RSA or ECC key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive.
|
||||
|
||||
Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair.
|
||||
```
|
||||
int write_psa_pubkey(psa_key_id_t key_id,
|
||||
unsigned char *buf, size_t size, size_t *len) {
|
||||
mbedtls_pk_context pk;
|
||||
mbedtls_pk_init(&pk);
|
||||
int ret = mbedtls_pk_copy_public_from_psa(key_id, &pk);
|
||||
if (ret != 0) goto exit;
|
||||
ret = mbedtls_pk_write_pubkey_der(&pk, buf, size);
|
||||
if (ret < 0) goto exit;
|
||||
*len = ret;
|
||||
memmove(buf, buf + size - ret, ret);
|
||||
ret = 0;
|
||||
exit:
|
||||
mbedtls_pk_free(&pk);
|
||||
}
|
||||
```
|
||||
|
||||
### Signature operations
|
||||
|
||||
@ -983,7 +955,8 @@ The following subsections describe the PSA signature mechanisms that correspond
|
||||
|
||||
#### ECDSA signature
|
||||
|
||||
**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765).
|
||||
**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. To convert between the two formats, use [`mbedtls_ecdsa_raw_to_der`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga9295799b5437bdff8ce8abd524c5ef2e) or [`mbedtls_ecdsa_der_to_raw`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga33b3cf65d5992ccc724b7ee00186ae61).
|
||||
|
||||
<!-- The following are specific to the DER format and therefore have no PSA equivalent: MBEDTLS_ECDSA_MAX_SIG_LEN, MBEDTLS_ECDSA_MAX_LEN -->
|
||||
|
||||
ECDSA is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_verify` and `mbedtls_ecdsa_read_signature`.
|
||||
@ -1300,7 +1273,7 @@ There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecd
|
||||
The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`:
|
||||
|
||||
* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future.
|
||||
* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`.
|
||||
* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`.
|
||||
* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants).
|
||||
|
||||
### Additional information about RSA
|
||||
|
1
framework
Submodule
1
framework
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 750634d3a51eb9d61b59fd5d801546927c946588
|
@ -51,15 +51,15 @@
|
||||
|
||||
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
|
||||
/*
|
||||
* Maximum window size used for modular exponentiation. Default: 2
|
||||
* Maximum window size used for modular exponentiation. Default: 3
|
||||
* Minimum value: 1. Maximum value: 6.
|
||||
*
|
||||
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
|
||||
* for the sliding window calculation. (So 64 by default)
|
||||
* for the sliding window calculation. (So 8 by default)
|
||||
*
|
||||
* Reduction in size, reduces speed.
|
||||
*/
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */
|
||||
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
|
||||
|
||||
#if !defined(MBEDTLS_MPI_MAX_SIZE)
|
||||
|
@ -158,7 +158,8 @@
|
||||
* (e.g. MBEDTLS_MD_LIGHT)
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
|
||||
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */ || \
|
||||
defined(MBEDTLS_PSA_CRYPTO_CLIENT) /* The same as the previous, but with separation only */
|
||||
#include "mbedtls/config_psa.h"
|
||||
#endif
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
#endif /* some curve accelerated */
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \
|
||||
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_AES) && \
|
||||
(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_KEY_TYPE_AES) && \
|
||||
defined(PSA_WANT_ALG_ECB_NO_PADDING)))
|
||||
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
@ -207,10 +207,6 @@
|
||||
#error "MBEDTLS_ECP_C defined (or a subset enabled), but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_C) && \
|
||||
!(defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA256))
|
||||
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
|
||||
@ -401,7 +397,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_LMS_C) && \
|
||||
! ( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) )
|
||||
! ( defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_ALG_SHA_256) )
|
||||
#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
|
||||
#endif
|
||||
|
||||
@ -436,11 +432,17 @@
|
||||
#error "MBEDTLS_PK_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && \
|
||||
(!defined(MBEDTLS_ASN1_PARSE_C) || \
|
||||
!defined(MBEDTLS_OID_C) || \
|
||||
!defined(MBEDTLS_PK_C))
|
||||
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
|
||||
#if defined(MBEDTLS_PK_WRITE_C) && \
|
||||
(!defined(MBEDTLS_ASN1_WRITE_C) || \
|
||||
!defined(MBEDTLS_OID_C) || \
|
||||
!defined(MBEDTLS_PK_C))
|
||||
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -789,7 +791,7 @@
|
||||
* Note: for dependencies common with TLS 1.2 (running handshake hash),
|
||||
* see MBEDTLS_SSL_TLS_C. */
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
!(defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||
!(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
|
||||
defined(PSA_WANT_ALG_HKDF_EXTRACT) && \
|
||||
defined(PSA_WANT_ALG_HKDF_EXPAND) && \
|
||||
(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)))
|
||||
@ -985,7 +987,7 @@
|
||||
#endif
|
||||
#undef MBEDTLS_THREADING_IMPL // temporary macro defined above
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
|
@ -34,6 +34,10 @@
|
||||
#undef MBEDTLS_SSL_PROTO_DTLS
|
||||
#endif
|
||||
|
||||
#if !(defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS))
|
||||
#undef MBEDTLS_SSL_TICKET_C
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
|
||||
|
@ -141,6 +141,19 @@ typedef struct mbedtls_ecdh_context {
|
||||
}
|
||||
mbedtls_ecdh_context;
|
||||
|
||||
/**
|
||||
* \brief Return the ECP group for provided context.
|
||||
*
|
||||
* \note To access group specific fields, users should use
|
||||
* `mbedtls_ecp_curve_info_from_grp_id` or
|
||||
* `mbedtls_ecp_group_load` on the extracted `group_id`.
|
||||
*
|
||||
* \param ctx The ECDH context to parse. This must not be \c NULL.
|
||||
*
|
||||
* \return The \c mbedtls_ecp_group_id of the context.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Check whether a given group can be used for ECDH.
|
||||
*
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
@ -1327,28 +1328,84 @@ int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
|
||||
int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||
const unsigned char *buf, size_t buflen);
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief This function exports an elliptic curve private key.
|
||||
*
|
||||
* \deprecated Note that although this function accepts an output
|
||||
* buffer that is smaller or larger than the key, most key
|
||||
* import interfaces require the output to have exactly
|
||||
* key's nominal length. It is generally simplest to
|
||||
* pass the key's nominal length as \c buflen, after
|
||||
* checking that the output buffer is large enough.
|
||||
* See the description of the \p buflen parameter for
|
||||
* how to calculate the nominal length.
|
||||
* To avoid this difficulty, use mbedtls_ecp_write_key_ext()
|
||||
* instead.
|
||||
* mbedtls_ecp_write_key() is deprecated and will be
|
||||
* removed in a future version of the library.
|
||||
*
|
||||
* \note If the private key was not set in \p key,
|
||||
* the output is unspecified. Future versions
|
||||
* may return an error in that case.
|
||||
*
|
||||
* \param key The private key.
|
||||
* \param buf The output buffer for containing the binary representation
|
||||
* of the key.
|
||||
* For Weierstrass curves, this is the big-endian
|
||||
* representation, padded with null bytes at the beginning
|
||||
* to reach \p buflen bytes.
|
||||
* For Montgomery curves, this is the standard byte string
|
||||
* representation (which is little-endian), padded with
|
||||
* null bytes at the end to reach \p buflen bytes.
|
||||
* \param buflen The total length of the buffer in bytes.
|
||||
* The length of the output is
|
||||
* (`grp->nbits` + 7) / 8 bytes
|
||||
* where `grp->nbits` is the private key size in bits.
|
||||
* For Weierstrass keys, if the output buffer is smaller,
|
||||
* leading zeros are trimmed to fit if possible. For
|
||||
* Montgomery keys, the output buffer must always be large
|
||||
* enough for the nominal length.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL or
|
||||
* #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the \p key
|
||||
* representation is larger than the available space in \p buf.
|
||||
* \return Another negative error code on different kinds of failure.
|
||||
*/
|
||||
int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
|
||||
unsigned char *buf, size_t buflen);
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/**
|
||||
* \brief This function exports an elliptic curve private key.
|
||||
*
|
||||
* \param key The private key.
|
||||
* \param olen On success, the length of the private key.
|
||||
* This is always (`grp->nbits` + 7) / 8 bytes
|
||||
* where `grp->nbits` is the private key size in bits.
|
||||
* \param buf The output buffer for containing the binary representation
|
||||
* of the key. (Big endian integer for Weierstrass curves, byte
|
||||
* string for Montgomery curves.)
|
||||
* of the key.
|
||||
* \param buflen The total length of the buffer in bytes.
|
||||
* #MBEDTLS_ECP_MAX_BYTES is always sufficient.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
|
||||
representation is larger than the available space in \p buf.
|
||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
|
||||
* the group is not implemented.
|
||||
* representation is larger than the available space in \p buf.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is
|
||||
* set in \p key.
|
||||
* \return Another negative error code on different kinds of failure.
|
||||
*/
|
||||
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
|
||||
unsigned char *buf, size_t buflen);
|
||||
int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
|
||||
size_t *olen, unsigned char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief This function exports an elliptic curve public key.
|
||||
*
|
||||
* \note If the public key was not set in \p key,
|
||||
* the output is unspecified. Future versions
|
||||
* may return an error in that case.
|
||||
*
|
||||
* \param key The public key.
|
||||
* \param format The point format. This must be either
|
||||
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
|
||||
@ -1431,6 +1488,10 @@ mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
|
||||
* Each of the output parameters can be a null pointer
|
||||
* if you do not need that parameter.
|
||||
*
|
||||
* \note If the private key or the public key was not set in \p key,
|
||||
* the corresponding output is unspecified. Future versions
|
||||
* may return an error in that case.
|
||||
*
|
||||
* \param key The key pair to export from.
|
||||
* \param grp Slot for exported ECP group.
|
||||
* It must either be null or point to an initialized ECP group.
|
||||
|
@ -46,6 +46,12 @@ extern "C" {
|
||||
|
||||
#if !defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
#if defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
#define MBEDTLS_GCM_HTABLE_SIZE 256
|
||||
#else
|
||||
#define MBEDTLS_GCM_HTABLE_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The GCM context structure.
|
||||
*/
|
||||
@ -53,18 +59,18 @@ typedef struct mbedtls_gcm_context {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
|
||||
#else
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
#endif
|
||||
uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */
|
||||
uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */
|
||||
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
|
||||
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
|
||||
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
|
||||
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
|
||||
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
|
||||
int MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
|
||||
#MBEDTLS_GCM_ENCRYPT or
|
||||
#MBEDTLS_GCM_DECRYPT. */
|
||||
uint64_t MBEDTLS_PRIVATE(H)[MBEDTLS_GCM_HTABLE_SIZE][2]; /*!< Precalculated HTable. */
|
||||
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
|
||||
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
|
||||
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
|
||||
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
|
||||
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
|
||||
unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
|
||||
#MBEDTLS_GCM_ENCRYPT or
|
||||
#MBEDTLS_GCM_DECRYPT. */
|
||||
unsigned char MBEDTLS_PRIVATE(acceleration); /*!< The acceleration to use. */
|
||||
}
|
||||
mbedtls_gcm_context;
|
||||
|
||||
|
@ -2800,6 +2800,22 @@
|
||||
*/
|
||||
#define MBEDTLS_GCM_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_GCM_LARGE_TABLE
|
||||
*
|
||||
* Enable large pre-computed tables for Galois/Counter Mode (GCM).
|
||||
* Can significantly increase throughput on systems without GCM hardware
|
||||
* acceleration (e.g., AESNI, AESCE).
|
||||
*
|
||||
* The mbedtls_gcm_context size will increase by 3840 bytes.
|
||||
* The code size will increase by roughly 344 bytes.
|
||||
*
|
||||
* Module: library/gcm.c
|
||||
*
|
||||
* Requires: MBEDTLS_GCM_C
|
||||
*/
|
||||
//#define MBEDTLS_GCM_LARGE_TABLE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HKDF_C
|
||||
*
|
||||
@ -3059,7 +3075,7 @@
|
||||
* Caller: library/x509_crt.c
|
||||
* library/x509_csr.c
|
||||
*
|
||||
* Requires: MBEDTLS_PK_C
|
||||
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_C
|
||||
*
|
||||
* Uncomment to enable generic public key parse functions.
|
||||
*/
|
||||
@ -3073,7 +3089,7 @@
|
||||
* Module: library/pkwrite.c
|
||||
* Caller: library/x509write.c
|
||||
*
|
||||
* Requires: MBEDTLS_PK_C
|
||||
* Requires: MBEDTLS_ASN1_WRITE_C, MBEDTLS_OID_C, MBEDTLS_PK_C
|
||||
*
|
||||
* Uncomment to enable generic public key write functions.
|
||||
*/
|
||||
@ -3185,6 +3201,9 @@
|
||||
* \deprecated This feature is deprecated. Please switch to the PSA driver
|
||||
* interface.
|
||||
*
|
||||
* \warning This feature is not thread-safe, and should not be used in a
|
||||
* multi-threaded environment.
|
||||
*
|
||||
* Module: library/psa_crypto_se.c
|
||||
*
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
@ -73,11 +73,11 @@ void mbedtls_pem_init(mbedtls_pem_context *ctx);
|
||||
* \param data source data to look in (must be nul-terminated)
|
||||
* \param pwd password for decryption (can be NULL)
|
||||
* \param pwdlen length of password
|
||||
* \param use_len destination for total length used (set after header is
|
||||
* correctly read, so unless you get
|
||||
* \param use_len destination for total length used from data buffer. It is
|
||||
* set after header is correctly read, so unless you get
|
||||
* MBEDTLS_ERR_PEM_BAD_INPUT_DATA or
|
||||
* MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
|
||||
* the length to skip)
|
||||
* the length to skip.
|
||||
*
|
||||
* \note Attempts to check password correctness by verifying if
|
||||
* the decrypted text starts with an ASN.1 sequence of
|
||||
|
@ -181,13 +181,6 @@ typedef struct mbedtls_pk_rsassa_pss_options {
|
||||
#define MBEDTLS_PK_USE_PSA_EC_DATA
|
||||
#endif
|
||||
|
||||
/* Helper symbol to state that the PK module has support for EC keys. This
|
||||
* can either be provided through the legacy ECP solution or through the
|
||||
* PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA. */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_ECP_C)
|
||||
#define MBEDTLS_PK_HAVE_ECC_KEYS
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
|
||||
|
||||
/**
|
||||
* \brief Types for interfacing with the debug module
|
||||
*/
|
||||
@ -397,6 +390,77 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
|
||||
const mbedtls_svc_key_id_t key);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
/**
|
||||
* \brief Create a PK context starting from a key stored in PSA.
|
||||
* This key:
|
||||
* - must be exportable and
|
||||
* - must be an RSA or EC key pair or public key (FFDH is not supported in PK).
|
||||
*
|
||||
* The resulting PK object will be a transparent type:
|
||||
* - #MBEDTLS_PK_RSA for RSA keys or
|
||||
* - #MBEDTLS_PK_ECKEY for EC keys.
|
||||
*
|
||||
* Once this functions returns the PK object will be completely
|
||||
* independent from the original PSA key that it was generated
|
||||
* from.
|
||||
* Calling mbedtls_pk_sign(), mbedtls_pk_verify(),
|
||||
* mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting
|
||||
* PK context will perform the corresponding algorithm for that
|
||||
* PK context type.
|
||||
* * For ECDSA, the choice of deterministic vs randomized will
|
||||
* be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC.
|
||||
* * For an RSA key, the output PK context will allow both
|
||||
* encrypt/decrypt and sign/verify regardless of the original
|
||||
* key's policy.
|
||||
* The original key's policy determines the output key's padding
|
||||
* mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
|
||||
* otherwise PKCS1 v1.5 is set.
|
||||
*
|
||||
* \param key_id The key identifier of the key stored in PSA.
|
||||
* \param pk The PK context that will be filled. It must be initialized,
|
||||
* but not set up.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
|
||||
* parameters are not correct.
|
||||
*/
|
||||
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
|
||||
|
||||
/**
|
||||
* \brief Create a PK context for the public key of a PSA key.
|
||||
*
|
||||
* The key must be an RSA or ECC key. It can be either a
|
||||
* public key or a key pair, and only the public key is copied.
|
||||
* The resulting PK object will be a transparent type:
|
||||
* - #MBEDTLS_PK_RSA for RSA keys or
|
||||
* - #MBEDTLS_PK_ECKEY for EC keys.
|
||||
*
|
||||
* Once this functions returns the PK object will be completely
|
||||
* independent from the original PSA key that it was generated
|
||||
* from.
|
||||
* Calling mbedtls_pk_verify() or
|
||||
* mbedtls_pk_encrypt() on the resulting
|
||||
* PK context will perform the corresponding algorithm for that
|
||||
* PK context type.
|
||||
*
|
||||
* For an RSA key, the output PK context will allow both
|
||||
* encrypt and verify regardless of the original key's policy.
|
||||
* The original key's policy determines the output key's padding
|
||||
* mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
|
||||
* otherwise PKCS1 v1.5 is set.
|
||||
*
|
||||
* \param key_id The key identifier of the key stored in PSA.
|
||||
* \param pk The PK context that will be filled. It must be initialized,
|
||||
* but not set up.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
|
||||
* parameters are not correct.
|
||||
*/
|
||||
int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||
/**
|
||||
* \brief Initialize an RSA-alt context
|
||||
@ -491,20 +555,20 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
|
||||
* \brief Determine valid PSA attributes that can be used to
|
||||
* import a key into PSA.
|
||||
*
|
||||
* The attributes determined by this function are suitable
|
||||
* for calling mbedtls_pk_import_into_psa() to create
|
||||
* a PSA key with the same key material.
|
||||
* The attributes determined by this function are suitable
|
||||
* for calling mbedtls_pk_import_into_psa() to create
|
||||
* a PSA key with the same key material.
|
||||
*
|
||||
* The typical flow of operations involving this function is
|
||||
* ```
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
|
||||
* if (ret != 0) ...; // error handling omitted
|
||||
* // Tweak attributes if desired
|
||||
* psa_key_id_t key_id = 0;
|
||||
* ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
|
||||
* if (ret != 0) ...; // error handling omitted
|
||||
* ```
|
||||
* The typical flow of operations involving this function is
|
||||
* ```
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
|
||||
* if (ret != 0) ...; // error handling omitted
|
||||
* // Tweak attributes if desired
|
||||
* psa_key_id_t key_id = 0;
|
||||
* ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
|
||||
* if (ret != 0) ...; // error handling omitted
|
||||
* ```
|
||||
*
|
||||
* \note This function does not support RSA-alt contexts
|
||||
* (set up with mbedtls_pk_setup_rsa_alt()).
|
||||
@ -599,6 +663,53 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
|
||||
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
|
||||
psa_key_usage_t usage,
|
||||
psa_key_attributes_t *attributes);
|
||||
|
||||
/**
|
||||
* \brief Import a key into the PSA key store.
|
||||
*
|
||||
* This function is equivalent to calling psa_import_key()
|
||||
* with the key material from \p pk.
|
||||
*
|
||||
* The typical way to use this function is:
|
||||
* -# Call mbedtls_pk_get_psa_attributes() to obtain
|
||||
* attributes for the given key.
|
||||
* -# If desired, modify the attributes, for example:
|
||||
* - To create a persistent key, call
|
||||
* psa_set_key_identifier() and optionally
|
||||
* psa_set_key_lifetime().
|
||||
* - To import only the public part of a key pair:
|
||||
*
|
||||
* psa_set_key_type(&attributes,
|
||||
* PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
|
||||
* psa_get_key_type(&attributes)));
|
||||
* - Restrict the key usage if desired.
|
||||
* -# Call mbedtls_pk_import_into_psa().
|
||||
*
|
||||
* \note This function does not support RSA-alt contexts
|
||||
* (set up with mbedtls_pk_setup_rsa_alt()).
|
||||
*
|
||||
* \param[in] pk The PK context to use. It must have been set up.
|
||||
* It can either contain a key pair or just a public key.
|
||||
* \param[in] attributes
|
||||
* The attributes to use for the new key. They must be
|
||||
* compatible with \p pk. In particular, the key type
|
||||
* must match the content of \p pk.
|
||||
* If \p pk contains a key pair, the key type in
|
||||
* attributes can be either the key pair type or the
|
||||
* corresponding public key type (to import only the
|
||||
* public part).
|
||||
* \param[out] key_id
|
||||
* On success, the identifier of the newly created key.
|
||||
* On error, this is #MBEDTLS_SVC_KEY_ID_INIT.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain
|
||||
* a key of the type identified in \p attributes.
|
||||
* Another error code on other failures.
|
||||
*/
|
||||
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key_id);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/**
|
||||
@ -619,14 +730,17 @@ int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
|
||||
* \param sig Signature to verify
|
||||
* \param sig_len Signature length
|
||||
*
|
||||
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
|
||||
* either PKCS#1 v1.5 or PSS (accepting any salt length),
|
||||
* depending on the padding mode in the underlying RSA context.
|
||||
* For a pk object constructed by parsing, this is PKCS#1 v1.5
|
||||
* by default. Use mbedtls_pk_verify_ext() to explicitly select
|
||||
* a different algorithm.
|
||||
*
|
||||
* \return 0 on success (signature is valid),
|
||||
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
|
||||
* signature in \p sig but its length is less than \p sig_len,
|
||||
* or a specific error code.
|
||||
*
|
||||
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
|
||||
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
|
||||
* to verify RSASSA_PSS signatures.
|
||||
*/
|
||||
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
@ -713,11 +827,15 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
|
||||
* \param f_rng RNG function, must not be \c NULL.
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
|
||||
* either PKCS#1 v1.5 or PSS (using the largest possible salt
|
||||
* length up to the hash length), depending on the padding mode
|
||||
* in the underlying RSA context. For a pk object constructed
|
||||
* by parsing, this is PKCS#1 v1.5 by default. Use
|
||||
* mbedtls_pk_verify_ext() to explicitly select a different
|
||||
* algorithm.
|
||||
*
|
||||
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
|
||||
* There is no interface in the PK module to make RSASSA-PSS
|
||||
* signatures yet.
|
||||
* \return 0 on success, or a specific error code.
|
||||
*
|
||||
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
|
||||
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
|
||||
@ -813,7 +931,10 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
|
||||
* \param f_rng RNG function, must not be \c NULL.
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
|
||||
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
|
||||
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
|
||||
* the underlying RSA context. For a pk object constructed by
|
||||
* parsing, this is PKCS#1 v1.5 by default.
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
*/
|
||||
@ -834,9 +955,12 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
|
||||
* \param f_rng RNG function, must not be \c NULL.
|
||||
* \param p_rng RNG parameter
|
||||
*
|
||||
* \note \p f_rng is used for padding generation.
|
||||
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
|
||||
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
|
||||
* the underlying RSA context. For a pk object constructed by
|
||||
* parsing, this is PKCS#1 v1.5 by default.
|
||||
*
|
||||
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
|
||||
* \note \p f_rng is used for padding generation.
|
||||
*
|
||||
* \return 0 on success, or a specific error code.
|
||||
*/
|
||||
@ -1159,33 +1283,6 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
|
||||
const mbedtls_pk_context *key);
|
||||
#endif /* MBEDTLS_PK_WRITE_C */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/**
|
||||
* \brief Turn an EC or RSA key into an opaque one.
|
||||
*
|
||||
* \warning This is a temporary utility function for tests. It might
|
||||
* change or be removed at any time without notice.
|
||||
*
|
||||
* \param pk Input: the EC or RSA key to import to a PSA key.
|
||||
* Output: a PK context wrapping that PSA key.
|
||||
* \param key Output: a PSA key identifier.
|
||||
* It's the caller's responsibility to call
|
||||
* psa_destroy_key() on that key identifier after calling
|
||||
* mbedtls_pk_free() on the PK context.
|
||||
* \param alg The algorithm to allow for use with that key.
|
||||
* \param usage The usage to allow for use with that key.
|
||||
* \param alg2 The secondary algorithm to allow for use with that key.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return An Mbed TLS error code otherwise.
|
||||
*/
|
||||
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
||||
mbedtls_svc_key_id_t *key,
|
||||
psa_algorithm_t alg,
|
||||
psa_key_usage_t usage,
|
||||
psa_algorithm_t alg2);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,44 +21,24 @@
|
||||
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
|
||||
#include <mbedtls/asn1write.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* Expose whatever RNG the PSA subsystem uses to applications using the
|
||||
* mbedtls_xxx API. The declarations and definitions here need to be
|
||||
* consistent with the implementation in library/psa_crypto_random_impl.h.
|
||||
* See that file for implementation documentation. */
|
||||
|
||||
|
||||
/* The type of a `f_rng` random generator function that many library functions
|
||||
* take.
|
||||
*
|
||||
* This type name is not part of the Mbed TLS stable API. It may be renamed
|
||||
* or moved without warning.
|
||||
*/
|
||||
typedef int mbedtls_f_rng_t(void *p_rng, unsigned char *output, size_t output_size);
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
/** The random generator function for the PSA subsystem.
|
||||
*
|
||||
* This function is suitable as the `f_rng` random generator function
|
||||
* parameter of many `mbedtls_xxx` functions. Use #MBEDTLS_PSA_RANDOM_STATE
|
||||
* to obtain the \p p_rng parameter.
|
||||
* parameter of many `mbedtls_xxx` functions.
|
||||
*
|
||||
* The implementation of this function depends on the configuration of the
|
||||
* library.
|
||||
*
|
||||
* \note Depending on the configuration, this may be a function or
|
||||
* a pointer to a function.
|
||||
*
|
||||
* \note This function may only be used if the PSA crypto subsystem is active.
|
||||
* This means that you must call psa_crypto_init() before any call to
|
||||
* this function, and you must not call this function after calling
|
||||
* mbedtls_psa_crypto_free().
|
||||
*
|
||||
* \param p_rng The random generator context. This must be
|
||||
* #MBEDTLS_PSA_RANDOM_STATE. No other state is
|
||||
* supported.
|
||||
* \param p_rng This parameter is only kept for backward compatibility
|
||||
* reasons with legacy `f_rng` functions and it's ignored.
|
||||
* Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
|
||||
* \param output The buffer to fill. It must have room for
|
||||
* \c output_size bytes.
|
||||
* \param output_size The number of bytes to write to \p output.
|
||||
@ -80,32 +60,11 @@ int mbedtls_psa_get_random(void *p_rng,
|
||||
|
||||
/** The random generator state for the PSA subsystem.
|
||||
*
|
||||
* This macro expands to an expression which is suitable as the `p_rng`
|
||||
* random generator state parameter of many `mbedtls_xxx` functions.
|
||||
* It must be used in combination with the random generator function
|
||||
* mbedtls_psa_get_random().
|
||||
*
|
||||
* The implementation of this macro depends on the configuration of the
|
||||
* library. Do not make any assumption on its nature.
|
||||
* This macro always expands to NULL because the `p_rng` parameter is unused
|
||||
* in mbedtls_psa_get_random(), but it's kept for interface's backward
|
||||
* compatibility.
|
||||
*/
|
||||
#define MBEDTLS_PSA_RANDOM_STATE NULL
|
||||
|
||||
#else /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
|
||||
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
|
||||
static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
|
||||
#endif
|
||||
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
|
||||
|
||||
#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
|
||||
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
#define MBEDTLS_PSA_RANDOM_STATE NULL
|
||||
|
||||
/** \defgroup psa_tls_helpers TLS helper functions
|
||||
* @{
|
||||
@ -180,7 +139,7 @@ static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa
|
||||
{
|
||||
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
|
@ -734,6 +734,21 @@ typedef enum {
|
||||
}
|
||||
mbedtls_ssl_states;
|
||||
|
||||
/*
|
||||
* Early data status, client side only.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
typedef enum {
|
||||
/*
|
||||
* See documentation of mbedtls_ssl_get_early_data_status().
|
||||
*/
|
||||
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED,
|
||||
MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED,
|
||||
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED,
|
||||
} mbedtls_ssl_early_data_status;
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
/**
|
||||
* \brief Callback type: send data on the network.
|
||||
*
|
||||
@ -1224,6 +1239,7 @@ struct mbedtls_ssl_session {
|
||||
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
|
||||
|
||||
unsigned char MBEDTLS_PRIVATE(exported);
|
||||
uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */
|
||||
|
||||
/** TLS version negotiated in the session. Used if and when renegotiating
|
||||
* or resuming a session instead of the configured minor TLS version.
|
||||
@ -1257,26 +1273,41 @@ struct mbedtls_ssl_session {
|
||||
uint32_t MBEDTLS_PRIVATE(ticket_lifetime); /*!< ticket lifetime hint */
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) && \
|
||||
defined(MBEDTLS_HAVE_TIME)
|
||||
/*! When a ticket is created by a TLS server as part of an established TLS
|
||||
* session, the ticket creation time may need to be saved for the ticket
|
||||
* module to be able to check the ticket age when the ticket is used.
|
||||
* That's the purpose of this field.
|
||||
* Before creating a new ticket, an Mbed TLS server set this field with
|
||||
* its current time in milliseconds. This time may then be saved in the
|
||||
* session ticket data by the session ticket writing function and
|
||||
* recovered by the ticket parsing function later when the ticket is used.
|
||||
* The ticket module may then use this time to compute the ticket age and
|
||||
* determine if it has expired or not.
|
||||
* The Mbed TLS implementations of the session ticket writing and parsing
|
||||
* functions save and retrieve the ticket creation time as part of the
|
||||
* session ticket data. The session ticket parsing function relies on
|
||||
* the mbedtls_ssl_session_get_ticket_creation_time() API to get the
|
||||
* ticket creation time from the session ticket data.
|
||||
*/
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
uint8_t MBEDTLS_PRIVATE(endpoint); /*!< 0: client, 1: server */
|
||||
uint8_t MBEDTLS_PRIVATE(ticket_flags); /*!< Ticket flags */
|
||||
uint32_t MBEDTLS_PRIVATE(ticket_age_add); /*!< Randomly generated value used to obscure the age of the ticket */
|
||||
uint8_t MBEDTLS_PRIVATE(resumption_key_len); /*!< resumption_key length */
|
||||
uint32_t MBEDTLS_PRIVATE(ticket_age_add); /*!< Randomly generated value used to obscure the age of the ticket */
|
||||
uint8_t MBEDTLS_PRIVATE(ticket_flags); /*!< Ticket flags */
|
||||
uint8_t MBEDTLS_PRIVATE(resumption_key_len); /*!< resumption_key length */
|
||||
unsigned char MBEDTLS_PRIVATE(resumption_key)[MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN];
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_SSL_CLI_C)
|
||||
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); /*!< time when ticket was received. */
|
||||
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
|
||||
/*! Time in milliseconds when the last ticket was received. */
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time);
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); /*!< time when ticket was created. */
|
||||
#endif
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
@ -1657,33 +1688,29 @@ struct mbedtls_ssl_context {
|
||||
#endif /* MBEDTLS_SSL_RENEGOTIATION */
|
||||
|
||||
/**
|
||||
* Maximum TLS version to be negotiated, then negotiated TLS version.
|
||||
* Maximum TLS version to be negotiated, then negotiated TLS version.
|
||||
*
|
||||
* It is initialized as the configured maximum TLS version to be
|
||||
* negotiated by mbedtls_ssl_setup().
|
||||
* It is initialized as the configured maximum TLS version to be
|
||||
* negotiated by mbedtls_ssl_setup().
|
||||
*
|
||||
* When renegotiating or resuming a session, it is overwritten in the
|
||||
* ClientHello writing preparation stage with the previously negotiated
|
||||
* TLS version.
|
||||
* When renegotiating or resuming a session, it is overwritten in the
|
||||
* ClientHello writing preparation stage with the previously negotiated
|
||||
* TLS version.
|
||||
*
|
||||
* On client side, it is updated to the TLS version selected by the server
|
||||
* for the handshake when the ServerHello is received.
|
||||
* On client side, it is updated to the TLS version selected by the server
|
||||
* for the handshake when the ServerHello is received.
|
||||
*
|
||||
* On server side, it is updated to the TLS version the server selects for
|
||||
* the handshake when the ClientHello is received.
|
||||
* On server side, it is updated to the TLS version the server selects for
|
||||
* the handshake when the ClientHello is received.
|
||||
*/
|
||||
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
/**
|
||||
* Status of the negotiation of the use of early data.
|
||||
* See the documentation of mbedtls_ssl_get_early_data_status() for more
|
||||
* information.
|
||||
*
|
||||
* Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is
|
||||
* reset.
|
||||
* State of the negotiation and transfer of early data. Reset to
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_IDLE when the context is reset.
|
||||
*/
|
||||
int MBEDTLS_PRIVATE(early_data_status);
|
||||
int MBEDTLS_PRIVATE(early_data_state);
|
||||
#endif
|
||||
|
||||
unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */
|
||||
@ -1802,7 +1829,8 @@ struct mbedtls_ssl_context {
|
||||
* within a single datagram. */
|
||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/*
|
||||
* One of:
|
||||
* MBEDTLS_SSL_EARLY_DATA_NO_DISCARD
|
||||
@ -1811,6 +1839,8 @@ struct mbedtls_ssl_context {
|
||||
*/
|
||||
uint8_t MBEDTLS_PRIVATE(discard_early_data_record);
|
||||
#endif
|
||||
uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/*
|
||||
* Record layer (outgoing data)
|
||||
@ -2630,8 +2660,73 @@ void mbedtls_ssl_conf_session_tickets_cb(mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_ticket_write_t *f_ticket_write,
|
||||
mbedtls_ssl_ticket_parse_t *f_ticket_parse,
|
||||
void *p_ticket);
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
/**
|
||||
* \brief Get the creation time of a session ticket.
|
||||
*
|
||||
* \note See the documentation of \c ticket_creation_time for information about
|
||||
* the intended usage of this function.
|
||||
*
|
||||
* \param session SSL session
|
||||
* \param ticket_creation_time On exit, holds the ticket creation time in
|
||||
* milliseconds.
|
||||
*
|
||||
* \return 0 on success,
|
||||
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if an input is not valid.
|
||||
*/
|
||||
static inline int mbedtls_ssl_session_get_ticket_creation_time(
|
||||
mbedtls_ssl_session *session, mbedtls_ms_time_t *ticket_creation_time)
|
||||
{
|
||||
if (session == NULL || ticket_creation_time == NULL ||
|
||||
session->MBEDTLS_PRIVATE(endpoint) != MBEDTLS_SSL_IS_SERVER) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
*ticket_creation_time = session->MBEDTLS_PRIVATE(ticket_creation_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
|
||||
|
||||
/**
|
||||
* \brief Get the session-id buffer.
|
||||
*
|
||||
* \param session SSL session.
|
||||
*
|
||||
* \return The address of the session-id buffer.
|
||||
*/
|
||||
static inline unsigned const char (*mbedtls_ssl_session_get_id(const mbedtls_ssl_session *
|
||||
session))[32]
|
||||
{
|
||||
return &session->MBEDTLS_PRIVATE(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the size of the session-id.
|
||||
*
|
||||
* \param session SSL session.
|
||||
*
|
||||
* \return size_t size of session-id buffer.
|
||||
*/
|
||||
static inline size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session)
|
||||
{
|
||||
return session->MBEDTLS_PRIVATE(id_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the ciphersuite-id.
|
||||
*
|
||||
* \param session SSL session.
|
||||
*
|
||||
* \return int represetation for ciphersuite.
|
||||
*/
|
||||
static inline int mbedtls_ssl_session_get_ciphersuite_id(const mbedtls_ssl_session *session)
|
||||
{
|
||||
return session->MBEDTLS_PRIVATE(ciphersuite);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure a key export callback.
|
||||
* (Default: none.)
|
||||
@ -4737,7 +4832,7 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl
|
||||
* \param ssl The SSL context representing the connection for which to
|
||||
* to export a session structure for later resumption.
|
||||
* \param session The target structure in which to store the exported session.
|
||||
* This must have been initialized with mbedtls_ssl_init_session()
|
||||
* This must have been initialized with mbedtls_ssl_session_init()
|
||||
* but otherwise be unused.
|
||||
*
|
||||
* \note This function can handle a variety of mechanisms for session
|
||||
@ -5106,10 +5201,6 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 2
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/**
|
||||
* \brief Read at most 'len' bytes of early data
|
||||
@ -5162,17 +5253,43 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
|
||||
* \brief Try to write exactly 'len' application data bytes while
|
||||
* performing the handshake (early data).
|
||||
*
|
||||
* \warning Early data is defined in the TLS 1.3 specification, RFC 8446.
|
||||
* IMPORTANT NOTE from section 2.3 of the specification:
|
||||
*
|
||||
* The security properties for 0-RTT data are weaker than
|
||||
* those for other kinds of TLS data. Specifically:
|
||||
* - This data is not forward secret, as it is encrypted
|
||||
* solely under keys derived using the offered PSK.
|
||||
* - There are no guarantees of non-replay between connections.
|
||||
* Protection against replay for ordinary TLS 1.3 1-RTT data
|
||||
* is provided via the server's Random value, but 0-RTT data
|
||||
* does not depend on the ServerHello and therefore has
|
||||
* weaker guarantees. This is especially relevant if the
|
||||
* data is authenticated either with TLS client
|
||||
* authentication or inside the application protocol. The
|
||||
* same warnings apply to any use of the
|
||||
* early_exporter_master_secret.
|
||||
*
|
||||
* \note This function behaves mainly as mbedtls_ssl_write(). The
|
||||
* specification of mbedtls_ssl_write() relevant to TLS 1.3
|
||||
* (thus not the parts specific to (D)TLS1.2) applies to this
|
||||
* function and the present documentation is restricted to the
|
||||
* differences with mbedtls_ssl_write().
|
||||
* function and the present documentation is mainly restricted
|
||||
* to the differences with mbedtls_ssl_write(). One noticeable
|
||||
* difference though is that mbedtls_ssl_write() aims to
|
||||
* complete the handshake before to write application data
|
||||
* while mbedtls_ssl_write_early() aims to drive the handshake
|
||||
* just past the point where it is not possible to send early
|
||||
* data anymore.
|
||||
*
|
||||
* \param ssl SSL context
|
||||
* \param buf buffer holding the data
|
||||
* \param len how many bytes must be written
|
||||
*
|
||||
* \return One additional specific return value:
|
||||
* \return The (non-negative) number of bytes actually written if
|
||||
* successful (may be less than \p len).
|
||||
*
|
||||
* \return One additional specific error code compared to
|
||||
* mbedtls_ssl_write():
|
||||
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA.
|
||||
*
|
||||
* #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it
|
||||
@ -5193,9 +5310,11 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
|
||||
* already completed.
|
||||
*
|
||||
* It is not possible to write early data for the SSL context
|
||||
* \p ssl but this does not preclude for using it with
|
||||
* \p ssl and any subsequent call to this API will return this
|
||||
* error code. But this does not preclude for using it with
|
||||
* mbedtls_ssl_write(), mbedtls_ssl_read() or
|
||||
* mbedtls_ssl_handshake().
|
||||
* mbedtls_ssl_handshake() and the handshake can be
|
||||
* completed by calling one of these APIs.
|
||||
*
|
||||
* \note This function may write early data only if the SSL context
|
||||
* has been configured for the handshake with a PSK for which
|
||||
@ -5228,8 +5347,8 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
|
||||
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called
|
||||
* prior to completion of the handshake.
|
||||
*
|
||||
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT if the client has
|
||||
* not indicated the use of early data to the server.
|
||||
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED if the client
|
||||
* has not indicated the use of early data to the server.
|
||||
*
|
||||
* \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has
|
||||
* indicated the use of early data and the server has accepted
|
||||
|
@ -468,6 +468,11 @@ static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_cip
|
||||
return info->MBEDTLS_PRIVATE(name);
|
||||
}
|
||||
|
||||
static inline int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info)
|
||||
{
|
||||
return info->MBEDTLS_PRIVATE(id);
|
||||
}
|
||||
|
||||
size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -50,6 +50,10 @@ typedef struct mbedtls_ssl_ticket_key {
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t MBEDTLS_PRIVATE(generation_time); /*!< key generation timestamp (seconds) */
|
||||
#endif
|
||||
/*! Lifetime of the key in seconds. This is also the lifetime of the
|
||||
* tickets created under that key.
|
||||
*/
|
||||
uint32_t MBEDTLS_PRIVATE(lifetime);
|
||||
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(ctx); /*!< context for auth enc/decryption */
|
||||
#else
|
||||
|
@ -322,8 +322,150 @@ mbedtls_x509_san_list;
|
||||
*/
|
||||
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn);
|
||||
|
||||
/**
|
||||
* \brief Convert the certificate DN string \p name into
|
||||
* a linked list of mbedtls_x509_name (equivalent to
|
||||
* mbedtls_asn1_named_data).
|
||||
*
|
||||
* \note This function allocates a linked list, and places the head
|
||||
* pointer in \p head. This list must later be freed by a
|
||||
* call to mbedtls_asn1_free_named_data_list().
|
||||
*
|
||||
* \param[out] head Address in which to store the pointer to the head of the
|
||||
* allocated list of mbedtls_x509_name
|
||||
* \param[in] name The string representation of a DN to convert
|
||||
*
|
||||
* \return 0 on success, or a negative error code.
|
||||
*/
|
||||
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name);
|
||||
|
||||
/**
|
||||
* \brief Return the next relative DN in an X509 name.
|
||||
*
|
||||
* \note Intended use is to compare function result to dn->next
|
||||
* in order to detect boundaries of multi-valued RDNs.
|
||||
*
|
||||
* \param dn Current node in the X509 name
|
||||
*
|
||||
* \return Pointer to the first attribute-value pair of the
|
||||
* next RDN in sequence, or NULL if end is reached.
|
||||
*/
|
||||
static inline mbedtls_x509_name *mbedtls_x509_dn_get_next(
|
||||
mbedtls_x509_name *dn)
|
||||
{
|
||||
while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) {
|
||||
dn = dn->next;
|
||||
}
|
||||
return dn->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store the certificate serial in printable form into buf;
|
||||
* no more than size characters will be written.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param serial The X509 serial to represent
|
||||
*
|
||||
* \return The length of the string written (not including the
|
||||
* terminated nul byte), or a negative error code.
|
||||
*/
|
||||
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial);
|
||||
|
||||
/**
|
||||
* \brief Compare pair of mbedtls_x509_time.
|
||||
*
|
||||
* \param t1 mbedtls_x509_time to compare
|
||||
* \param t2 mbedtls_x509_time to compare
|
||||
*
|
||||
* \return < 0 if t1 is before t2
|
||||
* 0 if t1 equals t2
|
||||
* > 0 if t1 is after t2
|
||||
*/
|
||||
int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2);
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
/**
|
||||
* \brief Fill mbedtls_x509_time with provided mbedtls_time_t.
|
||||
*
|
||||
* \param tt mbedtls_time_t to convert
|
||||
* \param now mbedtls_x509_time to fill with converted mbedtls_time_t
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return A non-zero return value on failure.
|
||||
*/
|
||||
int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now);
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
/**
|
||||
* \brief Check a given mbedtls_x509_time against the system time
|
||||
* and tell if it's in the past.
|
||||
*
|
||||
* \note Intended usage is "if( is_past( valid_to ) ) ERROR".
|
||||
* Hence the return value of 1 if on internal errors.
|
||||
*
|
||||
* \param to mbedtls_x509_time to check
|
||||
*
|
||||
* \return 1 if the given time is in the past or an error occurred,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
||||
|
||||
/**
|
||||
* \brief Check a given mbedtls_x509_time against the system time
|
||||
* and tell if it's in the future.
|
||||
*
|
||||
* \note Intended usage is "if( is_future( valid_from ) ) ERROR".
|
||||
* Hence the return value of 1 if on internal errors.
|
||||
*
|
||||
* \param from mbedtls_x509_time to check
|
||||
*
|
||||
* \return 1 if the given time is in the future or an error occurred,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
|
||||
|
||||
/**
|
||||
* \brief This function parses an item in the SubjectAlternativeNames
|
||||
* extension. Please note that this function might allocate
|
||||
* additional memory for a subject alternative name, thus
|
||||
* mbedtls_x509_free_subject_alt_name has to be called
|
||||
* to dispose of this additional memory afterwards.
|
||||
*
|
||||
* \param san_buf The buffer holding the raw data item of the subject
|
||||
* alternative name.
|
||||
* \param san The target structure to populate with the parsed presentation
|
||||
* of the subject alternative name encoded in \p san_buf.
|
||||
*
|
||||
* \note Supported GeneralName types, as defined in RFC 5280:
|
||||
* "rfc822Name", "dnsName", "directoryName",
|
||||
* "uniformResourceIdentifier" and "hardware_module_name"
|
||||
* of type "otherName", as defined in RFC 4108.
|
||||
*
|
||||
* \note This function should be called on a single raw data of
|
||||
* subject alternative name. For example, after successful
|
||||
* certificate parsing, one must iterate on every item in the
|
||||
* \c crt->subject_alt_names sequence, and pass it to
|
||||
* this function.
|
||||
*
|
||||
* \warning The target structure contains pointers to the raw data of the
|
||||
* parsed certificate, and its lifetime is restricted by the
|
||||
* lifetime of the certificate.
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
|
||||
* SAN type.
|
||||
* \return Another negative value for any other failure.
|
||||
*/
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san);
|
||||
/**
|
||||
* \brief Unallocate all data related to subject alternative name
|
||||
*
|
||||
* \param san SAN structure - extra memory owned by this structure will be freed
|
||||
*/
|
||||
void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san);
|
||||
|
||||
/**
|
||||
* \brief This function parses a CN string as an IP address.
|
||||
*
|
||||
|
@ -916,6 +916,18 @@ static inline int mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx,
|
||||
return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Access the ca_istrue field
|
||||
*
|
||||
* \param[in] crt Certificate to be queried, must not be \c NULL
|
||||
*
|
||||
* \return \c 1 if this a CA certificate \c 0 otherwise.
|
||||
* \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain
|
||||
* the Optional Basic Constraint extension.
|
||||
*
|
||||
*/
|
||||
int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt);
|
||||
|
||||
/** \} name Structures and functions for parsing and writing X.509 certificates */
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_WRITE_C)
|
||||
|
@ -119,8 +119,9 @@ static psa_key_attributes_t psa_key_attributes_init(void);
|
||||
* value in the structure.
|
||||
* The persistent key will be written to storage when the attribute
|
||||
* structure is passed to a key creation function such as
|
||||
* psa_import_key(), psa_generate_key(),
|
||||
* psa_key_derivation_output_key() or psa_copy_key().
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
|
||||
* or psa_copy_key().
|
||||
*
|
||||
* This function may be declared as `static` (i.e. without external
|
||||
* linkage). This function may be provided as a function-like macro,
|
||||
@ -163,8 +164,9 @@ static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
|
||||
* value in the structure.
|
||||
* The persistent key will be written to storage when the attribute
|
||||
* structure is passed to a key creation function such as
|
||||
* psa_import_key(), psa_generate_key(),
|
||||
* psa_key_derivation_output_key() or psa_copy_key().
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
|
||||
* or psa_copy_key().
|
||||
*
|
||||
* This function may be declared as `static` (i.e. without external
|
||||
* linkage). This function may be provided as a function-like macro,
|
||||
@ -3226,7 +3228,8 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
|
||||
* psa_key_derivation_set_capacity(). You may do this before, in the middle
|
||||
* of or after providing inputs. For some algorithms, this step is mandatory
|
||||
* because the output depends on the maximum capacity.
|
||||
* -# To derive a key, call psa_key_derivation_output_key().
|
||||
* -# To derive a key, call psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
* To derive a byte string for a different purpose, call
|
||||
* psa_key_derivation_output_bytes().
|
||||
* Successive calls to these functions use successive output bytes
|
||||
@ -3449,7 +3452,8 @@ psa_status_t psa_key_derivation_input_integer(
|
||||
* \note Once all inputs steps are completed, the operations will allow:
|
||||
* - psa_key_derivation_output_bytes() if each input was either a direct input
|
||||
* or a key with #PSA_KEY_USAGE_DERIVE set;
|
||||
* - psa_key_derivation_output_key() if the input for step
|
||||
* - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext()
|
||||
* if the input for step
|
||||
* #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
|
||||
* was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
|
||||
* either a direct input or a key with #PSA_KEY_USAGE_DERIVE set;
|
||||
@ -3697,6 +3701,11 @@ psa_status_t psa_key_derivation_output_bytes(
|
||||
* Future versions of this specification may include additional restrictions
|
||||
* on the derived key based on the attributes and strength of the secret key.
|
||||
*
|
||||
* \note This function is equivalent to calling
|
||||
* psa_key_derivation_output_key_ext()
|
||||
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* and `params_data_length == 0` (i.e. `params->data` is empty).
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* If the key type to be created is
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
|
||||
@ -3750,6 +3759,83 @@ psa_status_t psa_key_derivation_output_key(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/** Derive a key from an ongoing key derivation operation with custom
|
||||
* production parameters.
|
||||
*
|
||||
* See the description of psa_key_derivation_out_key() for the operation of
|
||||
* this function with the default production parameters.
|
||||
* Mbed TLS currently does not currently support any non-default production
|
||||
* parameters.
|
||||
*
|
||||
* \note This function is experimental and may change in future minor
|
||||
* versions of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* If the key type to be created is
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
|
||||
* the policy must be the same as in the current
|
||||
* operation.
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] params Customization parameters for the key derivation.
|
||||
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* with \p params_data_length = 0,
|
||||
* this function is equivalent to
|
||||
* psa_key_derivation_output_key().
|
||||
* Mbed TLS currently only supports the default
|
||||
* production parameters, i.e.
|
||||
* #PSA_KEY_PRODUCTION_PARAMETERS_INIT,
|
||||
* for all key types.
|
||||
* \param params_data_length
|
||||
* Length of `params->data` in bytes.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
* key. For persistent keys, this is the key
|
||||
* identifier defined in \p attributes.
|
||||
* \c 0 on failure.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* If the key is persistent, the key material and the key's metadata
|
||||
* have been saved to persistent storage.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* This is an attempt to create a persistent key, and there is
|
||||
* already a persistent key with the given identifier.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_DATA
|
||||
* There was not enough data to create the desired key.
|
||||
* Note that in this case, no output is written to the output buffer.
|
||||
* The operation's capacity is set to 0, thus subsequent calls to
|
||||
* this function will not succeed, even with a smaller output buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key type or key size is not supported, either by the
|
||||
* implementation in general or in this particular location.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The provided key attributes are not valid for the operation.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The #PSA_KEY_DERIVATION_INPUT_SECRET or
|
||||
* #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
|
||||
* key; or one of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_DERIVE.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active and completed
|
||||
* all required input steps), or the library has not been previously
|
||||
* initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t psa_key_derivation_output_key_ext(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value.
|
||||
*
|
||||
* This function calculates output bytes from a key derivation algorithm and
|
||||
@ -3835,7 +3921,8 @@ psa_status_t psa_key_derivation_verify_bytes(
|
||||
* and the permitted algorithm must match the
|
||||
* operation. The value of this key was likely
|
||||
* computed by a previous call to
|
||||
* psa_key_derivation_output_key().
|
||||
* psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
@ -4003,6 +4090,10 @@ psa_status_t psa_generate_random(uint8_t *output,
|
||||
* between 2^{n-1} and 2^n where n is the bit size specified in the
|
||||
* attributes.
|
||||
*
|
||||
* \note This function is equivalent to calling psa_generate_key_ext()
|
||||
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* and `params_data_length == 0` (i.e. `params->data` is empty).
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
* key. For persistent keys, this is the key
|
||||
@ -4035,6 +4126,60 @@ psa_status_t psa_generate_random(uint8_t *output,
|
||||
psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/**
|
||||
* \brief Generate a key or key pair using custom production parameters.
|
||||
*
|
||||
* See the description of psa_generate_key() for the operation of this
|
||||
* function with the default production parameters. In addition, this function
|
||||
* supports the following production customizations, described in more detail
|
||||
* in the documentation of ::psa_key_production_parameters_t:
|
||||
*
|
||||
* - RSA keys: generation with a custom public exponent.
|
||||
*
|
||||
* \note This function is experimental and may change in future minor
|
||||
* versions of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* \param[in] params Customization parameters for the key generation.
|
||||
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* with \p params_data_length = 0,
|
||||
* this function is equivalent to
|
||||
* psa_generate_key().
|
||||
* \param params_data_length
|
||||
* Length of `params->data` in bytes.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
* key. For persistent keys, this is the key
|
||||
* identifier defined in \p attributes.
|
||||
* \c 0 on failure.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* If the key is persistent, the key material and the key's metadata
|
||||
* have been saved to persistent storage.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* This is an attempt to create a persistent key, and there is
|
||||
* already a persistent key with the given identifier.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been previously initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup interruptible_hash Interruptible sign/verify hash
|
||||
|
@ -146,6 +146,83 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key,
|
||||
*/
|
||||
psa_status_t psa_close_key(psa_key_handle_t handle);
|
||||
|
||||
/** \addtogroup attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/** Custom Diffie-Hellman group.
|
||||
*
|
||||
* Mbed TLS does not support custom DH groups.
|
||||
*
|
||||
* \deprecated This value is not useful, so this macro will be removed in
|
||||
* a future version of the library.
|
||||
*/
|
||||
#define PSA_DH_FAMILY_CUSTOM \
|
||||
((psa_dh_family_t) MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(0x7e))
|
||||
|
||||
/**
|
||||
* \brief Set domain parameters for a key.
|
||||
*
|
||||
* \deprecated Mbed TLS no longer supports any domain parameters.
|
||||
* This function only does the equivalent of
|
||||
* psa_set_key_type() and will be removed in a future version
|
||||
* of the library.
|
||||
*
|
||||
* \param[in,out] attributes Attribute structure where \p type will be set.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[in] data Ignored.
|
||||
* \param data_length Must be 0.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
*/
|
||||
static inline psa_status_t MBEDTLS_DEPRECATED psa_set_key_domain_parameters(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type, const uint8_t *data, size_t data_length)
|
||||
{
|
||||
(void) data;
|
||||
if (data_length != 0) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
psa_set_key_type(attributes, type);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get domain parameters for a key.
|
||||
*
|
||||
* \deprecated Mbed TLS no longer supports any domain parameters.
|
||||
* This function alwaya has an empty output and will be
|
||||
* removed in a future version of the library.
|
||||
|
||||
* \param[in] attributes Ignored.
|
||||
* \param[out] data Ignored.
|
||||
* \param data_size Ignored.
|
||||
* \param[out] data_length Set to 0.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
*/
|
||||
static inline psa_status_t MBEDTLS_DEPRECATED psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
(void) attributes;
|
||||
(void) data;
|
||||
(void) data_size;
|
||||
*data_length = 0;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/** Safe output buffer size for psa_get_key_domain_parameters().
|
||||
*
|
||||
*/
|
||||
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
|
||||
MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(1u)
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -59,7 +59,7 @@ static inline void psa_set_key_enrollment_algorithm(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg2)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
|
||||
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
|
||||
}
|
||||
|
||||
/** Retrieve the enrollment algorithm policy from key attributes.
|
||||
@ -71,7 +71,7 @@ static inline void psa_set_key_enrollment_algorithm(
|
||||
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
|
||||
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
@ -129,7 +129,7 @@ static inline void psa_set_key_slot_number(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t slot_number)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
|
||||
attributes->MBEDTLS_PRIVATE(has_slot_number) = 1;
|
||||
attributes->MBEDTLS_PRIVATE(slot_number) = slot_number;
|
||||
}
|
||||
|
||||
@ -142,8 +142,7 @@ static inline void psa_set_key_slot_number(
|
||||
static inline void psa_clear_key_slot_number(
|
||||
psa_key_attributes_t *attributes)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) &=
|
||||
~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
|
||||
attributes->MBEDTLS_PRIVATE(has_slot_number) = 0;
|
||||
}
|
||||
|
||||
/** Register a key that is already present in a secure element.
|
||||
@ -409,140 +408,11 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Custom Diffie-Hellman group.
|
||||
*
|
||||
* For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM), the group data comes
|
||||
* from domain parameters set by psa_set_key_domain_parameters().
|
||||
*/
|
||||
#define PSA_DH_FAMILY_CUSTOM ((psa_dh_family_t) 0x7e)
|
||||
|
||||
/** PAKE operation stages. */
|
||||
#define PSA_PAKE_OPERATION_STAGE_SETUP 0
|
||||
#define PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS 1
|
||||
#define PSA_PAKE_OPERATION_STAGE_COMPUTATION 2
|
||||
|
||||
/**
|
||||
* \brief Set domain parameters for a key.
|
||||
*
|
||||
* Some key types require additional domain parameters in addition to
|
||||
* the key type identifier and the key size. Use this function instead
|
||||
* of psa_set_key_type() when you need to specify domain parameters.
|
||||
*
|
||||
* The format for the required domain parameters varies based on the key type.
|
||||
* Mbed TLS supports the following key type with domain parameters:
|
||||
*
|
||||
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
|
||||
* the domain parameter data consists of the public exponent,
|
||||
* represented as a big-endian integer with no leading zeros.
|
||||
* This information is used when generating an RSA key pair.
|
||||
* When importing a key, the public exponent is read from the imported
|
||||
* key data and the exponent recorded in the attribute structure is ignored.
|
||||
* As an exception, the public exponent 65537 is represented by an empty
|
||||
* byte string.
|
||||
*
|
||||
* \note This function may allocate memory or other resources.
|
||||
* Once you have called this function on an attribute structure,
|
||||
* you must call psa_reset_key_attributes() to free these resources.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \note Due to an implementation limitation, domain parameters are ignored
|
||||
* for keys that are managed by a driver.
|
||||
*
|
||||
* \param[in,out] attributes Attribute structure where the specified domain
|
||||
* parameters will be stored.
|
||||
* If this function fails, the content of
|
||||
* \p attributes is not modified.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[in] data Buffer containing the key domain parameters.
|
||||
* The content of this buffer is interpreted
|
||||
* according to \p type as described above.
|
||||
* \param data_length Size of the \p data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
|
||||
#define PSA_SET_KEY_DOMAIN_PARAMETERS
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
|
||||
|
||||
/**
|
||||
* \brief Get domain parameters for a key.
|
||||
*
|
||||
* Get the domain parameters for a key with this function, if any. The format
|
||||
* of the domain parameters written to \p data is specified in the
|
||||
* documentation for psa_set_key_domain_parameters().
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \note Due to an implementation limitation, domain parameters are not
|
||||
* supported with keys that are managed by a driver.
|
||||
*
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
* \param[out] data On success, the key domain parameters.
|
||||
* \param data_size Size of the \p data buffer in bytes.
|
||||
* The buffer is guaranteed to be large
|
||||
* enough if its size in bytes is at least
|
||||
* the value given by
|
||||
* PSA_KEY_DOMAIN_PARAMETERS_SIZE().
|
||||
* \param[out] data_length On success, the number of bytes
|
||||
* that make up the key domain parameters data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key is managed by a driver.
|
||||
*/
|
||||
psa_status_t psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Safe output buffer size for psa_get_key_domain_parameters().
|
||||
*
|
||||
* This macro returns a compile-time constant if its arguments are
|
||||
* compile-time constants.
|
||||
*
|
||||
* \warning This function may call its arguments multiple times or
|
||||
* zero times, so you should not pass arguments that contain
|
||||
* side effects.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param key_type A supported key type.
|
||||
* \param key_bits The size of the key in bits.
|
||||
*
|
||||
* \return If the parameters are valid and supported, return
|
||||
* a buffer size in bytes that guarantees that
|
||||
* psa_get_key_domain_parameters() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
*/
|
||||
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \
|
||||
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
0)
|
||||
#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/)
|
||||
#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/)
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
@ -223,6 +223,22 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
|
||||
return v;
|
||||
}
|
||||
|
||||
struct psa_key_production_parameters_s {
|
||||
/* Future versions may add other fields in this structure. */
|
||||
uint32_t flags;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
/** The default production parameters for key generation or key derivation.
|
||||
*
|
||||
* Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext()
|
||||
* with `params=PSA_KEY_PRODUCTION_PARAMETERS_INIT` and
|
||||
* `params_data_length == 0` is equivalent to
|
||||
* calling psa_generate_key() or psa_key_derivation_output_key()
|
||||
* respectively.
|
||||
*/
|
||||
#define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 }
|
||||
|
||||
struct psa_key_policy_s {
|
||||
psa_key_usage_t MBEDTLS_PRIVATE(usage);
|
||||
psa_algorithm_t MBEDTLS_PRIVATE(alg);
|
||||
@ -250,35 +266,15 @@ typedef uint16_t psa_key_bits_t;
|
||||
* conditionals. */
|
||||
#define PSA_MAX_KEY_BITS 0xfff8
|
||||
|
||||
/** A mask of flags that can be stored in key attributes.
|
||||
*
|
||||
* This type is also used internally to store flags in slots. Internal
|
||||
* flags are defined in library/psa_crypto_core.h. Internal flags may have
|
||||
* the same value as external flags if they are properly handled during
|
||||
* key creation and in psa_get_key_attributes.
|
||||
*/
|
||||
typedef uint16_t psa_key_attributes_flag_t;
|
||||
|
||||
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
|
||||
((psa_key_attributes_flag_t) 0x0001)
|
||||
|
||||
/* A mask of key attribute flags used externally only.
|
||||
* Only meant for internal checks inside the library. */
|
||||
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
|
||||
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
|
||||
0)
|
||||
|
||||
/* A mask of key attribute flags used both internally and externally.
|
||||
* Currently there aren't any. */
|
||||
#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
|
||||
0)
|
||||
|
||||
typedef struct {
|
||||
struct psa_key_attributes_s {
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
|
||||
int MBEDTLS_PRIVATE(has_slot_number);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
psa_key_type_t MBEDTLS_PRIVATE(type);
|
||||
psa_key_bits_t MBEDTLS_PRIVATE(bits);
|
||||
psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime);
|
||||
psa_key_policy_t MBEDTLS_PRIVATE(policy);
|
||||
psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags);
|
||||
/* This type has a different layout in the client view wrt the
|
||||
* service view of the key id, i.e. in service view usually is
|
||||
* expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined
|
||||
@ -291,45 +287,18 @@ typedef struct {
|
||||
* struct
|
||||
*/
|
||||
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id);
|
||||
} psa_core_key_attributes_t;
|
||||
|
||||
#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_TYPE_NONE, 0, \
|
||||
PSA_KEY_LIFETIME_VOLATILE, \
|
||||
PSA_KEY_POLICY_INIT, 0, \
|
||||
MBEDTLS_SVC_KEY_ID_INIT }
|
||||
|
||||
struct psa_key_attributes_s {
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
/* Unlike normal buffers, there are three cases for domain_parameters
|
||||
* and domain_parameters_size:
|
||||
* - domain_parameters_size == SIZE_MAX && domain_parameters == NULL:
|
||||
* Access to domain parameters is not supported for this key.
|
||||
* This is a hack which should not exist, intended for keys managed
|
||||
* by a driver, because drivers don't support domain parameters.
|
||||
* - domain_parameters_size == 0 && domain_parameters == NULL:
|
||||
* The domain parameters are empty.
|
||||
* - domain_parameters_size > 0 &&
|
||||
* domain_parameters == valid pointer to domain_parameters_size bytes:
|
||||
* The domain parameters are non-empty.
|
||||
*/
|
||||
void *MBEDTLS_PRIVATE(domain_parameters);
|
||||
size_t MBEDTLS_PRIVATE(domain_parameters_size);
|
||||
/* With client/service separation, struct psa_key_attributes_s is
|
||||
* marshalled through a transport channel between the client and
|
||||
* service side implementation of the PSA Crypto APIs, thus having
|
||||
* the mbedtls_svc_key_id_t id as the last field of this structure
|
||||
* allows for a more efficient marshalling/unmarshalling of parameters
|
||||
*/
|
||||
psa_core_key_attributes_t MBEDTLS_PRIVATE(core);
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
#define PSA_KEY_ATTRIBUTES_INIT { 0, NULL, 0, PSA_CORE_KEY_ATTRIBUTES_INIT }
|
||||
#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0,
|
||||
#else
|
||||
#define PSA_KEY_ATTRIBUTES_INIT { NULL, 0, PSA_CORE_KEY_ATTRIBUTES_INIT }
|
||||
#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER
|
||||
#endif
|
||||
#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \
|
||||
PSA_KEY_TYPE_NONE, 0, \
|
||||
PSA_KEY_LIFETIME_VOLATILE, \
|
||||
PSA_KEY_POLICY_INIT, \
|
||||
MBEDTLS_SVC_KEY_ID_INIT }
|
||||
|
||||
static inline struct psa_key_attributes_s psa_key_attributes_init(void)
|
||||
{
|
||||
@ -340,12 +309,12 @@ static inline struct psa_key_attributes_s psa_key_attributes_init(void)
|
||||
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
|
||||
psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime);
|
||||
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = key;
|
||||
attributes->MBEDTLS_PRIVATE(id) = key;
|
||||
|
||||
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) =
|
||||
attributes->MBEDTLS_PRIVATE(lifetime) =
|
||||
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_PERSISTENT,
|
||||
PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
|
||||
@ -355,26 +324,26 @@ static inline void psa_set_key_id(psa_key_attributes_t *attributes,
|
||||
static inline mbedtls_svc_key_id_t psa_get_key_id(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id);
|
||||
return attributes->MBEDTLS_PRIVATE(id);
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
|
||||
mbedtls_key_owner_id_t owner)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
|
||||
attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime;
|
||||
attributes->MBEDTLS_PRIVATE(lifetime) = lifetime;
|
||||
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
|
||||
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
|
||||
attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
|
||||
#else
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = 0;
|
||||
attributes->MBEDTLS_PRIVATE(id) = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -382,7 +351,7 @@ static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
|
||||
static inline psa_key_lifetime_t psa_get_key_lifetime(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
|
||||
return attributes->MBEDTLS_PRIVATE(lifetime);
|
||||
}
|
||||
|
||||
static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags)
|
||||
@ -400,72 +369,53 @@ static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
|
||||
psa_key_usage_t usage_flags)
|
||||
{
|
||||
psa_extend_key_usage_flags(&usage_flags);
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
|
||||
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
|
||||
}
|
||||
|
||||
static inline psa_key_usage_t psa_get_key_usage_flags(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
|
||||
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
|
||||
}
|
||||
|
||||
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
|
||||
attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
|
||||
}
|
||||
|
||||
static inline psa_algorithm_t psa_get_key_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
|
||||
return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
|
||||
}
|
||||
|
||||
/* This function is declared in crypto_extra.h, which comes after this
|
||||
* header file, but we need the function here, so repeat the declaration. */
|
||||
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
|
||||
#define PSA_SET_KEY_DOMAIN_PARAMETERS
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
|
||||
|
||||
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type)
|
||||
{
|
||||
if (attributes->MBEDTLS_PRIVATE(domain_parameters) == NULL) {
|
||||
/* Common case: quick path */
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = type;
|
||||
} else {
|
||||
/* Call the bigger function to free the old domain parameters.
|
||||
* Ignore any errors which may arise due to type requiring
|
||||
* non-default domain parameters, since this function can't
|
||||
* report errors. */
|
||||
(void) psa_set_key_domain_parameters(attributes, type, NULL, 0);
|
||||
}
|
||||
attributes->MBEDTLS_PRIVATE(type) = type;
|
||||
}
|
||||
|
||||
static inline psa_key_type_t psa_get_key_type(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type);
|
||||
return attributes->MBEDTLS_PRIVATE(type);
|
||||
}
|
||||
|
||||
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
|
||||
size_t bits)
|
||||
{
|
||||
if (bits > PSA_MAX_KEY_BITS) {
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
|
||||
attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
|
||||
} else {
|
||||
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
|
||||
attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t psa_get_key_bits(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
|
||||
return attributes->MBEDTLS_PRIVATE(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,6 +455,30 @@ typedef uint64_t psa_key_slot_number_t;
|
||||
*/
|
||||
typedef uint16_t psa_key_derivation_step_t;
|
||||
|
||||
/** \brief Custom parameters for key generation or key derivation.
|
||||
*
|
||||
* This is a structure type with at least the following fields:
|
||||
*
|
||||
* - \c flags: an unsigned integer type. 0 for the default production parameters.
|
||||
* - \c data: a flexible array of bytes.
|
||||
*
|
||||
* The interpretation of this structure depend on the type of the
|
||||
* created key.
|
||||
*
|
||||
* - #PSA_KEY_TYPE_RSA_KEY_PAIR:
|
||||
* - \c flags: must be 0.
|
||||
* - \c data: the public exponent, in little-endian order.
|
||||
* This must be an odd integer and must not be 1.
|
||||
* Implementations must support 65535, should support 3 and may
|
||||
* support other values.
|
||||
* When not using a driver, Mbed TLS supports values up to \c INT_MAX.
|
||||
* If this is empty or if the custom production parameters are omitted
|
||||
* altogether, the default value 65537 is used.
|
||||
* - Other key types: reserved for future use. \c flags must be 0.
|
||||
*
|
||||
*/
|
||||
typedef struct psa_key_production_parameters_s psa_key_production_parameters_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* PSA_CRYPTO_TYPES_H */
|
||||
|
@ -413,7 +413,7 @@
|
||||
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||
/** The public key type corresponding to a key pair type.
|
||||
*
|
||||
* You may also pass a key pair type as \p type, it will be left unchanged.
|
||||
* You may also pass a public key type as \p type, it will be left unchanged.
|
||||
*
|
||||
* \param type A public key type or key pair type.
|
||||
*
|
||||
|
@ -56,6 +56,7 @@ set(src_crypto
|
||||
padlock.c
|
||||
pem.c
|
||||
pk.c
|
||||
pk_ecc.c
|
||||
pk_wrap.c
|
||||
pkcs12.c
|
||||
pkcs5.c
|
||||
|
@ -1,3 +1,26 @@
|
||||
ifndef MBEDTLS_PATH
|
||||
MBEDTLS_PATH := ..
|
||||
endif
|
||||
|
||||
GENERATED_FILES := \
|
||||
error.c version_features.c \
|
||||
ssl_debug_helpers_generated.c \
|
||||
psa_crypto_driver_wrappers.h \
|
||||
psa_crypto_driver_wrappers_no_static.c
|
||||
|
||||
ifneq ($(GENERATED_FILES),$(wildcard $(GENERATED_FILES)))
|
||||
ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make))
|
||||
# Use the define keyword to get a multi-line message.
|
||||
# GNU make appends ". Stop.", so tweak the ending of our message accordingly.
|
||||
define error_message
|
||||
$(MBEDTLS_PATH)/framework/exported.make not found.
|
||||
Run `git submodule update --init` to fetch the submodule contents.
|
||||
This is a fatal error
|
||||
endef
|
||||
$(error $(error_message))
|
||||
endif
|
||||
include $(MBEDTLS_PATH)/framework/exported.make
|
||||
endif
|
||||
|
||||
# Also see "include/mbedtls/mbedtls_config.h"
|
||||
|
||||
@ -125,6 +148,7 @@ OBJS_CRYPTO= \
|
||||
padlock.o \
|
||||
pem.o \
|
||||
pk.o \
|
||||
pk_ecc.o \
|
||||
pk_wrap.o \
|
||||
pkcs12.o \
|
||||
pkcs5.o \
|
||||
@ -314,11 +338,6 @@ libmbedcrypto.dll: $(OBJS_CRYPTO)
|
||||
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
.PHONY: generated_files
|
||||
GENERATED_FILES = \
|
||||
error.c version_features.c \
|
||||
ssl_debug_helpers_generated.c \
|
||||
psa_crypto_driver_wrappers.h \
|
||||
psa_crypto_driver_wrappers_no_static.c
|
||||
generated_files: $(GENERATED_FILES)
|
||||
|
||||
# See root Makefile
|
||||
|
378
library/bignum.c
378
library/bignum.c
@ -37,6 +37,19 @@
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Conditionally select an MPI sign in constant time.
|
||||
* (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
|
||||
* values.)
|
||||
*/
|
||||
static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
|
||||
signed short sign1, signed short sign2)
|
||||
{
|
||||
return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare signed values in constant time
|
||||
*/
|
||||
@ -112,7 +125,7 @@ int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
|
||||
{
|
||||
mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
|
||||
|
||||
X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s);
|
||||
X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
|
||||
|
||||
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
|
||||
|
||||
@ -149,8 +162,8 @@ int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
|
||||
|
||||
s = X->s;
|
||||
X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s);
|
||||
Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s);
|
||||
X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
|
||||
Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
|
||||
|
||||
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
|
||||
|
||||
@ -288,8 +301,7 @@ static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)
|
||||
* This function is not constant-time. Leading zeros in Y may be removed.
|
||||
*
|
||||
* Ensure that X does not shrink. This is not guaranteed by the public API,
|
||||
* but some code in the bignum module relies on this property, for example
|
||||
* in mbedtls_mpi_exp_mod().
|
||||
* but some code in the bignum module might still rely on this property.
|
||||
*/
|
||||
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
|
||||
{
|
||||
@ -1598,98 +1610,11 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N)
|
||||
{
|
||||
*mm = mbedtls_mpi_core_montmul_init(N->p);
|
||||
}
|
||||
|
||||
/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
|
||||
*
|
||||
* \param[in,out] A One of the numbers to multiply.
|
||||
* It must have at least as many limbs as N
|
||||
* (A->n >= N->n), and any limbs beyond n are ignored.
|
||||
* On successful completion, A contains the result of
|
||||
* the multiplication A * B * R^-1 mod N where
|
||||
* R = (2^ciL)^n.
|
||||
* \param[in] B One of the numbers to multiply.
|
||||
* It must be nonzero and must not have more limbs than N
|
||||
* (B->n <= N->n).
|
||||
* \param[in] N The modulus. \p N must be odd.
|
||||
* \param mm The value calculated by `mpi_montg_init(&mm, N)`.
|
||||
* This is -N^-1 mod 2^ciL.
|
||||
* \param[in,out] T A bignum for temporary storage.
|
||||
* It must be at least twice the limb size of N plus 1
|
||||
* (T->n >= 2 * N->n + 1).
|
||||
* Its initial content is unused and
|
||||
* its final content is indeterminate.
|
||||
* It does not get reallocated.
|
||||
*/
|
||||
static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B,
|
||||
const mbedtls_mpi *N, mbedtls_mpi_uint mm,
|
||||
mbedtls_mpi *T)
|
||||
{
|
||||
mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Montgomery reduction: A = A * R^-1 mod N
|
||||
*
|
||||
* See mpi_montmul() regarding constraints and guarantees on the parameters.
|
||||
*/
|
||||
static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
|
||||
mbedtls_mpi_uint mm, mbedtls_mpi *T)
|
||||
{
|
||||
mbedtls_mpi_uint z = 1;
|
||||
mbedtls_mpi U;
|
||||
U.n = 1;
|
||||
U.s = 1;
|
||||
U.p = &z;
|
||||
|
||||
mpi_montmul(A, &U, N, mm, T);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an MPI from a table without leaking the index.
|
||||
*
|
||||
* This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
|
||||
* reads the entire table in order to avoid leaking the value of idx to an
|
||||
* attacker able to observe memory access patterns.
|
||||
*
|
||||
* \param[out] R Where to write the selected MPI.
|
||||
* \param[in] T The table to read from.
|
||||
* \param[in] T_size The number of elements in the table.
|
||||
* \param[in] idx The index of the element to select;
|
||||
* this must satisfy 0 <= idx < T_size.
|
||||
*
|
||||
* \return \c 0 on success, or a negative error code.
|
||||
*/
|
||||
static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
for (size_t i = 0; i < T_size; i++) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
|
||||
(unsigned char) mbedtls_ct_uint_eq(i, idx)));
|
||||
}
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
|
||||
*/
|
||||
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t window_bitsize;
|
||||
size_t i, j, nblimbs;
|
||||
size_t bufsize, nbits;
|
||||
size_t exponent_bits_in_window = 0;
|
||||
mbedtls_mpi_uint ei, mm, state;
|
||||
mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
|
||||
int neg;
|
||||
|
||||
if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
@ -1705,261 +1630,88 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
}
|
||||
|
||||
/*
|
||||
* Init temps and window size
|
||||
* Ensure that the exponent that we are passing to the core is not NULL.
|
||||
*/
|
||||
mpi_montg_init(&mm, N);
|
||||
mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T);
|
||||
mbedtls_mpi_init(&Apos);
|
||||
mbedtls_mpi_init(&WW);
|
||||
memset(W, 0, sizeof(W));
|
||||
|
||||
i = mbedtls_mpi_bitlen(E);
|
||||
|
||||
window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 :
|
||||
(i > 79) ? 4 : (i > 23) ? 3 : 1;
|
||||
|
||||
#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
|
||||
if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) {
|
||||
window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
|
||||
if (E->n == 0) {
|
||||
ret = mbedtls_mpi_lset(X, 1);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
const size_t w_table_used_size = (size_t) 1 << window_bitsize;
|
||||
|
||||
/*
|
||||
* This function is not constant-trace: its memory accesses depend on the
|
||||
* exponent value. To defend against timing attacks, callers (such as RSA
|
||||
* and DHM) should use exponent blinding. However this is not enough if the
|
||||
* adversary can find the exponent in a single trace, so this function
|
||||
* takes extra precautions against adversaries who can observe memory
|
||||
* access patterns.
|
||||
*
|
||||
* This function performs a series of multiplications by table elements and
|
||||
* squarings, and we want the prevent the adversary from finding out which
|
||||
* table element was used, and from distinguishing between multiplications
|
||||
* and squarings. Firstly, when multiplying by an element of the window
|
||||
* W[i], we do a constant-trace table lookup to obfuscate i. This leaves
|
||||
* squarings as having a different memory access patterns from other
|
||||
* multiplications. So secondly, we put the accumulator in the table as
|
||||
* well, and also do a constant-trace table lookup to multiply by the
|
||||
* accumulator which is W[x_index].
|
||||
*
|
||||
* This way, all multiplications take the form of a lookup-and-multiply.
|
||||
* The number of lookup-and-multiply operations inside each iteration of
|
||||
* the main loop still depends on the bits of the exponent, but since the
|
||||
* other operations in the loop don't have an easily recognizable memory
|
||||
* trace, an adversary is unlikely to be able to observe the exact
|
||||
* patterns.
|
||||
*
|
||||
* An adversary may still be able to recover the exponent if they can
|
||||
* observe both memory accesses and branches. However, branch prediction
|
||||
* exploitation typically requires many traces of execution over the same
|
||||
* data, which is defeated by randomized blinding.
|
||||
* Allocate working memory for mbedtls_mpi_core_exp_mod()
|
||||
*/
|
||||
const size_t x_index = 0;
|
||||
mbedtls_mpi_init(&W[x_index]);
|
||||
|
||||
j = N->n + 1;
|
||||
/* All W[i] including the accumulator must have at least N->n limbs for
|
||||
* the mpi_montmul() and mpi_montred() calls later. Here we ensure that
|
||||
* W[1] and the accumulator W[x_index] are large enough. later we'll grow
|
||||
* other W[i] to the same length. They must not be shrunk midway through
|
||||
* this function!
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
|
||||
|
||||
/*
|
||||
* Compensate for negative A (and correct at the end)
|
||||
*/
|
||||
neg = (A->s == -1);
|
||||
if (neg) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
|
||||
Apos.s = 1;
|
||||
A = &Apos;
|
||||
size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
|
||||
mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
|
||||
if (T == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_mpi RR;
|
||||
mbedtls_mpi_init(&RR);
|
||||
|
||||
/*
|
||||
* If 1st call, pre-compute R^2 mod N
|
||||
*/
|
||||
if (prec_RR == NULL || prec_RR->p == NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
|
||||
|
||||
if (prec_RR != NULL) {
|
||||
memcpy(prec_RR, &RR, sizeof(mbedtls_mpi));
|
||||
*prec_RR = RR;
|
||||
}
|
||||
} else {
|
||||
memcpy(&RR, prec_RR, sizeof(mbedtls_mpi));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
|
||||
RR = *prec_RR;
|
||||
}
|
||||
|
||||
/*
|
||||
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
|
||||
* To preserve constness we need to make a copy of A. Using X for this to
|
||||
* save memory.
|
||||
*/
|
||||
if (mbedtls_mpi_cmp_mpi(A, N) >= 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
|
||||
/* This should be a no-op because W[1] is already that large before
|
||||
* mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
|
||||
* in mpi_montmul() below, so let's make sure. */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1));
|
||||
} else {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
|
||||
}
|
||||
|
||||
/* Note that this is safe because W[1] always has at least N->n limbs
|
||||
* (it grew above and was preserved by mbedtls_mpi_copy()). */
|
||||
mpi_montmul(&W[1], &RR, N, mm, &T);
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
|
||||
|
||||
/*
|
||||
* W[x_index] = R^2 * R^-1 mod N = R mod N
|
||||
* Compensate for negative A (and correct at the end).
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR));
|
||||
mpi_montred(&W[x_index], N, mm, &T);
|
||||
X->s = 1;
|
||||
|
||||
|
||||
if (window_bitsize > 1) {
|
||||
/*
|
||||
* W[i] = W[1] ^ i
|
||||
*
|
||||
* The first bit of the sliding window is always 1 and therefore we
|
||||
* only need to store the second half of the table.
|
||||
*
|
||||
* (There are two special elements in the table: W[0] for the
|
||||
* accumulator/result and W[1] for A in Montgomery form. Both of these
|
||||
* are already set at this point.)
|
||||
*/
|
||||
j = w_table_used_size / 2;
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
|
||||
|
||||
for (i = 0; i < window_bitsize - 1; i++) {
|
||||
mpi_montmul(&W[j], &W[j], N, mm, &T);
|
||||
}
|
||||
|
||||
/*
|
||||
* W[i] = W[i - 1] * W[1]
|
||||
*/
|
||||
for (i = j + 1; i < w_table_used_size; i++) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
|
||||
|
||||
mpi_montmul(&W[i], &W[1], N, mm, &T);
|
||||
}
|
||||
/*
|
||||
* Make sure that X is in a form that is safe for consumption by
|
||||
* the core functions.
|
||||
*
|
||||
* - The core functions will not touch the limbs of X above N->n. The
|
||||
* result will be correct if those limbs are 0, which the mod call
|
||||
* ensures.
|
||||
* - Also, X must have at least as many limbs as N for the calls to the
|
||||
* core functions.
|
||||
*/
|
||||
if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
|
||||
}
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
|
||||
|
||||
nblimbs = E->n;
|
||||
bufsize = 0;
|
||||
nbits = 0;
|
||||
state = 0;
|
||||
|
||||
while (1) {
|
||||
if (bufsize == 0) {
|
||||
if (nblimbs == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
nblimbs--;
|
||||
|
||||
bufsize = sizeof(mbedtls_mpi_uint) << 3;
|
||||
}
|
||||
|
||||
bufsize--;
|
||||
|
||||
ei = (E->p[nblimbs] >> bufsize) & 1;
|
||||
|
||||
/*
|
||||
* skip leading 0s
|
||||
*/
|
||||
if (ei == 0 && state == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ei == 0 && state == 1) {
|
||||
/*
|
||||
* out of window, square W[x_index]
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
|
||||
mpi_montmul(&W[x_index], &WW, N, mm, &T);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* add ei to current window
|
||||
*/
|
||||
state = 2;
|
||||
|
||||
nbits++;
|
||||
exponent_bits_in_window |= (ei << (window_bitsize - nbits));
|
||||
|
||||
if (nbits == window_bitsize) {
|
||||
/*
|
||||
* W[x_index] = W[x_index]^window_bitsize R^-1 mod N
|
||||
*/
|
||||
for (i = 0; i < window_bitsize; i++) {
|
||||
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
|
||||
x_index));
|
||||
mpi_montmul(&W[x_index], &WW, N, mm, &T);
|
||||
}
|
||||
|
||||
/*
|
||||
* W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
|
||||
exponent_bits_in_window));
|
||||
mpi_montmul(&W[x_index], &WW, N, mm, &T);
|
||||
|
||||
state--;
|
||||
nbits = 0;
|
||||
exponent_bits_in_window = 0;
|
||||
}
|
||||
/*
|
||||
* Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
|
||||
*/
|
||||
{
|
||||
mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
|
||||
mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
|
||||
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
|
||||
mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
|
||||
}
|
||||
|
||||
/*
|
||||
* process the remaining bits
|
||||
* Correct for negative A.
|
||||
*/
|
||||
for (i = 0; i < nbits; i++) {
|
||||
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
|
||||
mpi_montmul(&W[x_index], &WW, N, mm, &T);
|
||||
if (A->s == -1 && (E->p[0] & 1) != 0) {
|
||||
mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
|
||||
X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
|
||||
|
||||
exponent_bits_in_window <<= 1;
|
||||
|
||||
if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) {
|
||||
MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1));
|
||||
mpi_montmul(&W[x_index], &WW, N, mm, &T);
|
||||
}
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
|
||||
}
|
||||
|
||||
/*
|
||||
* W[x_index] = A^E * R * R^-1 mod N = A^E mod N
|
||||
*/
|
||||
mpi_montred(&W[x_index], N, mm, &T);
|
||||
|
||||
if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
|
||||
W[x_index].s = -1;
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index]));
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the result in the output variable.
|
||||
*/
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
|
||||
|
||||
cleanup:
|
||||
|
||||
/* The first bit of the sliding window is always 1 and therefore the first
|
||||
* half of the table was unused. */
|
||||
for (i = w_table_used_size/2; i < w_table_used_size; i++) {
|
||||
mbedtls_mpi_free(&W[i]);
|
||||
}
|
||||
|
||||
mbedtls_mpi_free(&W[x_index]);
|
||||
mbedtls_mpi_free(&W[1]);
|
||||
mbedtls_mpi_free(&T);
|
||||
mbedtls_mpi_free(&Apos);
|
||||
mbedtls_mpi_free(&WW);
|
||||
mbedtls_mpi_zeroize_and_free(T, T_limbs);
|
||||
|
||||
if (prec_RR == NULL || prec_RR->p == NULL) {
|
||||
mbedtls_mpi_free(&RR);
|
||||
|
@ -856,16 +856,17 @@ mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
|
||||
return c;
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
|
||||
size_t limbs)
|
||||
mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
|
||||
size_t limbs)
|
||||
{
|
||||
volatile const mbedtls_mpi_uint *force_read_A = A;
|
||||
mbedtls_mpi_uint bits = 0;
|
||||
|
||||
for (size_t i = 0; i < limbs; i++) {
|
||||
bits |= A[i];
|
||||
bits |= force_read_A[i];
|
||||
}
|
||||
|
||||
return bits;
|
||||
return mbedtls_ct_bool(bits);
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,
|
||||
|
@ -662,11 +662,11 @@ mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
|
||||
* \param[in] A The MPI to test.
|
||||
* \param limbs Number of limbs in \p A.
|
||||
*
|
||||
* \return 0 if `A == 0`
|
||||
* non-0 (may be any value) if `A != 0`.
|
||||
* \return MBEDTLS_CT_FALSE if `A == 0`
|
||||
* MBEDTLS_CT_TRUE if `A != 0`.
|
||||
*/
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
|
||||
size_t limbs);
|
||||
mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
|
||||
size_t limbs);
|
||||
|
||||
/**
|
||||
* \brief Returns the number of limbs of working memory required for
|
||||
|
@ -56,22 +56,29 @@ static int cmac_multiply_by_u(unsigned char *output,
|
||||
size_t blocksize)
|
||||
{
|
||||
const unsigned char R_128 = 0x87;
|
||||
const unsigned char R_64 = 0x1B;
|
||||
unsigned char R_n, mask;
|
||||
unsigned char overflow = 0x00;
|
||||
uint32_t overflow = 0x00;
|
||||
int i;
|
||||
|
||||
if (blocksize == MBEDTLS_AES_BLOCK_SIZE) {
|
||||
R_n = R_128;
|
||||
} else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
|
||||
}
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) {
|
||||
const unsigned char R_64 = 0x1B;
|
||||
R_n = R_64;
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
for (i = (int) blocksize - 1; i >= 0; i--) {
|
||||
output[i] = input[i] << 1 | overflow;
|
||||
overflow = input[i] >> 7;
|
||||
for (i = (int) blocksize - 4; i >= 0; i -= 4) {
|
||||
uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0);
|
||||
uint32_t new_overflow = i32 >> 31;
|
||||
i32 = (i32 << 1) | overflow;
|
||||
MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0);
|
||||
overflow = new_overflow;
|
||||
}
|
||||
|
||||
/* mask = ( input[0] >> 7 ) ? 0xff : 0x00
|
||||
@ -217,6 +224,10 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
|
||||
block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
|
||||
state = ctx->cmac_ctx->state;
|
||||
|
||||
/* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form
|
||||
* error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */
|
||||
MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE);
|
||||
|
||||
/* Is there data still to process from the last call, that's greater in
|
||||
* size than a block? */
|
||||
if (cmac_ctx->unprocessed_len > 0 &&
|
||||
@ -284,6 +295,7 @@ int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
|
||||
|
||||
cmac_ctx = ctx->cmac_ctx;
|
||||
block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
|
||||
MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning
|
||||
state = cmac_ctx->state;
|
||||
|
||||
mbedtls_platform_zeroize(K1, sizeof(K1));
|
||||
|
@ -144,6 +144,15 @@ static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx)
|
||||
#endif
|
||||
}
|
||||
|
||||
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
return ctx->MBEDTLS_PRIVATE(grp).id;
|
||||
#else
|
||||
return ctx->MBEDTLS_PRIVATE(grp_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
|
@ -3302,10 +3302,11 @@ cleanup:
|
||||
/*
|
||||
* Write a private key.
|
||||
*/
|
||||
#if !defined MBEDTLS_DEPRECATED_REMOVED
|
||||
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
|
||||
unsigned char *buf, size_t buflen)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
||||
@ -3332,6 +3333,39 @@ cleanup:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
|
||||
size_t *olen, unsigned char *buf, size_t buflen)
|
||||
{
|
||||
size_t len = (key->grp.nbits + 7) / 8;
|
||||
if (len > buflen) {
|
||||
/* For robustness, ensure *olen <= buflen even on error. */
|
||||
*olen = 0;
|
||||
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*olen = len;
|
||||
|
||||
/* Private key not set */
|
||||
if (key->d.n == 0) {
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
|
||||
return mbedtls_mpi_write_binary_le(&key->d, buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
|
||||
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
|
||||
return mbedtls_mpi_write_binary(&key->d, buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private key set but no recognized curve type? This shouldn't happen. */
|
||||
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a public key.
|
||||
|
315
library/gcm.c
315
library/gcm.c
@ -41,6 +41,12 @@
|
||||
|
||||
#if !defined(MBEDTLS_GCM_ALT)
|
||||
|
||||
/* Used to select the acceleration mechanism */
|
||||
#define MBEDTLS_GCM_ACC_SMALLTABLE 0
|
||||
#define MBEDTLS_GCM_ACC_LARGETABLE 1
|
||||
#define MBEDTLS_GCM_ACC_AESNI 2
|
||||
#define MBEDTLS_GCM_ACC_AESCE 3
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
@ -49,6 +55,39 @@ void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
|
||||
memset(ctx, 0, sizeof(mbedtls_gcm_context));
|
||||
}
|
||||
|
||||
static inline void gcm_set_acceleration(mbedtls_gcm_context *ctx)
|
||||
{
|
||||
#if defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
ctx->acceleration = MBEDTLS_GCM_ACC_LARGETABLE;
|
||||
#else
|
||||
ctx->acceleration = MBEDTLS_GCM_ACC_SMALLTABLE;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
/* With CLMUL support, we need only h, not the rest of the table */
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
ctx->acceleration = MBEDTLS_GCM_ACC_AESNI;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESCE_HAVE_CODE)
|
||||
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
|
||||
ctx->acceleration = MBEDTLS_GCM_ACC_AESCE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void gcm_gen_table_rightshift(uint64_t dst[2], const uint64_t src[2])
|
||||
{
|
||||
uint8_t *u8Dst = (uint8_t *) dst;
|
||||
uint8_t *u8Src = (uint8_t *) src;
|
||||
|
||||
MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[1], 0) >> 1, &dst[1], 0);
|
||||
u8Dst[8] |= (u8Src[7] & 0x01) << 7;
|
||||
MBEDTLS_PUT_UINT64_BE(MBEDTLS_GET_UINT64_BE(&src[0], 0) >> 1, &dst[0], 0);
|
||||
u8Dst[0] ^= (u8Src[15] & 0x01) ? 0xE1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Precompute small multiples of H, that is set
|
||||
* HH[i] || HL[i] = H times i,
|
||||
@ -60,11 +99,8 @@ void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
|
||||
static int gcm_gen_table(mbedtls_gcm_context *ctx)
|
||||
{
|
||||
int ret, i, j;
|
||||
uint64_t hi, lo;
|
||||
uint64_t vl, vh;
|
||||
unsigned char h[16];
|
||||
|
||||
memset(h, 0, 16);
|
||||
uint64_t u64h[2] = { 0 };
|
||||
uint8_t *h = (uint8_t *) u64h;
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
|
||||
@ -76,53 +112,48 @@ static int gcm_gen_table(mbedtls_gcm_context *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* pack h as two 64-bits ints, big-endian */
|
||||
hi = MBEDTLS_GET_UINT32_BE(h, 0);
|
||||
lo = MBEDTLS_GET_UINT32_BE(h, 4);
|
||||
vh = (uint64_t) hi << 32 | lo;
|
||||
gcm_set_acceleration(ctx);
|
||||
|
||||
hi = MBEDTLS_GET_UINT32_BE(h, 8);
|
||||
lo = MBEDTLS_GET_UINT32_BE(h, 12);
|
||||
vl = (uint64_t) hi << 32 | lo;
|
||||
|
||||
/* 8 = 1000 corresponds to 1 in GF(2^128) */
|
||||
ctx->HL[8] = vl;
|
||||
ctx->HH[8] = vh;
|
||||
/* MBEDTLS_GCM_HTABLE_SIZE/2 = 1000 corresponds to 1 in GF(2^128) */
|
||||
ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][0] = u64h[0];
|
||||
ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2][1] = u64h[1];
|
||||
|
||||
switch (ctx->acceleration) {
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
/* With CLMUL support, we need only h, not the rest of the table */
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
return 0;
|
||||
}
|
||||
case MBEDTLS_GCM_ACC_AESNI:
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESCE_HAVE_CODE)
|
||||
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
|
||||
return 0;
|
||||
}
|
||||
case MBEDTLS_GCM_ACC_AESCE:
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* 0 corresponds to 0 in GF(2^128) */
|
||||
ctx->HH[0] = 0;
|
||||
ctx->HL[0] = 0;
|
||||
default:
|
||||
/* 0 corresponds to 0 in GF(2^128) */
|
||||
ctx->H[0][0] = 0;
|
||||
ctx->H[0][1] = 0;
|
||||
|
||||
for (i = 4; i > 0; i >>= 1) {
|
||||
uint32_t T = (vl & 1) * 0xe1000000U;
|
||||
vl = (vh << 63) | (vl >> 1);
|
||||
vh = (vh >> 1) ^ ((uint64_t) T << 32);
|
||||
for (i = MBEDTLS_GCM_HTABLE_SIZE/4; i > 0; i >>= 1) {
|
||||
gcm_gen_table_rightshift(ctx->H[i], ctx->H[i*2]);
|
||||
}
|
||||
|
||||
ctx->HL[i] = vl;
|
||||
ctx->HH[i] = vh;
|
||||
}
|
||||
#if !defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
/* pack elements of H as 64-bits ints, big-endian */
|
||||
for (i = MBEDTLS_GCM_HTABLE_SIZE/2; i > 0; i >>= 1) {
|
||||
MBEDTLS_PUT_UINT64_BE(ctx->H[i][0], &ctx->H[i][0], 0);
|
||||
MBEDTLS_PUT_UINT64_BE(ctx->H[i][1], &ctx->H[i][1], 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 2; i <= 8; i *= 2) {
|
||||
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
|
||||
vh = *HiH;
|
||||
vl = *HiL;
|
||||
for (j = 1; j < i; j++) {
|
||||
HiH[j] = vh ^ ctx->HH[j];
|
||||
HiL[j] = vl ^ ctx->HL[j];
|
||||
}
|
||||
for (i = 2; i < MBEDTLS_GCM_HTABLE_SIZE; i <<= 1) {
|
||||
for (j = 1; j < i; j++) {
|
||||
mbedtls_xor_no_simd((unsigned char *) ctx->H[i+j],
|
||||
(unsigned char *) ctx->H[i],
|
||||
(unsigned char *) ctx->H[j],
|
||||
16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -181,6 +212,80 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
static const uint16_t last8[256] = {
|
||||
0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05,
|
||||
0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b,
|
||||
0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19,
|
||||
0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17,
|
||||
0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d,
|
||||
0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33,
|
||||
0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21,
|
||||
0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f,
|
||||
0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75,
|
||||
0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b,
|
||||
0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69,
|
||||
0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67,
|
||||
0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d,
|
||||
0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43,
|
||||
0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51,
|
||||
0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f,
|
||||
0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4,
|
||||
0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea,
|
||||
0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8,
|
||||
0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6,
|
||||
0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc,
|
||||
0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2,
|
||||
0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0,
|
||||
0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece,
|
||||
0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94,
|
||||
0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a,
|
||||
0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88,
|
||||
0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86,
|
||||
0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac,
|
||||
0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2,
|
||||
0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0,
|
||||
0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe
|
||||
};
|
||||
|
||||
static void gcm_mult_largetable(uint8_t *output, const uint8_t *x, uint64_t H[256][2])
|
||||
{
|
||||
int i;
|
||||
uint64_t u64z[2];
|
||||
uint16_t *u16z = (uint16_t *) u64z;
|
||||
uint8_t *u8z = (uint8_t *) u64z;
|
||||
uint8_t rem;
|
||||
|
||||
u64z[0] = 0;
|
||||
u64z[1] = 0;
|
||||
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) {
|
||||
for (i = 15; i > 0; i--) {
|
||||
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
|
||||
rem = u8z[15];
|
||||
|
||||
u64z[1] >>= 8;
|
||||
u8z[8] = u8z[7];
|
||||
u64z[0] >>= 8;
|
||||
|
||||
u16z[0] ^= MBEDTLS_GET_UINT16_LE(&last8[rem], 0);
|
||||
}
|
||||
} else {
|
||||
for (i = 15; i > 0; i--) {
|
||||
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[x[i]], 16);
|
||||
rem = u8z[15];
|
||||
|
||||
u64z[1] <<= 8;
|
||||
u8z[8] = u8z[7];
|
||||
u64z[0] <<= 8;
|
||||
|
||||
u16z[0] ^= last8[rem];
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_xor_no_simd(output, u8z, (uint8_t *) H[x[0]], 16);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Shoup's method for multiplication use this table with
|
||||
* last4[x] = x times P^128
|
||||
@ -194,6 +299,47 @@ static const uint16_t last4[16] =
|
||||
0x9180, 0x8da0, 0xa9c0, 0xb5e0
|
||||
};
|
||||
|
||||
static void gcm_mult_smalltable(uint8_t *output, const uint8_t *x, uint64_t H[16][2])
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char lo, hi, rem;
|
||||
uint64_t u64z[2];
|
||||
const uint64_t *pu64z = NULL;
|
||||
uint8_t *u8z = (uint8_t *) u64z;
|
||||
|
||||
lo = x[15] & 0xf;
|
||||
hi = (x[15] >> 4) & 0xf;
|
||||
|
||||
pu64z = H[lo];
|
||||
|
||||
rem = (unsigned char) pu64z[1] & 0xf;
|
||||
u64z[1] = (pu64z[0] << 60) | (pu64z[1] >> 4);
|
||||
u64z[0] = (pu64z[0] >> 4);
|
||||
u64z[0] ^= (uint64_t) last4[rem] << 48;
|
||||
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
|
||||
|
||||
for (i = 14; i >= 0; i--) {
|
||||
lo = x[i] & 0xf;
|
||||
hi = (x[i] >> 4) & 0xf;
|
||||
|
||||
rem = (unsigned char) u64z[1] & 0xf;
|
||||
u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
|
||||
u64z[0] = (u64z[0] >> 4);
|
||||
u64z[0] ^= (uint64_t) last4[rem] << 48;
|
||||
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[lo], 16);
|
||||
|
||||
rem = (unsigned char) u64z[1] & 0xf;
|
||||
u64z[1] = (u64z[0] << 60) | (u64z[1] >> 4);
|
||||
u64z[0] = (u64z[0] >> 4);
|
||||
u64z[0] ^= (uint64_t) last4[rem] << 48;
|
||||
mbedtls_xor_no_simd(u8z, u8z, (uint8_t *) H[hi], 16);
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT64_BE(u64z[0], output, 0);
|
||||
MBEDTLS_PUT_UINT64_BE(u64z[1], output, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Sets output to x times H using the precomputed tables.
|
||||
* x and output are seen as elements of GF(2^128) as in [MGV].
|
||||
@ -201,71 +347,31 @@ static const uint16_t last4[16] =
|
||||
static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
|
||||
unsigned char output[16])
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char lo, hi, rem;
|
||||
uint64_t zh, zl;
|
||||
|
||||
switch (ctx->acceleration) {
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
unsigned char h[16];
|
||||
|
||||
/* mbedtls_aesni_gcm_mult needs big-endian input */
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
|
||||
|
||||
mbedtls_aesni_gcm_mult(output, x, h);
|
||||
return;
|
||||
}
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
|
||||
#if defined(MBEDTLS_AESCE_HAVE_CODE)
|
||||
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
|
||||
unsigned char h[16];
|
||||
|
||||
/* mbedtls_aesce_gcm_mult needs big-endian input */
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12);
|
||||
|
||||
mbedtls_aesce_gcm_mult(output, x, h);
|
||||
return;
|
||||
}
|
||||
case MBEDTLS_GCM_ACC_AESNI:
|
||||
mbedtls_aesni_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
lo = x[15] & 0xf;
|
||||
#if defined(MBEDTLS_AESCE_HAVE_CODE)
|
||||
case MBEDTLS_GCM_ACC_AESCE:
|
||||
mbedtls_aesce_gcm_mult(output, x, (uint8_t *) ctx->H[MBEDTLS_GCM_HTABLE_SIZE/2]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
zh = ctx->HH[lo];
|
||||
zl = ctx->HL[lo];
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
lo = x[i] & 0xf;
|
||||
hi = (x[i] >> 4) & 0xf;
|
||||
|
||||
if (i != 15) {
|
||||
rem = (unsigned char) zl & 0xf;
|
||||
zl = (zh << 60) | (zl >> 4);
|
||||
zh = (zh >> 4);
|
||||
zh ^= (uint64_t) last4[rem] << 48;
|
||||
zh ^= ctx->HH[lo];
|
||||
zl ^= ctx->HL[lo];
|
||||
|
||||
}
|
||||
|
||||
rem = (unsigned char) zl & 0xf;
|
||||
zl = (zh << 60) | (zl >> 4);
|
||||
zh = (zh >> 4);
|
||||
zh ^= (uint64_t) last4[rem] << 48;
|
||||
zh ^= ctx->HH[hi];
|
||||
zl ^= ctx->HL[hi];
|
||||
#if defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
case MBEDTLS_GCM_ACC_LARGETABLE:
|
||||
gcm_mult_largetable(output, x, ctx->H);
|
||||
break;
|
||||
#else
|
||||
case MBEDTLS_GCM_ACC_SMALLTABLE:
|
||||
gcm_mult_smalltable(output, x, ctx->H);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0);
|
||||
MBEDTLS_PUT_UINT32_BE(zh, output, 4);
|
||||
MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8);
|
||||
MBEDTLS_PUT_UINT32_BE(zl, output, 12);
|
||||
return;
|
||||
}
|
||||
|
||||
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
|
||||
@ -306,8 +412,17 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
|
||||
while (iv_len > 0) {
|
||||
use_len = (iv_len < 16) ? iv_len : 16;
|
||||
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic warning "-Wstringop-overflow=0"
|
||||
#endif
|
||||
|
||||
mbedtls_xor(ctx->y, ctx->y, p, use_len);
|
||||
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
gcm_mult(ctx, ctx->y, ctx->y);
|
||||
|
||||
iv_len -= use_len;
|
||||
|
@ -240,6 +240,29 @@ exit:
|
||||
}
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
|
||||
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
|
||||
{
|
||||
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
|
||||
size_t pad_len = input[input_len - 1];
|
||||
size_t i;
|
||||
|
||||
if (pad_len > input_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
|
||||
*data_len = input_len - pad_len;
|
||||
|
||||
for (i = *data_len; i < input_len; i++) {
|
||||
if (input[i] != pad_len) {
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */
|
||||
|
||||
#endif /* PEM_RFC1421 */
|
||||
|
||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||
@ -389,6 +412,10 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return MBEDTLS_ERR_PEM_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((buf = mbedtls_calloc(1, len)) == NULL) {
|
||||
return MBEDTLS_ERR_PEM_ALLOC_FAILED;
|
||||
}
|
||||
@ -426,20 +453,20 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_free(buf);
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
|
||||
* length bytes (allow 4 to be sure) in all known use cases.
|
||||
*
|
||||
* Use that as a heuristic to try to detect password mismatches.
|
||||
*/
|
||||
if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) {
|
||||
/* Check PKCS padding and update data length based on padding info.
|
||||
* This can be used to detect invalid padding data and password
|
||||
* mismatches. */
|
||||
size_t unpadded_len;
|
||||
ret = pem_check_pkcs_padding(buf, len, &unpadded_len);
|
||||
if (ret != 0) {
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
|
||||
return ret;
|
||||
}
|
||||
len = unpadded_len;
|
||||
#else
|
||||
mbedtls_zeroize_and_free(buf, len);
|
||||
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;
|
||||
|
524
library/pk.c
524
library/pk.c
@ -18,10 +18,8 @@
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#include "mbedtls/rsa.h"
|
||||
#if defined(MBEDTLS_PKCS1_V21) && !defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "rsa_internal.h"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
#include "mbedtls/ecp.h"
|
||||
#endif
|
||||
@ -37,6 +35,10 @@
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
|
||||
(PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
|
||||
PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
|
||||
|
||||
/*
|
||||
* Initialise a mbedtls_pk_context
|
||||
*/
|
||||
@ -579,6 +581,279 @@ int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) || defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
static psa_status_t export_import_into_psa(mbedtls_svc_key_id_t old_key_id,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *new_key_id)
|
||||
{
|
||||
unsigned char key_buffer[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
|
||||
size_t key_length = 0;
|
||||
psa_status_t status = psa_export_key(old_key_id,
|
||||
key_buffer, sizeof(key_buffer),
|
||||
&key_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
status = psa_import_key(attributes, key_buffer, key_length, new_key_id);
|
||||
mbedtls_platform_zeroize(key_buffer, key_length);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int copy_into_psa(mbedtls_svc_key_id_t old_key_id,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *new_key_id)
|
||||
{
|
||||
/* Normally, we prefer copying: it's more efficient and works even
|
||||
* for non-exportable keys. */
|
||||
psa_status_t status = psa_copy_key(old_key_id, attributes, new_key_id);
|
||||
if (status == PSA_ERROR_NOT_PERMITTED /*missing COPY usage*/ ||
|
||||
status == PSA_ERROR_INVALID_ARGUMENT /*incompatible policy*/) {
|
||||
/* There are edge cases where copying won't work, but export+import
|
||||
* might:
|
||||
* - If the old key does not allow PSA_KEY_USAGE_COPY.
|
||||
* - If the old key's usage does not allow what attributes wants.
|
||||
* Because the key was intended for use in the pk module, and may
|
||||
* have had a policy chosen solely for what pk needs rather than
|
||||
* based on a detailed understanding of PSA policies, we are a bit
|
||||
* more liberal than psa_copy_key() here.
|
||||
*/
|
||||
/* Here we need to check that the types match, otherwise we risk
|
||||
* importing nonsensical data. */
|
||||
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
status = psa_get_key_attributes(old_key_id, &old_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
|
||||
psa_reset_key_attributes(&old_attributes);
|
||||
if (old_type != psa_get_key_type(attributes)) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
status = export_import_into_psa(old_key_id, attributes, new_key_id);
|
||||
}
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
static int import_pair_into_psa(const mbedtls_pk_context *pk,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key_id)
|
||||
{
|
||||
switch (mbedtls_pk_get_type(pk)) {
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
case MBEDTLS_PK_RSA:
|
||||
{
|
||||
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
unsigned char key_buffer[
|
||||
PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)];
|
||||
unsigned char *const key_end = key_buffer + sizeof(key_buffer);
|
||||
unsigned char *key_data = key_end;
|
||||
int ret = mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk),
|
||||
key_buffer, &key_data);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
size_t key_length = key_end - key_data;
|
||||
ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
|
||||
key_data, key_length,
|
||||
key_id));
|
||||
mbedtls_platform_zeroize(key_data, key_length);
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
case MBEDTLS_PK_ECDSA:
|
||||
{
|
||||
/* We need to check the curve family, otherwise the import could
|
||||
* succeed with nonsensical data.
|
||||
* We don't check the bit-size: it's optional in attributes,
|
||||
* and if it's specified, psa_import_key() will know from the key
|
||||
* data length and will check that the bit-size matches. */
|
||||
psa_key_type_t to_type = psa_get_key_type(attributes);
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
psa_ecc_family_t from_family = pk->ec_family;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
|
||||
size_t from_bits = 0;
|
||||
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
|
||||
&from_bits);
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
if (to_type != PSA_KEY_TYPE_ECC_KEY_PAIR(from_family)) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
if (mbedtls_svc_key_id_is_null(pk->priv_id)) {
|
||||
/* We have a public key and want a key pair. */
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
return copy_into_psa(pk->priv_id, attributes, key_id);
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
if (ec->d.n == 0) {
|
||||
/* Private key not set. Assume the input is a public key only.
|
||||
* (The other possibility is that it's an incomplete object
|
||||
* where the group is set but neither the public key nor
|
||||
* the private key. This is not possible through ecp.h
|
||||
* functions, so we don't bother reporting a more suitable
|
||||
* error in that case.) */
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
size_t key_length = 0;
|
||||
int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
|
||||
key_buffer, sizeof(key_buffer));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
|
||||
key_buffer, key_length,
|
||||
key_id));
|
||||
mbedtls_platform_zeroize(key_buffer, key_length);
|
||||
return ret;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
case MBEDTLS_PK_OPAQUE:
|
||||
return copy_into_psa(pk->priv_id, attributes, key_id);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
default:
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
static int import_public_into_psa(const mbedtls_pk_context *pk,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key_id)
|
||||
{
|
||||
psa_key_type_t psa_type = psa_get_key_type(attributes);
|
||||
|
||||
#if defined(MBEDTLS_RSA_C) || \
|
||||
(defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)) || \
|
||||
defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
unsigned char key_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
|
||||
#endif
|
||||
unsigned char *key_data = NULL;
|
||||
size_t key_length = 0;
|
||||
|
||||
switch (mbedtls_pk_get_type(pk)) {
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
case MBEDTLS_PK_RSA:
|
||||
{
|
||||
if (psa_type != PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
unsigned char *const key_end = key_buffer + sizeof(key_buffer);
|
||||
key_data = key_end;
|
||||
int ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*pk),
|
||||
key_buffer, &key_data);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
key_length = (size_t) ret;
|
||||
break;
|
||||
}
|
||||
#endif /*MBEDTLS_RSA_C */
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
case MBEDTLS_PK_ECDSA:
|
||||
{
|
||||
/* We need to check the curve family, otherwise the import could
|
||||
* succeed with nonsensical data.
|
||||
* We don't check the bit-size: it's optional in attributes,
|
||||
* and if it's specified, psa_import_key() will know from the key
|
||||
* data length and will check that the bit-size matches. */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
key_data = (unsigned char *) pk->pub_raw;
|
||||
key_length = pk->pub_raw_len;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
|
||||
size_t from_bits = 0;
|
||||
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
|
||||
&from_bits);
|
||||
if (psa_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(from_family)) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
int ret = mbedtls_ecp_write_public_key(
|
||||
ec, MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&key_length, key_buffer, sizeof(key_buffer));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
key_data = key_buffer;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
break;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
case MBEDTLS_PK_OPAQUE:
|
||||
{
|
||||
psa_key_attributes_t old_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status =
|
||||
psa_get_key_attributes(pk->priv_id, &old_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
psa_key_type_t old_type = psa_get_key_type(&old_attributes);
|
||||
psa_reset_key_attributes(&old_attributes);
|
||||
if (psa_type != PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(old_type)) {
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
}
|
||||
status = psa_export_public_key(pk->priv_id,
|
||||
key_buffer, sizeof(key_buffer),
|
||||
&key_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
key_data = key_buffer;
|
||||
break;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
default:
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
return PSA_PK_TO_MBEDTLS_ERR(psa_import_key(attributes,
|
||||
key_data, key_length,
|
||||
key_id));
|
||||
}
|
||||
|
||||
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key_id)
|
||||
{
|
||||
/* Set the output immediately so that it won't contain garbage even
|
||||
* if we error out before calling psa_import_key(). */
|
||||
*key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
|
||||
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA_ALT) {
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
|
||||
|
||||
int want_public = PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(attributes));
|
||||
if (want_public) {
|
||||
return import_public_into_psa(pk, attributes, key_id);
|
||||
} else {
|
||||
return import_pair_into_psa(pk, attributes, key_id);
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/*
|
||||
@ -746,7 +1021,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg);
|
||||
p = buf + sizeof(buf);
|
||||
key_len = mbedtls_pk_write_pubkey(&p, buf, ctx);
|
||||
key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p);
|
||||
|
||||
if (key_len < 0) {
|
||||
return key_len;
|
||||
@ -911,9 +1186,32 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
|
||||
}
|
||||
|
||||
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t psa_alg, psa_enrollment_alg, sign_alg;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
|
||||
status = psa_get_key_attributes(ctx->priv_id, &key_attr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
psa_alg = psa_get_key_algorithm(&key_attr);
|
||||
psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
|
||||
/* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
|
||||
* alg and enrollment alg should be of type RSA_PSS. */
|
||||
if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
|
||||
sign_alg = psa_alg;
|
||||
} else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
|
||||
sign_alg = psa_enrollment_alg;
|
||||
} else {
|
||||
/* The opaque key has no RSA PSS algorithm associated. */
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Adjust the hashing algorithm. */
|
||||
sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
|
||||
|
||||
status = psa_sign_hash(ctx->priv_id, sign_alg,
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
|
||||
@ -1080,124 +1378,136 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
|
||||
return ctx->pk_info->type;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/*
|
||||
* Load the key to a PSA key slot,
|
||||
* then turn the PK context into a wrapper for that key slot.
|
||||
*
|
||||
* Currently only works for EC & RSA private keys.
|
||||
*/
|
||||
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
|
||||
mbedtls_svc_key_id_t *key,
|
||||
psa_algorithm_t alg,
|
||||
psa_key_usage_t usage,
|
||||
psa_algorithm_t alg2)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
static int copy_from_psa(mbedtls_svc_key_id_t key_id,
|
||||
mbedtls_pk_context *pk,
|
||||
int public_only)
|
||||
{
|
||||
#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C)
|
||||
((void) pk);
|
||||
((void) key);
|
||||
((void) alg);
|
||||
((void) usage);
|
||||
((void) alg2);
|
||||
#else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
|
||||
size_t d_len;
|
||||
psa_ecc_family_t curve_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
size_t bits;
|
||||
psa_status_t status;
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_algorithm_t alg_type;
|
||||
size_t key_bits;
|
||||
/* Use a buffer size large enough to contain either a key pair or public key. */
|
||||
unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
|
||||
size_t exp_key_len;
|
||||
int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
|
||||
/* export the private key material in the format PSA wants */
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH];
|
||||
status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
}
|
||||
if (pk == NULL) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
curve_id = pk->ec_family;
|
||||
bits = pk->ec_bits;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
status = psa_get_key_attributes(key_id, &key_attr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
d_len = PSA_BITS_TO_BYTES(ec->grp.nbits);
|
||||
if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (public_only) {
|
||||
status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
|
||||
} else {
|
||||
status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits);
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id);
|
||||
key_type = psa_get_key_type(&key_attr);
|
||||
if (public_only) {
|
||||
key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
|
||||
}
|
||||
key_bits = psa_get_key_bits(&key_attr);
|
||||
alg_type = psa_get_key_algorithm(&key_attr);
|
||||
|
||||
/* prepare the key attributes */
|
||||
psa_set_key_type(&attributes, key_type);
|
||||
psa_set_key_bits(&attributes, bits);
|
||||
psa_set_key_usage_flags(&attributes, usage);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
if (alg2 != PSA_ALG_NONE) {
|
||||
psa_set_key_enrollment_algorithm(&attributes, alg2);
|
||||
}
|
||||
|
||||
/* import private key into PSA */
|
||||
status = psa_import_key(&attributes, d, d_len, key);
|
||||
mbedtls_platform_zeroize(d, sizeof(d));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
/* make PK context wrap the key slot */
|
||||
mbedtls_pk_free(pk);
|
||||
mbedtls_pk_init(pk);
|
||||
|
||||
return mbedtls_pk_setup_opaque(pk, *key);
|
||||
} else
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) {
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
int key_len;
|
||||
psa_status_t status;
|
||||
if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
|
||||
(key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) {
|
||||
|
||||
/* export the private key material in the format PSA wants */
|
||||
key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf));
|
||||
if (key_len <= 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* prepare the key attributes */
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk));
|
||||
psa_set_key_usage_flags(&attributes, usage);
|
||||
psa_set_key_algorithm(&attributes, alg);
|
||||
if (alg2 != PSA_ALG_NONE) {
|
||||
psa_set_key_enrollment_algorithm(&attributes, alg2);
|
||||
if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
|
||||
} else {
|
||||
ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len);
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* import private key into PSA */
|
||||
status = psa_import_key(&attributes,
|
||||
buf + sizeof(buf) - key_len,
|
||||
key_len, key);
|
||||
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_TO_MBEDTLS_ERR(status);
|
||||
mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
|
||||
if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
|
||||
md_type = mbedtls_md_type_from_psa_alg(alg_type);
|
||||
}
|
||||
|
||||
/* make PK context wrap the key slot */
|
||||
mbedtls_pk_free(pk);
|
||||
mbedtls_pk_init(pk);
|
||||
|
||||
return mbedtls_pk_setup_opaque(pk, *key);
|
||||
if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) {
|
||||
ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type);
|
||||
} else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) ||
|
||||
alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) {
|
||||
ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type);
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ||
|
||||
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) {
|
||||
mbedtls_ecp_group_id grp_id;
|
||||
|
||||
ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits);
|
||||
ret = mbedtls_pk_ecc_set_group(pk, grp_id);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) {
|
||||
ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
} else {
|
||||
ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len);
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
{
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
mbedtls_platform_zeroize(exp_key, sizeof(exp_key));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
|
||||
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
|
||||
mbedtls_pk_context *pk)
|
||||
{
|
||||
return copy_from_psa(key_id, pk, 0);
|
||||
}
|
||||
|
||||
int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id,
|
||||
mbedtls_pk_context *pk)
|
||||
{
|
||||
return copy_from_psa(key_id, pk, 1);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
255
library/pk_ecc.c
Normal file
255
library/pk_ecc.c
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* ECC setters for PK.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "pk_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
|
||||
int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
size_t ec_bits;
|
||||
psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits);
|
||||
|
||||
/* group may already be initialized; if so, make sure IDs match */
|
||||
if ((pk->ec_family != 0 && pk->ec_family != ec_family) ||
|
||||
(pk->ec_bits != 0 && pk->ec_bits != ec_bits)) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
pk->ec_family = ec_family;
|
||||
pk->ec_bits = ec_bits;
|
||||
|
||||
return 0;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
|
||||
|
||||
/* grp may already be initialized; if so, make sure IDs match */
|
||||
if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
|
||||
mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
return mbedtls_ecp_group_load(&(ecp->grp), grp_id);
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_usage_t flags;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
|
||||
if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
/* Do not set algorithm here because Montgomery keys cannot do ECDSA and
|
||||
* the PK module cannot do ECDH. When the key will be used in TLS for
|
||||
* ECDH, it will be exported and then re-imported with proper flags
|
||||
* and algorithm. */
|
||||
flags = PSA_KEY_USAGE_EXPORT;
|
||||
} else {
|
||||
psa_set_key_algorithm(&attributes,
|
||||
MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH));
|
||||
flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE |
|
||||
PSA_KEY_USAGE_EXPORT;
|
||||
}
|
||||
psa_set_key_usage_flags(&attributes, flags);
|
||||
|
||||
status = psa_import_key(&attributes, key, key_len, &pk->priv_id);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
|
||||
int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
return 0;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
|
||||
const unsigned char *prv, size_t prv_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
|
||||
&pk->pub_raw_len);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
psa_status_t status;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
size_t curve_bits;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
|
||||
|
||||
/* Import private key into PSA, from serialized input */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
|
||||
status = psa_import_key(&key_attr, prv, prv_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
}
|
||||
|
||||
/* Export public key from PSA */
|
||||
unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t pub_len;
|
||||
status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len);
|
||||
psa_status_t destruction_status = psa_destroy_key(key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
} else if (destruction_status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(destruction_status);
|
||||
}
|
||||
|
||||
/* Load serialized public key into ecp_keypair structure */
|
||||
return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len);
|
||||
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
|
||||
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
/*
|
||||
* Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case.
|
||||
*
|
||||
* Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA
|
||||
* functions to handle keys. However, currently psa_import_key() does not
|
||||
* support compressed points. In case that support was explicitly requested,
|
||||
* this fallback uses ECP functions to get the job done. This is the reason
|
||||
* why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT.
|
||||
*
|
||||
* [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the public key as an ECPoint,
|
||||
* in any format supported by ECP.
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
|
||||
const unsigned char *pub,
|
||||
size_t pub_len)
|
||||
{
|
||||
#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
|
||||
(void) pk;
|
||||
(void) pub;
|
||||
(void) pub_len;
|
||||
return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
mbedtls_ecp_keypair ecp_key;
|
||||
mbedtls_ecp_group_id ecp_group_id;
|
||||
int ret;
|
||||
|
||||
ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
|
||||
|
||||
mbedtls_ecp_keypair_init(&ecp_key);
|
||||
ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
pub, pub_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&pk->pub_raw_len, pk->pub_raw,
|
||||
sizeof(pk->pub_raw));
|
||||
|
||||
exit:
|
||||
mbedtls_ecp_keypair_free(&ecp_key);
|
||||
return ret;
|
||||
#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
/* Load the key */
|
||||
if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) {
|
||||
/* Format directly supported by PSA:
|
||||
* - non-Weierstrass curves that only have one format;
|
||||
* - uncompressed format for Weierstrass curves. */
|
||||
if (pub_len > sizeof(pk->pub_raw)) {
|
||||
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(pk->pub_raw, pub, pub_len);
|
||||
pk->pub_raw_len = pub_len;
|
||||
} else {
|
||||
/* Other format, try the fallback */
|
||||
int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate the key by trying to import it */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
psa_set_key_usage_flags(&key_attrs, 0);
|
||||
psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
|
||||
psa_set_key_bits(&key_attrs, pk->ec_bits);
|
||||
|
||||
if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
|
||||
&key_id) != PSA_SUCCESS) ||
|
||||
(psa_destroy_key(key_id) != PSA_SUCCESS)) {
|
||||
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
int ret;
|
||||
mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
|
||||
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PK_C && MBEDTLS_PK_HAVE_ECC_KEYS */
|
@ -17,7 +17,7 @@
|
||||
#include "mbedtls/ecp.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
@ -28,7 +28,7 @@
|
||||
#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
|
||||
psa_to_pk_ecdsa_errors, \
|
||||
psa_pk_status_to_mbedtls)
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
/* Headers/footers for PEM files */
|
||||
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----"
|
||||
@ -127,6 +127,62 @@ static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk)
|
||||
|
||||
return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the group used by this key.
|
||||
*
|
||||
* [in/out] pk: in: must have been pk_setup() to an ECC type
|
||||
* out: will have group (curve) information set
|
||||
* [in] grp_in: a supported group ID (not NONE)
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id);
|
||||
|
||||
/*
|
||||
* Set the private key material
|
||||
*
|
||||
* [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the private key set.
|
||||
* [in] key, key_len: the raw private key (no ASN.1 wrapping).
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len);
|
||||
|
||||
/*
|
||||
* Set the public key.
|
||||
*
|
||||
* [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the raw public key (an ECPoint).
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len);
|
||||
|
||||
/*
|
||||
* Derive a public key from its private counterpart.
|
||||
* Computationally intensive, only use when public key is not available.
|
||||
*
|
||||
* [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key().
|
||||
* out: will have the public key set.
|
||||
* [in] prv, prv_len: the raw private key (see note below).
|
||||
* [in] f_rng, p_rng: RNG function and context.
|
||||
*
|
||||
* Note: the private key information is always available from pk,
|
||||
* however for convenience the serialized version is also passed,
|
||||
* as it's available at each calling site, and useful in some configs
|
||||
* (as otherwise we would have to re-serialize it from the pk context).
|
||||
*
|
||||
* There are three implementations of this function:
|
||||
* 1. MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 3. not MBEDTLS_USE_PSA_CRYPTO.
|
||||
*/
|
||||
int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
|
||||
const unsigned char *prv, size_t prv_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/* Helper for (deterministic) ECDSA */
|
||||
|
@ -74,8 +74,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
|
||||
unsigned char *p = buf + sizeof(buf);
|
||||
psa_algorithm_t psa_alg_md =
|
||||
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
psa_algorithm_t psa_alg_md;
|
||||
size_t rsa_len = mbedtls_rsa_get_len(rsa);
|
||||
|
||||
#if SIZE_MAX > UINT_MAX
|
||||
@ -84,6 +83,12 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_alg_md = PSA_ALG_RSA_PSS(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
} else {
|
||||
psa_alg_md = PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
|
||||
}
|
||||
|
||||
if (sig_len < rsa_len) {
|
||||
return MBEDTLS_ERR_RSA_VERIFY_FAILED;
|
||||
}
|
||||
@ -235,10 +240,14 @@ static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
|
||||
if (psa_md_alg == 0) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
psa_algorithm_t psa_alg;
|
||||
if (mbedtls_rsa_get_padding_mode(mbedtls_pk_rsa(*pk)) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
|
||||
} else {
|
||||
psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg);
|
||||
}
|
||||
|
||||
return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PKCS1V15_SIGN(
|
||||
psa_md_alg),
|
||||
pk->pk_ctx, hash, hash_len,
|
||||
return mbedtls_pk_psa_rsa_sign_ext(psa_alg, pk->pk_ctx, hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
@ -276,6 +285,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_algorithm_t psa_md_alg, decrypt_alg;
|
||||
psa_status_t status;
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
|
||||
@ -284,12 +294,6 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
#endif /* !MBEDTLS_RSA_ALT */
|
||||
|
||||
if (ilen != mbedtls_rsa_get_len(rsa)) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
@ -301,7 +305,13 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
|
||||
decrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
|
||||
} else {
|
||||
decrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
|
||||
}
|
||||
psa_set_key_algorithm(&attributes, decrypt_alg);
|
||||
|
||||
status = psa_import_key(&attributes,
|
||||
buf + sizeof(buf) - key_len, key_len,
|
||||
@ -311,7 +321,7 @@ static int rsa_decrypt_wrap(mbedtls_pk_context *pk,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
status = psa_asymmetric_decrypt(key_id, decrypt_alg,
|
||||
input, ilen,
|
||||
NULL, 0,
|
||||
output, osize, olen);
|
||||
@ -358,6 +368,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_algorithm_t psa_md_alg, psa_encrypt_alg;
|
||||
psa_status_t status;
|
||||
int key_len;
|
||||
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
|
||||
@ -366,12 +377,6 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
((void) f_rng);
|
||||
((void) p_rng);
|
||||
|
||||
#if !defined(MBEDTLS_RSA_ALT)
|
||||
if (rsa->padding != MBEDTLS_RSA_PKCS_V15) {
|
||||
return MBEDTLS_ERR_RSA_INVALID_PADDING;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbedtls_rsa_get_len(rsa) > osize) {
|
||||
return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
|
||||
}
|
||||
@ -382,7 +387,13 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
}
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
|
||||
if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) {
|
||||
psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa));
|
||||
psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg);
|
||||
} else {
|
||||
psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT;
|
||||
}
|
||||
psa_set_key_algorithm(&attributes, psa_encrypt_alg);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
|
||||
|
||||
status = psa_import_key(&attributes,
|
||||
@ -393,7 +404,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg,
|
||||
input, ilen,
|
||||
NULL, 0,
|
||||
output, osize, olen);
|
||||
|
@ -44,302 +44,6 @@
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* ECC setters
|
||||
*
|
||||
* 1. This is an abstraction layer around MBEDTLS_PK_USE_PSA_EC_DATA:
|
||||
* this macro will not appear outside this section.
|
||||
* 2. All inputs are raw: no metadata, no ASN.1 until the next section.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
* Set the group used by this key.
|
||||
*
|
||||
* [in/out] pk: in: must have been pk_setup() to an ECC type
|
||||
* out: will have group (curve) information set
|
||||
* [in] grp_in: a supported group ID (not NONE)
|
||||
*/
|
||||
static int pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
size_t ec_bits;
|
||||
psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits);
|
||||
|
||||
/* group may already be initialized; if so, make sure IDs match */
|
||||
if ((pk->ec_family != 0 && pk->ec_family != ec_family) ||
|
||||
(pk->ec_bits != 0 && pk->ec_bits != ec_bits)) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
pk->ec_family = ec_family;
|
||||
pk->ec_bits = ec_bits;
|
||||
|
||||
return 0;
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk);
|
||||
|
||||
/* grp may already be initialized; if so, make sure IDs match */
|
||||
if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE &&
|
||||
mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) {
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* set group */
|
||||
return mbedtls_ecp_group_load(&(ecp->grp), grp_id);
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the private key material
|
||||
*
|
||||
* [in/out] pk: in: must have the group set already, see pk_ecc_set_group().
|
||||
* out: will have the private key set.
|
||||
* [in] key, key_len: the raw private key (no ASN.1 wrapping).
|
||||
*/
|
||||
static int pk_ecc_set_key(mbedtls_pk_context *pk,
|
||||
unsigned char *key, size_t key_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_usage_t flags;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family));
|
||||
if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
/* Do not set algorithm here because Montgomery keys cannot do ECDSA and
|
||||
* the PK module cannot do ECDH. When the key will be used in TLS for
|
||||
* ECDH, it will be exported and then re-imported with proper flags
|
||||
* and algorithm. */
|
||||
flags = PSA_KEY_USAGE_EXPORT;
|
||||
} else {
|
||||
psa_set_key_algorithm(&attributes,
|
||||
MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH));
|
||||
flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE |
|
||||
PSA_KEY_USAGE_EXPORT;
|
||||
}
|
||||
psa_set_key_usage_flags(&attributes, flags);
|
||||
|
||||
status = psa_import_key(&attributes, key, key_len, &pk->priv_id);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
|
||||
int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
|
||||
}
|
||||
return 0;
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
/*
|
||||
* Derive a public key from its private counterpart.
|
||||
* Computationally intensive, only use when public key is not available.
|
||||
*
|
||||
* [in/out] pk: in: must have the private key set, see pk_ecc_set_key().
|
||||
* out: will have the public key set.
|
||||
* [in] prv, prv_len: the raw private key (see note below).
|
||||
* [in] f_rng, p_rng: RNG function and context.
|
||||
*
|
||||
* Note: the private key information is always available from pk,
|
||||
* however for convenience the serialized version is also passed,
|
||||
* as it's available at each calling site, and useful in some configs
|
||||
* (as otherwise we would have to re-serialize it from the pk context).
|
||||
*
|
||||
* There are three implementations of this function:
|
||||
* 1. MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA,
|
||||
* 3. not MBEDTLS_USE_PSA_CRYPTO.
|
||||
*/
|
||||
static int pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk,
|
||||
const unsigned char *prv, size_t prv_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw),
|
||||
&pk->pub_raw_len);
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
|
||||
#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
psa_status_t status;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
size_t curve_bits;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits);
|
||||
|
||||
/* Import private key into PSA, from serialized input */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT);
|
||||
status = psa_import_key(&key_attr, prv, prv_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
}
|
||||
|
||||
/* Export public key from PSA */
|
||||
unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
|
||||
size_t pub_len;
|
||||
status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len);
|
||||
psa_status_t destruction_status = psa_destroy_key(key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(status);
|
||||
} else if (destruction_status != PSA_SUCCESS) {
|
||||
return psa_pk_status_to_mbedtls(destruction_status);
|
||||
}
|
||||
|
||||
/* Load serialized public key into ecp_keypair structure */
|
||||
return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len);
|
||||
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
(void) prv;
|
||||
(void) prv_len;
|
||||
|
||||
mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng);
|
||||
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
/*
|
||||
* Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case.
|
||||
*
|
||||
* Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA
|
||||
* functions to handle keys. However, currently psa_import_key() does not
|
||||
* support compressed points. In case that support was explicitly requested,
|
||||
* this fallback uses ECP functions to get the job done. This is the reason
|
||||
* why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT.
|
||||
*
|
||||
* [in/out] pk: in: must have the group set, see pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the public key as an ECPoint,
|
||||
* in any format supported by ECP.
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk,
|
||||
const unsigned char *pub,
|
||||
size_t pub_len)
|
||||
{
|
||||
#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED)
|
||||
(void) pk;
|
||||
(void) pub;
|
||||
(void) pub_len;
|
||||
return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
mbedtls_ecp_keypair ecp_key;
|
||||
mbedtls_ecp_group_id ecp_group_id;
|
||||
int ret;
|
||||
|
||||
ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits);
|
||||
|
||||
mbedtls_ecp_keypair_init(&ecp_key);
|
||||
ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
pub, pub_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
&pk->pub_raw_len, pk->pub_raw,
|
||||
sizeof(pk->pub_raw));
|
||||
|
||||
exit:
|
||||
mbedtls_ecp_keypair_free(&ecp_key);
|
||||
return ret;
|
||||
#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
/*
|
||||
* Set the public key.
|
||||
*
|
||||
* [in/out] pk: in: must have its group set, see pk_ecc_set_group().
|
||||
* out: will have the public key set.
|
||||
* [in] pub, pub_len: the raw public key (an ECPoint).
|
||||
*
|
||||
* Return:
|
||||
* - 0 on success;
|
||||
* - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid
|
||||
* but not supported;
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
static int pk_ecc_set_pubkey(mbedtls_pk_context *pk,
|
||||
const unsigned char *pub, size_t pub_len)
|
||||
{
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
|
||||
/* Load the key */
|
||||
if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) {
|
||||
/* Format directly supported by PSA:
|
||||
* - non-Weierstrass curves that only have one format;
|
||||
* - uncompressed format for Weierstrass curves. */
|
||||
if (pub_len > sizeof(pk->pub_raw)) {
|
||||
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(pk->pub_raw, pub, pub_len);
|
||||
pk->pub_raw_len = pub_len;
|
||||
} else {
|
||||
/* Other format, try the fallback */
|
||||
int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate the key by trying to import it */
|
||||
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
psa_set_key_usage_flags(&key_attrs, 0);
|
||||
psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family));
|
||||
psa_set_key_bits(&key_attrs, pk->ec_bits);
|
||||
|
||||
if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len,
|
||||
&key_id) != PSA_SUCCESS) ||
|
||||
(psa_destroy_key(key_id) != PSA_SUCCESS)) {
|
||||
return MBEDTLS_ERR_PK_INVALID_PUBKEY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
int ret;
|
||||
mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx;
|
||||
ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q);
|
||||
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Low-level ECC parsing: optional support for SpecifiedECDomain
|
||||
@ -698,7 +402,7 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *p
|
||||
}
|
||||
}
|
||||
|
||||
return pk_ecc_set_group(pk, grp_id);
|
||||
return mbedtls_pk_ecc_set_group(pk, grp_id);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
|
||||
@ -714,7 +418,7 @@ static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params,
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
return pk_ecc_set_group(pk, grp_id);
|
||||
return mbedtls_pk_ecc_set_group(pk, grp_id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -740,7 +444,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
|
||||
/*
|
||||
* Load the private key
|
||||
*/
|
||||
ret = pk_ecc_set_key(pk, key, len);
|
||||
ret = mbedtls_pk_ecc_set_key(pk, key, len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -748,7 +452,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
|
||||
/* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys,
|
||||
* which never contain a public key. As such, derive the public key
|
||||
* unconditionally. */
|
||||
if ((ret = pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) {
|
||||
if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -874,7 +578,7 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
|
||||
ret = pk_use_ecparams(&alg_params, pk);
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
|
||||
ret = mbedtls_pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
|
||||
*p += end - *p;
|
||||
}
|
||||
} else
|
||||
@ -966,7 +670,7 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
|
||||
/*
|
||||
* Load the private key
|
||||
*/
|
||||
ret = pk_ecc_set_key(pk, d, d_len);
|
||||
ret = mbedtls_pk_ecc_set_key(pk, d, d_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -990,11 +694,11 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
|
||||
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
|
||||
}
|
||||
|
||||
if ((ret = pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
|
||||
if ((ret = mbedtls_pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
|
||||
pubkey_done = 1;
|
||||
} else {
|
||||
/*
|
||||
* The only acceptable failure mode of pk_ecc_set_pubkey() above
|
||||
* The only acceptable failure mode of mbedtls_pk_ecc_set_pubkey() above
|
||||
* is if the point format is not recognized.
|
||||
*/
|
||||
if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) {
|
||||
@ -1007,7 +711,7 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
|
||||
}
|
||||
|
||||
if (!pubkey_done) {
|
||||
if ((ret = pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) {
|
||||
if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ static int pk_write_ec_private(unsigned char **p, unsigned char *start,
|
||||
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
|
||||
byte_length = (ec->grp.pbits + 7) / 8;
|
||||
|
||||
ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
|
||||
ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp));
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,10 +33,10 @@ static psa_status_t psa_aead_setup(
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_cipher_id_t cipher_id;
|
||||
mbedtls_cipher_mode_t mode;
|
||||
size_t key_bits = attributes->core.bits;
|
||||
size_t key_bits = attributes->bits;
|
||||
(void) key_buffer_size;
|
||||
|
||||
status = mbedtls_cipher_values_from_psa(alg, attributes->core.type,
|
||||
status = mbedtls_cipher_values_from_psa(alg, attributes->type,
|
||||
&key_bits, &mode, &cipher_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
@ -49,7 +49,7 @@ static psa_status_t psa_aead_setup(
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
|
||||
* The call to mbedtls_ccm_encrypt_and_tag or
|
||||
* mbedtls_ccm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ static psa_status_t psa_aead_setup(
|
||||
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
|
||||
* The call to mbedtls_gcm_crypt_and_tag or
|
||||
* mbedtls_gcm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
@ -289,14 +289,14 @@ static psa_status_t psa_cipher_setup(
|
||||
int ret = 0;
|
||||
size_t key_bits;
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
psa_key_type_t key_type = attributes->core.type;
|
||||
psa_key_type_t key_type = attributes->type;
|
||||
|
||||
(void) key_buffer_size;
|
||||
|
||||
mbedtls_cipher_init(&operation->ctx.cipher);
|
||||
|
||||
operation->alg = alg;
|
||||
key_bits = attributes->core.bits;
|
||||
key_bits = attributes->bits;
|
||||
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
|
||||
key_bits, NULL);
|
||||
if (cipher_info == NULL) {
|
||||
|
@ -16,57 +16,7 @@
|
||||
|
||||
void psa_reset_key_attributes(psa_key_attributes_t *attributes)
|
||||
{
|
||||
mbedtls_free(attributes->domain_parameters);
|
||||
memset(attributes, 0, sizeof(*attributes));
|
||||
}
|
||||
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
uint8_t *copy = NULL;
|
||||
|
||||
if (data_length != 0) {
|
||||
copy = mbedtls_calloc(1, data_length);
|
||||
if (copy == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memcpy(copy, data, data_length);
|
||||
}
|
||||
/* After this point, this function is guaranteed to succeed, so it
|
||||
* can start modifying `*attributes`. */
|
||||
|
||||
if (attributes->domain_parameters != NULL) {
|
||||
mbedtls_free(attributes->domain_parameters);
|
||||
attributes->domain_parameters = NULL;
|
||||
attributes->domain_parameters_size = 0;
|
||||
}
|
||||
|
||||
attributes->domain_parameters = copy;
|
||||
attributes->domain_parameters_size = data_length;
|
||||
attributes->core.type = type;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
if (attributes->domain_parameters == NULL &&
|
||||
attributes->domain_parameters_size == SIZE_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (attributes->domain_parameters_size > data_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*data_length = attributes->domain_parameters_size;
|
||||
if (attributes->domain_parameters_size != 0) {
|
||||
memcpy(data, attributes->domain_parameters,
|
||||
attributes->domain_parameters_size);
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
@ -59,7 +59,7 @@ typedef enum {
|
||||
* and metadata for one key.
|
||||
*/
|
||||
typedef struct {
|
||||
psa_core_key_attributes_t attr;
|
||||
psa_key_attributes_t attr;
|
||||
|
||||
/*
|
||||
* The current state of the key slot, as described in
|
||||
@ -89,7 +89,9 @@ typedef struct {
|
||||
* A function must call psa_register_read(slot) before reading the current
|
||||
* contents of the slot for an operation.
|
||||
* They then must call psa_unregister_read(slot) once they have finished
|
||||
* reading the current contents of the slot.
|
||||
* reading the current contents of the slot. If the key slot mutex is not
|
||||
* held (when mutexes are enabled), this call must be done via a call to
|
||||
* psa_unregister_read_under_mutex(slot).
|
||||
* A function must call psa_key_slot_has_readers(slot) to check if
|
||||
* the slot is in use for reading.
|
||||
*
|
||||
@ -157,11 +159,6 @@ typedef struct {
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
/* A mask of key attribute flags used only internally.
|
||||
* Currently there aren't any. */
|
||||
#define PSA_KA_MASK_INTERNAL_ONLY ( \
|
||||
0)
|
||||
|
||||
/** Test whether a key slot has any registered readers.
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
@ -175,56 +172,6 @@ static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
|
||||
return slot->registered_readers > 0;
|
||||
}
|
||||
|
||||
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in] slot The key slot to query.
|
||||
* \param mask The mask of bits to extract.
|
||||
*
|
||||
* \return The key attribute flags in the given slot,
|
||||
* bitwise-anded with \p mask.
|
||||
*/
|
||||
static inline uint16_t psa_key_slot_get_flags(const psa_key_slot_t *slot,
|
||||
uint16_t mask)
|
||||
{
|
||||
return slot->attr.flags & mask;
|
||||
}
|
||||
|
||||
/** Set flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to modify.
|
||||
* \param value The new value of the selected bits.
|
||||
*/
|
||||
static inline void psa_key_slot_set_flags(psa_key_slot_t *slot,
|
||||
uint16_t mask,
|
||||
uint16_t value)
|
||||
{
|
||||
slot->attr.flags = ((~mask & slot->attr.flags) |
|
||||
(mask & value));
|
||||
}
|
||||
|
||||
/** Turn on flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to set.
|
||||
*/
|
||||
static inline void psa_key_slot_set_bits_in_flags(psa_key_slot_t *slot,
|
||||
uint16_t mask)
|
||||
{
|
||||
slot->attr.flags |= mask;
|
||||
}
|
||||
|
||||
/** Turn off flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to clear.
|
||||
*/
|
||||
static inline void psa_key_slot_clear_bits(psa_key_slot_t *slot,
|
||||
uint16_t mask)
|
||||
{
|
||||
slot->attr.flags &= ~mask;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** Get the SE slot number of a key from the key slot storing its description.
|
||||
*
|
||||
@ -396,6 +343,18 @@ psa_status_t psa_export_public_key_internal(
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
/** Whether a key production parameters structure is the default.
|
||||
*
|
||||
* Calls to a key generation driver with non-default production parameters
|
||||
* require a driver supporting custom production parameters.
|
||||
*
|
||||
* \param[in] params The key production parameters to check.
|
||||
* \param params_data_length Size of `params->data` in bytes.
|
||||
*/
|
||||
int psa_key_production_parameters_are_default(
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate a key.
|
||||
*
|
||||
@ -403,6 +362,9 @@ psa_status_t psa_export_public_key_internal(
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to generate.
|
||||
* \param[in] params The production parameters from
|
||||
* psa_generate_key_ext().
|
||||
* \param params_data_length The size of `params->data` in bytes.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
@ -417,6 +379,8 @@ psa_status_t psa_export_public_key_internal(
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
|
@ -216,8 +216,8 @@ psa_status_t mbedtls_psa_ecp_import_key(
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->core.type,
|
||||
attributes->core.bits,
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
data,
|
||||
data_length,
|
||||
&ecp);
|
||||
@ -225,7 +225,7 @@ psa_status_t mbedtls_psa_ecp_import_key(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) ==
|
||||
if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
|
||||
PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
*bits = ecp->grp.nbits + 1;
|
||||
} else {
|
||||
@ -235,7 +235,7 @@ psa_status_t mbedtls_psa_ecp_import_key(
|
||||
/* Re-export the data to PSA export format. There is currently no support
|
||||
* for other input formats then the export format, so this is a 1-1
|
||||
* copy operation. */
|
||||
status = mbedtls_psa_ecp_export_key(attributes->core.type,
|
||||
status = mbedtls_psa_ecp_export_key(attributes->type,
|
||||
ecp,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
@ -281,20 +281,8 @@ psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
|
||||
|
||||
return status;
|
||||
} else {
|
||||
if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key(ecp,
|
||||
data,
|
||||
PSA_BITS_TO_BYTES(ecp->grp.nbits)));
|
||||
if (status == PSA_SUCCESS) {
|
||||
*data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
|
||||
} else {
|
||||
memset(data, 0, data_size);
|
||||
}
|
||||
|
||||
mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@ -308,7 +296,7 @@ psa_status_t mbedtls_psa_ecp_export_public_key(
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->core.type, attributes->core.bits,
|
||||
attributes->type, attributes->bits,
|
||||
key_buffer, key_buffer_size, &ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
@ -316,7 +304,7 @@ psa_status_t mbedtls_psa_ecp_export_public_key(
|
||||
|
||||
status = mbedtls_psa_ecp_export_key(
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)),
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
|
||||
ecp, data, data_size, data_length);
|
||||
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
@ -337,18 +325,14 @@ psa_status_t mbedtls_psa_ecp_generate_key(
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
|
||||
attributes->core.type);
|
||||
attributes->type);
|
||||
mbedtls_ecp_group_id grp_id =
|
||||
mbedtls_ecc_group_from_psa(curve, attributes->core.bits);
|
||||
mbedtls_ecc_group_from_psa(curve, attributes->bits);
|
||||
|
||||
const mbedtls_ecp_curve_info *curve_info =
|
||||
mbedtls_ecp_curve_info_from_grp_id(grp_id);
|
||||
mbedtls_ecp_keypair ecp;
|
||||
|
||||
if (attributes->domain_parameters_size != 0) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
@ -363,14 +347,11 @@ psa_status_t mbedtls_psa_ecp_generate_key(
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size));
|
||||
mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
|
||||
key_buffer, key_buffer_size));
|
||||
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*key_buffer_length = key_buffer_size;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
|
||||
@ -393,8 +374,8 @@ psa_status_t mbedtls_psa_ecdsa_sign_hash(
|
||||
size_t curve_bytes;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->core.type,
|
||||
attributes->core.bits,
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
@ -480,8 +461,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash(
|
||||
|
||||
(void) alg;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->core.type,
|
||||
attributes->core.bits,
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
@ -545,14 +526,14 @@ psa_status_t mbedtls_psa_key_agreement_ecdh(
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->core.type) ||
|
||||
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
|
||||
!PSA_ALG_IS_ECDH(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->core.type,
|
||||
attributes->core.bits,
|
||||
attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
|
@ -151,7 +151,7 @@ psa_status_t mbedtls_psa_ffdh_export_public_key(
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi GX, G, X, P;
|
||||
psa_key_type_t type = attributes->core.type;
|
||||
psa_key_type_t type = attributes->type;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
if (key_buffer_size > data_size) {
|
||||
@ -167,7 +167,7 @@ psa_status_t mbedtls_psa_ffdh_export_public_key(
|
||||
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
||||
|
||||
size_t key_len = PSA_BITS_TO_BYTES(attributes->core.bits);
|
||||
size_t key_len = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G);
|
||||
|
||||
@ -283,7 +283,7 @@ psa_status_t mbedtls_psa_ffdh_key_agreement(
|
||||
mbedtls_mpi_init(&K);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||
PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
|
||||
PSA_BITS_TO_BYTES(attributes->bits), &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
|
@ -1,14 +1,6 @@
|
||||
/** \file psa_crypto_random_impl.h
|
||||
*
|
||||
* \brief PSA crypto random generator implementation abstraction.
|
||||
*
|
||||
* The definitions here need to be consistent with the declarations
|
||||
* in include/psa_util_internal.h. This file contains some redundant
|
||||
* declarations to increase the chance that a compiler will detect
|
||||
* inconsistencies if one file is changed without updating the other,
|
||||
* but not all potential inconsistencies can be enforced, so make sure
|
||||
* to check the public declarations and contracts in
|
||||
* include/psa_util_internal.h if you modify this file.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
@ -22,22 +14,12 @@
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
|
||||
#include <string.h>
|
||||
#include <mbedtls/entropy.h> // only for error codes
|
||||
#include <psa/crypto.h>
|
||||
|
||||
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
|
||||
|
||||
/* Trivial wrapper around psa_generate_random(). */
|
||||
int mbedtls_psa_get_random(void *p_rng,
|
||||
unsigned char *output,
|
||||
size_t output_size);
|
||||
|
||||
/* The PSA RNG API doesn't need any externally maintained state. */
|
||||
#define MBEDTLS_PSA_RANDOM_STATE NULL
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
/* Choose a DRBG based on configuration and availability */
|
||||
#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
|
||||
|
||||
@ -67,11 +49,37 @@ int mbedtls_psa_get_random(void *p_rng,
|
||||
#error "No hash algorithm available for HMAC_DBRG."
|
||||
#endif
|
||||
|
||||
#else
|
||||
#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#error "No DRBG module available for the psa_crypto module."
|
||||
|
||||
#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
|
||||
|
||||
/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
|
||||
#endif
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
|
||||
|
||||
typedef struct {
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx);
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx);
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_psa_drbg_context_t drbg;
|
||||
} mbedtls_psa_random_context_t;
|
||||
|
||||
/** Initialize the PSA DRBG.
|
||||
*
|
||||
@ -99,63 +107,6 @@ static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** The type of the PSA random generator context.
|
||||
*
|
||||
* The random generator context is composed of an entropy context and
|
||||
* a DRBG context.
|
||||
*/
|
||||
typedef struct {
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx);
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx);
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_psa_drbg_context_t drbg;
|
||||
} mbedtls_psa_random_context_t;
|
||||
|
||||
/* Defined in include/psa_util_internal.h so that it's visible to
|
||||
* application code. The declaration here is redundant, but included
|
||||
* as a safety net to make it more likely that a future change that
|
||||
* accidentally causes the implementation to diverge from the interface
|
||||
* will be noticed. */
|
||||
/* Do not include the declaration under MSVC because it doesn't accept it
|
||||
* ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
|
||||
* Observed with Visual Studio 2013. A known bug apparently:
|
||||
* https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
|
||||
*/
|
||||
#if !defined(_MSC_VER)
|
||||
static mbedtls_f_rng_t *const mbedtls_psa_get_random;
|
||||
#endif
|
||||
|
||||
/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
|
||||
* return.
|
||||
*/
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
|
||||
#endif
|
||||
|
||||
/** A pointer to the PSA DRBG state.
|
||||
*
|
||||
* This variable is only intended to be used through the macro
|
||||
* #MBEDTLS_PSA_RANDOM_STATE.
|
||||
*/
|
||||
/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
|
||||
* global PSA crypto state. */
|
||||
/* The type `mbedtls_psa_drbg_context_t` is defined in
|
||||
* include/psa_util_internal.h so that `mbedtls_psa_random_state` can be
|
||||
* declared there and be visible to application code. */
|
||||
extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
|
||||
|
||||
/** A pointer to the PSA DRBG state.
|
||||
*
|
||||
* This macro expands to an expression that is suitable as the \c p_rng
|
||||
* parameter to pass to mbedtls_psa_get_random().
|
||||
*
|
||||
* This macro exists in all configurations where the psa_crypto module is
|
||||
* enabled. Its expansion depends on the configuration.
|
||||
*/
|
||||
#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
|
||||
|
||||
/** Seed the PSA DRBG.
|
||||
*
|
||||
* \param entropy An entropy context to read the seed from.
|
||||
@ -167,23 +118,15 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
|
||||
* \return \c 0 on success.
|
||||
* \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
|
||||
*/
|
||||
static inline int mbedtls_psa_drbg_seed(
|
||||
mbedtls_entropy_context *entropy,
|
||||
const unsigned char *custom, size_t len)
|
||||
static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
|
||||
mbedtls_entropy_context *entropy,
|
||||
const unsigned char *custom, size_t len)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
|
||||
mbedtls_entropy_func,
|
||||
entropy,
|
||||
custom, len);
|
||||
return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
const mbedtls_md_info_t *md_info =
|
||||
mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
|
||||
return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
|
||||
md_info,
|
||||
mbedtls_entropy_func,
|
||||
entropy,
|
||||
custom, len);
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
|
||||
return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ psa_status_t mbedtls_psa_rsa_import_key(
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
data,
|
||||
data_length,
|
||||
&rsa);
|
||||
@ -130,7 +130,7 @@ psa_status_t mbedtls_psa_rsa_import_key(
|
||||
* representation in the key slot. Export representation in case of RSA is
|
||||
* the smallest representation that's allowed as input, so a straight-up
|
||||
* allocation of the same size as the input buffer will be large enough. */
|
||||
status = mbedtls_psa_rsa_export_key(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
rsa,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
@ -196,7 +196,7 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(
|
||||
attributes->core.type, key_buffer, key_buffer_size, &rsa);
|
||||
attributes->type, key_buffer, key_buffer_size, &rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@ -216,26 +216,21 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
static psa_status_t psa_rsa_read_exponent(const uint8_t *domain_parameters,
|
||||
size_t domain_parameters_size,
|
||||
static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes,
|
||||
size_t e_length,
|
||||
int *exponent)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t acc = 0;
|
||||
|
||||
if (domain_parameters_size == 0) {
|
||||
*exponent = 65537;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/* Mbed TLS encodes the public exponent as an int. For simplicity, only
|
||||
* support values that fit in a 32-bit integer, which is larger than
|
||||
* int on just about every platform anyway. */
|
||||
if (domain_parameters_size > sizeof(acc)) {
|
||||
if (e_length > sizeof(acc)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
for (i = 0; i < domain_parameters_size; i++) {
|
||||
acc = (acc << 8) | domain_parameters[i];
|
||||
for (i = 0; i < e_length; i++) {
|
||||
acc = (acc << 8) | e_bytes[i];
|
||||
}
|
||||
if (acc > INT_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
@ -246,31 +241,33 @@ static psa_status_t psa_rsa_read_exponent(const uint8_t *domain_parameters,
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_rsa_context rsa;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int exponent;
|
||||
int exponent = 65537;
|
||||
|
||||
status = psa_rsa_read_exponent(attributes->domain_parameters,
|
||||
attributes->domain_parameters_size,
|
||||
&exponent);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
if (params_data_length != 0) {
|
||||
status = psa_rsa_read_exponent(params->data, params_data_length,
|
||||
&exponent);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_rsa_init(&rsa);
|
||||
ret = mbedtls_rsa_gen_key(&rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
(unsigned int) attributes->core.bits,
|
||||
(unsigned int) attributes->bits,
|
||||
exponent);
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
status = mbedtls_psa_rsa_export_key(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
&rsa, key_buffer, key_buffer_size,
|
||||
key_buffer_length);
|
||||
mbedtls_rsa_free(&rsa);
|
||||
@ -328,7 +325,7 @@ psa_status_t mbedtls_psa_rsa_sign_hash(
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
@ -427,7 +424,7 @@ psa_status_t mbedtls_psa_rsa_verify_hash(
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
@ -539,11 +536,11 @@ psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attribut
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
|
||||
if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
@ -635,11 +632,11 @@ psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attribut
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->core.type,
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
|
@ -109,6 +109,15 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the RSA key to generate.
|
||||
* \param[in] params Production parameters for the key
|
||||
* generation. This function only uses
|
||||
* `params->data`,
|
||||
* which contains the public exponent.
|
||||
* This can be a null pointer if
|
||||
* \c params_data_length is 0.
|
||||
* \param params_data_length Length of `params->data` in bytes.
|
||||
* This can be 0, in which case the
|
||||
* public exponent will be 65537.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
@ -123,6 +132,7 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
*/
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
|
||||
/** Sign an already-calculated hash with an RSA private key.
|
||||
|
@ -70,6 +70,9 @@ int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok)
|
||||
* On success, the function locks the key slot. It is the responsibility of
|
||||
* the caller to unlock the key slot when it does not access it anymore.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param key Key identifier to query.
|
||||
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
|
||||
* key slot containing the description of the key
|
||||
@ -94,16 +97,14 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory(
|
||||
if (psa_key_id_is_volatile(key_id)) {
|
||||
slot = &global_data.key_slots[key_id - PSA_KEY_ID_VOLATILE_MIN];
|
||||
|
||||
/*
|
||||
* Check if both the PSA key identifier key_id and the owner
|
||||
* identifier of key match those of the key slot.
|
||||
*
|
||||
* Note that, if the key slot is not occupied, its PSA key identifier
|
||||
* is equal to zero. This is an invalid value for a PSA key identifier
|
||||
* and thus cannot be equal to the valid PSA key identifier key_id.
|
||||
*/
|
||||
status = mbedtls_svc_key_id_equal(key, slot->attr.id) ?
|
||||
PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
|
||||
/* Check if both the PSA key identifier key_id and the owner
|
||||
* identifier of key match those of the key slot. */
|
||||
if ((slot->state == PSA_SLOT_FULL) &&
|
||||
(mbedtls_svc_key_id_equal(key, slot->attr.id))) {
|
||||
status = PSA_SUCCESS;
|
||||
} else {
|
||||
status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
} else {
|
||||
if (!psa_is_valid_key_id(key, 1)) {
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
@ -248,11 +249,6 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot)
|
||||
data = (psa_se_key_data_storage_t *) key_data;
|
||||
status = psa_copy_key_material_into_slot(
|
||||
slot, data->slot_number, sizeof(data->slot_number));
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
|
||||
PSA_SLOT_FULL);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
@ -262,9 +258,6 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
|
||||
PSA_SLOT_FULL);
|
||||
|
||||
exit:
|
||||
psa_free_persistent_key_data(key_data, key_data_length);
|
||||
return status;
|
||||
@ -336,10 +329,7 @@ static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot)
|
||||
|
||||
/* Copy actual key length and core attributes into the slot on success */
|
||||
slot->key.bytes = key_buffer_length;
|
||||
slot->attr = attributes.core;
|
||||
|
||||
status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING,
|
||||
PSA_SLOT_FULL);
|
||||
slot->attr = attributes;
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_remove_key_data_from_memory(slot);
|
||||
@ -358,12 +348,27 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||
* would be returned if the lock fails. */
|
||||
status = PSA_SUCCESS;
|
||||
/* If the key is persistent and not loaded, we cannot unlock the mutex
|
||||
* between checking if the key is loaded and setting the slot as FULL,
|
||||
* as otherwise another thread may load and then destroy the key
|
||||
* in the meantime. */
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
/*
|
||||
* On success, the pointer to the slot is passed directly to the caller
|
||||
* thus no need to unlock the key slot here.
|
||||
*/
|
||||
status = psa_get_and_lock_key_slot_in_memory(key, p_slot);
|
||||
if (status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -374,6 +379,10 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
|
||||
status = psa_reserve_free_key_slot(&volatile_key_id, p_slot);
|
||||
if (status != PSA_SUCCESS) {
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -407,10 +416,15 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
status = psa_register_read(*p_slot);
|
||||
}
|
||||
|
||||
return status;
|
||||
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
status = PSA_ERROR_INVALID_HANDLE;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_unregister_read(psa_key_slot_t *slot)
|
||||
@ -447,6 +461,24 @@ psa_status_t psa_unregister_read(psa_key_slot_t *slot)
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* We need to set status as success, otherwise CORRUPTION_DETECTED
|
||||
* would be returned if the lock fails. */
|
||||
status = PSA_SUCCESS;
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
status = psa_unregister_read(slot);
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
|
||||
&mbedtls_threading_key_slot_mutex));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
|
||||
psa_se_drv_table_entry_t **p_drv)
|
||||
{
|
||||
@ -510,7 +542,7 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle)
|
||||
|
||||
*handle = key;
|
||||
|
||||
return psa_unregister_read(slot);
|
||||
return psa_unregister_read_under_mutex(slot);
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
(void) key;
|
||||
|
@ -107,6 +107,9 @@ void psa_wipe_all_key_slots(void);
|
||||
* It is the responsibility of the caller to change the slot's state to
|
||||
* PSA_SLOT_EMPTY/FULL once key creation has finished.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[out] volatile_key_id On success, volatile key identifier
|
||||
* associated to the returned slot.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
@ -202,6 +205,27 @@ static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
|
||||
*/
|
||||
psa_status_t psa_unregister_read(psa_key_slot_t *slot);
|
||||
|
||||
/** Wrap a call to psa_unregister_read in the global key slot mutex.
|
||||
*
|
||||
* If threading is disabled, this simply calls psa_unregister_read.
|
||||
*
|
||||
* \note To ease the handling of errors in retrieving a key slot
|
||||
* a NULL input pointer is valid, and the function returns
|
||||
* successfully without doing anything in that case.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p slot is NULL or the key slot reader counter has been
|
||||
* decremented (and potentially wiped) successfully.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was neither PSA_SLOT_FULL nor
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or a wipe was attempted and the slot's state was not
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or registered_readers was equal to 0.
|
||||
*/
|
||||
psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot);
|
||||
|
||||
/** Test whether a lifetime designates a key in an external cryptoprocessor.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
|
@ -235,7 +235,7 @@ typedef struct {
|
||||
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data)
|
||||
{
|
||||
psa_persistent_key_storage_format *storage_format =
|
||||
@ -267,7 +267,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_core_key_attributes_t *attr)
|
||||
psa_key_attributes_t *attr)
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
@ -314,7 +314,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length)
|
||||
{
|
||||
@ -352,7 +352,7 @@ void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
|
||||
mbedtls_zeroize_and_free(key_data, key_data_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key);
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length);
|
||||
|
||||
@ -123,7 +123,7 @@ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length);
|
||||
|
||||
@ -163,7 +163,7 @@ void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length);
|
||||
*/
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data);
|
||||
|
||||
/**
|
||||
@ -186,7 +186,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_core_key_attributes_t *attr);
|
||||
psa_key_attributes_t *attr);
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** This symbol is defined if transaction support is required. */
|
||||
@ -231,8 +231,9 @@ typedef uint16_t psa_crypto_transaction_type_t;
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
* and reading it back on the same device.
|
||||
*
|
||||
* \note The transaction mechanism is designed for a single active transaction
|
||||
* at a time. The transaction object is #psa_crypto_transaction.
|
||||
* \note The transaction mechanism is not thread-safe. There can only be one
|
||||
* single active transaction at a time.
|
||||
* The transaction object is #psa_crypto_transaction.
|
||||
*
|
||||
* \note If an API call starts a transaction, it must complete this transaction
|
||||
* before returning to the application.
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include <mbedtls/cipher.h>
|
||||
#endif
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
/* PSA_SUCCESS is kept at the top of each error table since
|
||||
* it's the most common status when everything functions properly. */
|
||||
@ -164,6 +165,8 @@ int psa_pk_status_to_mbedtls(psa_status_t status)
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return MBEDTLS_ERR_PK_INVALID_ALG;
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
case PSA_ERROR_BAD_STATE:
|
||||
@ -336,7 +339,31 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
|
||||
}
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
/* Wrapper function allowing the classic API to use the PSA RNG.
|
||||
*
|
||||
* `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
|
||||
* `psa_generate_random(...)`. The state parameter is ignored since the
|
||||
* PSA API doesn't support passing an explicit state.
|
||||
*/
|
||||
int mbedtls_psa_get_random(void *p_rng,
|
||||
unsigned char *output,
|
||||
size_t output_size)
|
||||
{
|
||||
/* This function takes a pointer to the RNG state because that's what
|
||||
* classic mbedtls functions using an RNG expect. The PSA RNG manages
|
||||
* its own state internally and doesn't let the caller access that state.
|
||||
* So we just ignore the state parameter, and in practice we'll pass
|
||||
* NULL. */
|
||||
(void) p_rng;
|
||||
psa_status_t status = psa_generate_random(output, output_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return 0;
|
||||
} else {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
/*************************************************************************
|
||||
* FFDH
|
||||
@ -96,5 +96,5 @@ int psa_pk_status_to_mbedtls(psa_status_t status);
|
||||
sizeof(error_list)/sizeof(error_list[0]), \
|
||||
fallback_f)
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
#endif /* MBEDTLS_PSA_UTIL_INTERNAL_H */
|
||||
|
@ -108,8 +108,9 @@ int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, si
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
|
||||
end = p + len;
|
||||
if (end != p + len) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
|
||||
return ret;
|
||||
@ -241,8 +242,9 @@ int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
|
||||
end = p + len;
|
||||
if (end != p + len) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Import N */
|
||||
if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
|
||||
@ -2229,7 +2231,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
|
||||
if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
if (ctx->hash_id == MBEDTLS_MD_NONE) {
|
||||
if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) {
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen,
|
||||
|
117
library/sha3.c
117
library/sha3.c
@ -14,6 +14,33 @@
|
||||
|
||||
#if defined(MBEDTLS_SHA3_C)
|
||||
|
||||
/*
|
||||
* These macros select manually unrolled implementations of parts of the main permutation function.
|
||||
*
|
||||
* Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
|
||||
* from manually unrolling at higher optimisation levels.
|
||||
*
|
||||
* Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
|
||||
* these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
|
||||
* x86-64.
|
||||
*/
|
||||
#if !defined(MBEDTLS_SHA3_THETA_UNROLL)
|
||||
#define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
|
||||
#endif
|
||||
#if !defined(MBEDTLS_SHA3_CHI_UNROLL)
|
||||
#if defined(__OPTIMIZE_SIZE__)
|
||||
#define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
|
||||
#else
|
||||
#define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_SHA3_PI_UNROLL)
|
||||
#define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
|
||||
#endif
|
||||
#if !defined(MBEDTLS_SHA3_RHO_UNROLL)
|
||||
#define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
|
||||
#endif
|
||||
|
||||
#include "mbedtls/sha3.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
@ -56,18 +83,15 @@ static const uint8_t iota_r_packed[24] = {
|
||||
};
|
||||
#undef H
|
||||
|
||||
static const uint8_t rho[24] = {
|
||||
1, 62, 28, 27, 36, 44, 6, 55, 20,
|
||||
3, 10, 43, 25, 39, 41, 45, 15,
|
||||
21, 8, 18, 2, 61, 56, 14
|
||||
static const uint32_t rho[6] = {
|
||||
0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
|
||||
};
|
||||
|
||||
static const uint8_t pi[24] = {
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
|
||||
static const uint32_t pi[6] = {
|
||||
0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
|
||||
};
|
||||
|
||||
#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y))))
|
||||
#define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
|
||||
#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
|
||||
} while (0)
|
||||
#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
|
||||
@ -84,39 +108,97 @@ static void keccak_f1600(mbedtls_sha3_context *ctx)
|
||||
uint64_t t;
|
||||
|
||||
/* Theta */
|
||||
#if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
|
||||
for (i = 0; i < 5; i++) {
|
||||
lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
|
||||
}
|
||||
for (i = 0; i < 5; i++) {
|
||||
t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
|
||||
s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
|
||||
}
|
||||
#else
|
||||
lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
|
||||
lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
|
||||
lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
|
||||
lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
|
||||
lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
|
||||
|
||||
t = lane[4] ^ ROT64(lane[1], 1);
|
||||
t = lane[4] ^ ROTR64(lane[1], 63);
|
||||
s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
|
||||
|
||||
t = lane[0] ^ ROT64(lane[2], 1);
|
||||
t = lane[0] ^ ROTR64(lane[2], 63);
|
||||
s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
|
||||
|
||||
t = lane[1] ^ ROT64(lane[3], 1);
|
||||
t = lane[1] ^ ROTR64(lane[3], 63);
|
||||
s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
|
||||
|
||||
t = lane[2] ^ ROT64(lane[4], 1);
|
||||
t = lane[2] ^ ROTR64(lane[4], 63);
|
||||
s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
|
||||
|
||||
t = lane[3] ^ ROT64(lane[0], 1);
|
||||
t = lane[3] ^ ROTR64(lane[0], 63);
|
||||
s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
|
||||
#endif
|
||||
|
||||
/* Rho */
|
||||
for (i = 1; i < 25; i++) {
|
||||
s[i] = ROT64(s[i], rho[i-1]);
|
||||
for (i = 1; i < 25; i += 4) {
|
||||
uint32_t r = rho[(i - 1) >> 2];
|
||||
#if MBEDTLS_SHA3_RHO_UNROLL == 0
|
||||
for (int j = i; j < i + 4; j++) {
|
||||
uint8_t r8 = (uint8_t) (r >> 24);
|
||||
r <<= 8;
|
||||
s[j] = ROTR64(s[j], r8);
|
||||
}
|
||||
#else
|
||||
s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
|
||||
s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
|
||||
s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
|
||||
s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Pi */
|
||||
t = s[1];
|
||||
for (i = 0; i < 24; i++) {
|
||||
SWAP(s[pi[i]], t);
|
||||
#if MBEDTLS_SHA3_PI_UNROLL == 0
|
||||
for (i = 0; i < 24; i += 4) {
|
||||
uint32_t p = pi[i >> 2];
|
||||
for (unsigned j = 0; j < 4; j++) {
|
||||
SWAP(s[p & 0xff], t);
|
||||
p >>= 8;
|
||||
}
|
||||
}
|
||||
#else
|
||||
uint32_t p = pi[0];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
p = pi[1];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
p = pi[2];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
p = pi[3];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
p = pi[4];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
p = pi[5];
|
||||
SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
|
||||
SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
|
||||
#endif
|
||||
|
||||
/* Chi */
|
||||
#if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
|
||||
for (i = 0; i <= 20; i += 5) {
|
||||
lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
|
||||
lane[3] = s[i + 3]; lane[4] = s[i + 4];
|
||||
s[i + 0] ^= (~lane[1]) & lane[2];
|
||||
s[i + 1] ^= (~lane[2]) & lane[3];
|
||||
s[i + 2] ^= (~lane[3]) & lane[4];
|
||||
s[i + 3] ^= (~lane[4]) & lane[0];
|
||||
s[i + 4] ^= (~lane[0]) & lane[1];
|
||||
}
|
||||
#else
|
||||
lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
|
||||
s[0] ^= (~lane[1]) & lane[2];
|
||||
s[1] ^= (~lane[2]) & lane[3];
|
||||
@ -151,6 +233,7 @@ static void keccak_f1600(mbedtls_sha3_context *ctx)
|
||||
s[22] ^= (~lane[3]) & lane[4];
|
||||
s[23] ^= (~lane[4]) & lane[0];
|
||||
s[24] ^= (~lane[0]) & lane[1];
|
||||
#endif
|
||||
|
||||
/* Iota */
|
||||
/* Decompress the round masks (see definition of rc) */
|
||||
|
@ -765,11 +765,6 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_HAVE_TIME */
|
||||
|
||||
if (ssl->conf->f_rng == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
|
||||
return MBEDTLS_ERR_SSL_NO_RNG;
|
||||
}
|
||||
|
||||
/* Bet on the highest configured version if we are not in a TLS 1.2
|
||||
* renegotiation or session resumption.
|
||||
*/
|
||||
|
@ -21,6 +21,11 @@
|
||||
|
||||
const char *mbedtls_ssl_states_str(mbedtls_ssl_states in);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in);
|
||||
const char *mbedtls_ssl_early_data_state_str(mbedtls_ssl_early_data_state in);
|
||||
#endif
|
||||
|
||||
const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in);
|
||||
|
||||
const char *mbedtls_tls_prf_types_str(mbedtls_tls_prf_types in);
|
||||
|
@ -665,21 +665,21 @@ struct mbedtls_ssl_handshake_params {
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
/** Minimum TLS version to be negotiated.
|
||||
*
|
||||
* It is set up in the ClientHello writing preparation stage and used
|
||||
* throughout the ClientHello writing. Not relevant anymore as soon as
|
||||
* the protocol version has been negotiated thus as soon as the
|
||||
* ServerHello is received.
|
||||
* For a fresh handshake not linked to any previous handshake, it is
|
||||
* equal to the configured minimum minor version to be negotiated. When
|
||||
* renegotiating or resuming a session, it is equal to the previously
|
||||
* negotiated minor version.
|
||||
* It is set up in the ClientHello writing preparation stage and used
|
||||
* throughout the ClientHello writing. Not relevant anymore as soon as
|
||||
* the protocol version has been negotiated thus as soon as the
|
||||
* ServerHello is received.
|
||||
* For a fresh handshake not linked to any previous handshake, it is
|
||||
* equal to the configured minimum minor version to be negotiated. When
|
||||
* renegotiating or resuming a session, it is equal to the previously
|
||||
* negotiated minor version.
|
||||
*
|
||||
* There is no maximum TLS version field in this handshake context.
|
||||
* From the start of the handshake, we need to define a current protocol
|
||||
* version for the record layer which we define as the maximum TLS
|
||||
* version to be negotiated. The `tls_version` field of the SSL context is
|
||||
* used to store this maximum value until it contains the actual
|
||||
* negotiated value.
|
||||
* There is no maximum TLS version field in this handshake context.
|
||||
* From the start of the handshake, we need to define a current protocol
|
||||
* version for the record layer which we define as the maximum TLS
|
||||
* version to be negotiated. The `tls_version` field of the SSL context is
|
||||
* used to store this maximum value until it contains the actual
|
||||
* negotiated value.
|
||||
*/
|
||||
mbedtls_ssl_protocol_version min_tls_version;
|
||||
#endif
|
||||
@ -730,16 +730,21 @@ struct mbedtls_ssl_handshake_params {
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
uint8_t key_exchange_mode; /*!< Selected key exchange mode */
|
||||
|
||||
/** Number of HelloRetryRequest messages received/sent from/to the server. */
|
||||
uint8_t hello_retry_request_count;
|
||||
/**
|
||||
* Flag indicating if, in the course of the current handshake, an
|
||||
* HelloRetryRequest message has been sent by the server or received by
|
||||
* the client (<> 0) or not (0).
|
||||
*/
|
||||
uint8_t hello_retry_request_flag;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
/**
|
||||
* Number of dummy change_cipher_spec (CCS) record sent. Used to send only
|
||||
* one CCS per handshake without having to complicate the handshake state
|
||||
* transitions.
|
||||
* Flag indicating if, in the course of the current handshake, a dummy
|
||||
* change_cipher_spec (CCS) record has already been sent. Used to send only
|
||||
* one CCS per handshake while not complicating the handshake state
|
||||
* transitions for that purpose.
|
||||
*/
|
||||
uint8_t ccs_count;
|
||||
uint8_t ccs_sent;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
@ -2146,20 +2151,30 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *end,
|
||||
size_t *out_len);
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
|
||||
size_t early_data_len);
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* The client has not sent the first ClientHello yet, it is unknown if the
|
||||
* client will send an early data indication extension or not.
|
||||
* The client has not sent the first ClientHello yet, the negotiation of early
|
||||
* data has not started yet.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_IDLE,
|
||||
|
||||
/*
|
||||
* In its ClientHello, the client has not included an early data indication
|
||||
* extension.
|
||||
*/
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT,
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
* ClientHello, it has not received the response (ServerHello or
|
||||
* HelloRetryRequest) from the server yet. The transform to protect early data
|
||||
* is not set and early data cannot be sent yet.
|
||||
* is not set either as for middlebox compatibility a dummy CCS may have to be
|
||||
* sent in clear. Early data cannot be sent to the server yet.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT,
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
@ -2167,16 +2182,28 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
* HelloRetryRequest) from the server yet. The transform to protect early data
|
||||
* has been set and early data can be written now.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE,
|
||||
|
||||
/*
|
||||
* The client has indicated the use of early data and the server has accepted
|
||||
* it.
|
||||
*/
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED,
|
||||
|
||||
/*
|
||||
* The client has indicated the use of early data but the server has rejected
|
||||
* it.
|
||||
*/
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED,
|
||||
|
||||
/*
|
||||
* The client has sent an early data indication extension in its first
|
||||
* ClientHello, the server has accepted them and the client has received the
|
||||
* server Finished message. It cannot send early data to the server anymore.
|
||||
*/
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED,
|
||||
|
||||
} mbedtls_ssl_early_data_state;
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
@ -4005,7 +4005,11 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("EarlyData: deprotect and discard app data records."));
|
||||
/* TODO: Add max_early_data_size check here, see issue 6347 */
|
||||
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
|
||||
@ -4129,9 +4133,15 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
|
||||
*/
|
||||
if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
|
||||
if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
|
||||
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("EarlyData: Ignore application message before 2nd ClientHello"));
|
||||
/* TODO: Add max_early_data_size check here, see issue 6347 */
|
||||
|
||||
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
|
||||
} else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
|
||||
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
|
||||
@ -6058,6 +6068,111 @@ int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const struct mbedtls_ssl_config *conf;
|
||||
uint32_t remaining;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
|
||||
|
||||
if (ssl == NULL || (conf = ssl->conf) == NULL) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
|
||||
(conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
|
||||
(conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
|
||||
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
|
||||
}
|
||||
|
||||
if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are at the beginning of the handshake, the early data state being
|
||||
* equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just
|
||||
* enough to be able to send early data if possible. That way, we can
|
||||
* guarantee that when starting the handshake with this function we will
|
||||
* send at least one record of early data. Note that when the state is
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data
|
||||
* as the early data outbound transform has not been set as we may have to
|
||||
* first send a dummy CCS in clear.
|
||||
*/
|
||||
if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
|
||||
(ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
|
||||
while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
|
||||
(ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
|
||||
ret = mbedtls_ssl_handshake_step(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_flush_output(ssl);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
remaining = ssl->session_negotiate->max_early_data_size;
|
||||
} else {
|
||||
/*
|
||||
* If we are past the point where we can send early data or we have
|
||||
* already reached the maximum early data size, return immediatly.
|
||||
* Otherwise, progress the handshake as much as possible to not delay
|
||||
* it too much. If we reach a point where we can still send early data,
|
||||
* then we will send some.
|
||||
*/
|
||||
if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
|
||||
(ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
|
||||
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
|
||||
}
|
||||
|
||||
remaining = ssl->session_negotiate->max_early_data_size -
|
||||
ssl->total_early_data_size;
|
||||
|
||||
if (remaining == 0) {
|
||||
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_handshake(ssl);
|
||||
if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
|
||||
(ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
|
||||
|| (remaining == 0)) {
|
||||
return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
|
||||
}
|
||||
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
ret = ssl_write_real(ssl, buf, len);
|
||||
if (ret >= 0) {
|
||||
ssl->total_early_data_size += ret;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
/*
|
||||
* Notify the peer that the connection is being closed
|
||||
*/
|
||||
|
@ -75,6 +75,10 @@ static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx,
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
key->generation_time = mbedtls_time(NULL);
|
||||
#endif
|
||||
/* The lifetime of a key is the configured lifetime of the tickets when
|
||||
* the key is created.
|
||||
*/
|
||||
key->lifetime = ctx->ticket_lifetime;
|
||||
|
||||
if ((ret = ctx->f_rng(ctx->p_rng, key->name, sizeof(key->name))) != 0) {
|
||||
return ret;
|
||||
@ -116,16 +120,17 @@ static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx)
|
||||
#if !defined(MBEDTLS_HAVE_TIME)
|
||||
((void) ctx);
|
||||
#else
|
||||
if (ctx->ticket_lifetime != 0) {
|
||||
mbedtls_ssl_ticket_key * const key = ctx->keys + ctx->active;
|
||||
if (key->lifetime != 0) {
|
||||
mbedtls_time_t current_time = mbedtls_time(NULL);
|
||||
mbedtls_time_t key_time = ctx->keys[ctx->active].generation_time;
|
||||
mbedtls_time_t key_time = key->generation_time;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
#endif
|
||||
|
||||
if (current_time >= key_time &&
|
||||
(uint64_t) (current_time - key_time) < ctx->ticket_lifetime) {
|
||||
(uint64_t) (current_time - key_time) < key->lifetime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -198,6 +203,8 @@ int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx,
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
key->generation_time = mbedtls_time(NULL);
|
||||
#endif
|
||||
key->lifetime = lifetime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -331,7 +338,7 @@ int mbedtls_ssl_ticket_write(void *p_ticket,
|
||||
|
||||
key = &ctx->keys[ctx->active];
|
||||
|
||||
*ticket_lifetime = ctx->ticket_lifetime;
|
||||
*ticket_lifetime = key->lifetime;
|
||||
|
||||
memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES);
|
||||
|
||||
@ -495,43 +502,22 @@ int mbedtls_ssl_ticket_parse(void *p_ticket,
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
/* Check for expiration */
|
||||
mbedtls_ms_time_t ticket_age = -1;
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
ticket_age = mbedtls_ms_time() - session->ticket_creation_time;
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
ticket_age = mbedtls_ms_time() - session->ticket_reception_time;
|
||||
}
|
||||
#endif
|
||||
mbedtls_ms_time_t ticket_creation_time, ticket_age;
|
||||
mbedtls_ms_time_t ticket_lifetime =
|
||||
(mbedtls_ms_time_t) ctx->ticket_lifetime * 1000;
|
||||
|
||||
mbedtls_ms_time_t ticket_lifetime =
|
||||
(mbedtls_ms_time_t) ctx->ticket_lifetime * 1000;
|
||||
|
||||
if (ticket_age < 0 || ticket_age > ticket_lifetime) {
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
goto cleanup;
|
||||
}
|
||||
ret = mbedtls_ssl_session_get_ticket_creation_time(session,
|
||||
&ticket_creation_time);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
|
||||
/* Check for expiration */
|
||||
mbedtls_time_t current_time = mbedtls_time(NULL);
|
||||
|
||||
if (current_time < session->start ||
|
||||
(uint32_t) (current_time - session->start) > ctx->ticket_lifetime) {
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
goto cleanup;
|
||||
}
|
||||
ticket_age = mbedtls_ms_time() - ticket_creation_time;
|
||||
if (ticket_age < 0 || ticket_age > ticket_lifetime) {
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
goto cleanup;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
|
1401
library/ssl_tls.c
1401
library/ssl_tls.c
File diff suppressed because it is too large
Load Diff
@ -1268,6 +1268,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
|
||||
ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
|
||||
ssl->conf->transport);
|
||||
ssl->session_negotiate->tls_version = ssl->tls_version;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
|
||||
if (ssl->tls_version < ssl->conf->min_tls_version ||
|
||||
ssl->tls_version > ssl->conf->max_tls_version) {
|
||||
|
@ -1161,6 +1161,7 @@ read_record_header:
|
||||
ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
|
||||
ssl->conf->transport);
|
||||
ssl->session_negotiate->tls_version = ssl->tls_version;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
|
||||
if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2"));
|
||||
@ -2177,11 +2178,6 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
|
||||
|
||||
if (ssl->conf->f_rng == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
|
||||
return MBEDTLS_ERR_SSL_NO_RNG;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 . 0 handshake type
|
||||
* 1 . 3 handshake length
|
||||
@ -2702,8 +2698,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
|
||||
PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
|
||||
psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
|
||||
|
||||
key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
|
||||
ret = mbedtls_ecp_write_key(key, buf, key_len);
|
||||
ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
|
||||
if (ret != 0) {
|
||||
mbedtls_platform_zeroize(buf, sizeof(buf));
|
||||
break;
|
||||
@ -4281,6 +4276,9 @@ static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl)
|
||||
* 10 . 9+n ticket content
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time();
|
||||
#endif
|
||||
if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
|
||||
ssl->session_negotiate,
|
||||
ssl->out_msg + 10,
|
||||
|
@ -1180,7 +1180,15 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->handshake->hello_retry_request_count == 0) {
|
||||
/* In the first ClientHello, write the early data indication extension if
|
||||
* necessary and update the early data state.
|
||||
* If an HRR has been received and thus we are currently writing the
|
||||
* second ClientHello, the second ClientHello must not contain an early
|
||||
* data extension and the early data state must stay as it is:
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or
|
||||
* MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED.
|
||||
*/
|
||||
if (!ssl->handshake->hello_retry_request_flag) {
|
||||
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
|
||||
ssl_tls13_early_data_has_valid_ticket(ssl) &&
|
||||
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
|
||||
@ -1191,9 +1199,9 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
|
||||
}
|
||||
p += ext_len;
|
||||
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT;
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT;
|
||||
} else {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
@ -1231,7 +1239,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
|
||||
size_t psk_len;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) {
|
||||
if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ("Set hs psk for early data when writing the first psk"));
|
||||
|
||||
@ -1294,7 +1302,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
|
||||
1, ("Switch to early data keys for outbound traffic"));
|
||||
mbedtls_ssl_set_outbound_transform(
|
||||
ssl, ssl->handshake->transform_earlydata);
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
@ -1478,10 +1486,8 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
||||
return SSL_SERVER_HELLO_TLS1_2;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
ssl->session_negotiate->tls_version = ssl->tls_version;
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
|
||||
handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
|
||||
|
||||
@ -1497,7 +1503,7 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
||||
* to a HelloRetryRequest), it MUST abort the handshake with an
|
||||
* "unexpected_message" alert.
|
||||
*/
|
||||
if (handshake->hello_retry_request_count > 0) {
|
||||
if (handshake->hello_retry_request_flag) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
@ -1519,7 +1525,7 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
handshake->hello_retry_request_count++;
|
||||
handshake->hello_retry_request_flag = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1674,7 +1680,7 @@ static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
|
||||
* proposed in the HRR, we abort the handshake and send an
|
||||
* "illegal_parameter" alert.
|
||||
*/
|
||||
else if ((!is_hrr) && (handshake->hello_retry_request_count > 0) &&
|
||||
else if ((!is_hrr) && handshake->hello_retry_request_flag &&
|
||||
(cipher_suite != ssl->session_negotiate->ciphersuite)) {
|
||||
fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
|
||||
}
|
||||
@ -1913,7 +1919,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
|
||||
* cases we compute it here.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT ||
|
||||
if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT ||
|
||||
handshake->key_exchange_mode ==
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
|
||||
#endif
|
||||
@ -1969,8 +1975,8 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
|
||||
ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2232,9 +2238,10 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
|
||||
} else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED;
|
||||
} else if (ssl->early_data_state !=
|
||||
MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2272,6 +2279,7 @@ cleanup:
|
||||
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
|
||||
*
|
||||
@ -2310,6 +2318,32 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) ||
|
||||
(!mbedtls_ssl_is_handshake_over(ssl))) {
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
switch (ssl->early_data_state) {
|
||||
case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT:
|
||||
return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED;
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED:
|
||||
return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED:
|
||||
return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
/*
|
||||
* STATE HANDLING: CertificateRequest
|
||||
@ -2571,8 +2605,8 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED;
|
||||
if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) {
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED;
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
|
||||
} else
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
@ -3032,9 +3066,11 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
||||
ret = ssl_tls13_process_server_finished(ssl);
|
||||
break;
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
case MBEDTLS_SSL_END_OF_EARLY_DATA:
|
||||
ret = ssl_tls13_write_end_of_early_data(ssl);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
|
||||
ret = ssl_tls13_write_client_certificate(ssl);
|
||||
@ -3063,23 +3099,17 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
|
||||
break;
|
||||
@ -3094,7 +3124,7 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
|
||||
1, ("Switch to early data keys for outbound traffic"));
|
||||
mbedtls_ssl_set_outbound_transform(
|
||||
ssl, ssl->handshake->transform_earlydata);
|
||||
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
|
||||
ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
@ -1379,6 +1379,12 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
|
||||
|
||||
/* Only one CCS to send. */
|
||||
if (ssl->handshake->ccs_sent) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Write CCS message */
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_change_cipher_spec_body(
|
||||
ssl, ssl->out_msg,
|
||||
@ -1390,7 +1396,7 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
|
||||
/* Dispatch message */
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0));
|
||||
|
||||
ssl->handshake->ccs_count++;
|
||||
ssl->handshake->ccs_sent = 1;
|
||||
|
||||
cleanup:
|
||||
|
||||
@ -1448,6 +1454,54 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
|
||||
size_t early_data_len)
|
||||
{
|
||||
/*
|
||||
* This function should be called only while an handshake is in progress
|
||||
* and thus a session under negotiation. Add a sanity check to detect a
|
||||
* misuse.
|
||||
*/
|
||||
if (ssl->session_negotiate == NULL) {
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/* RFC 8446 section 4.6.1
|
||||
*
|
||||
* A server receiving more than max_early_data_size bytes of 0-RTT data
|
||||
* SHOULD terminate the connection with an "unexpected_message" alert.
|
||||
* Note that if it is still possible to send early_data_len bytes of early
|
||||
* data, it means that early_data_len is smaller than max_early_data_size
|
||||
* (type uint32_t) and can fit in an uint32_t. We use this further
|
||||
* down.
|
||||
*/
|
||||
if (early_data_len >
|
||||
(ssl->session_negotiate->max_early_data_size -
|
||||
ssl->total_early_data_size)) {
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
|
||||
ssl->total_early_data_size, early_data_len,
|
||||
ssl->session_negotiate->max_early_data_size));
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
* early_data_len has been checked to be less than max_early_data_size
|
||||
* that is uint32_t. Its cast to an uint32_t below is thus safe. We need
|
||||
* the cast to appease some compilers.
|
||||
*/
|
||||
ssl->total_early_data_size += (uint32_t) early_data_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/* Reset SSL context and update hash for handling HRR.
|
||||
|
@ -39,6 +39,63 @@ static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite(
|
||||
return ciphersuite_info;
|
||||
}
|
||||
|
||||
static void ssl_tls13_select_ciphersuite(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *cipher_suites,
|
||||
const unsigned char *cipher_suites_end,
|
||||
int psk_ciphersuite_id,
|
||||
psa_algorithm_t psk_hash_alg,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
|
||||
{
|
||||
*selected_ciphersuite_info = NULL;
|
||||
|
||||
/*
|
||||
* In a compliant ClientHello the byte-length of the list of ciphersuites
|
||||
* is even and this function relies on this fact. This should have been
|
||||
* checked in the main ClientHello parsing function. Double check here.
|
||||
*/
|
||||
if ((cipher_suites_end - cipher_suites) & 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const unsigned char *p = cipher_suites;
|
||||
p < cipher_suites_end; p += 2) {
|
||||
/*
|
||||
* "cipher_suites_end - p is even" is an invariant of the loop. As
|
||||
* cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and it
|
||||
* is thus safe to read two bytes.
|
||||
*/
|
||||
uint16_t id = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
|
||||
const mbedtls_ssl_ciphersuite_t *info =
|
||||
ssl_tls13_validate_peer_ciphersuite(ssl, id);
|
||||
if (info == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a valid PSK ciphersuite identifier has been passed in, we want
|
||||
* an exact match.
|
||||
*/
|
||||
if (psk_ciphersuite_id != 0) {
|
||||
if (id != psk_ciphersuite_id) {
|
||||
continue;
|
||||
}
|
||||
} else if (psk_hash_alg != PSA_ALG_NONE) {
|
||||
if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac) !=
|
||||
psk_hash_alg) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*selected_ciphersuite_info = info;
|
||||
return;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x",
|
||||
(unsigned) psk_ciphersuite_id, psk_hash_alg));
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
/* From RFC 8446:
|
||||
*
|
||||
@ -90,8 +147,30 @@ static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1
|
||||
#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
|
||||
/*
|
||||
* Non-error return values of
|
||||
* ssl_tls13_offered_psks_check_identity_match_ticket() and
|
||||
* ssl_tls13_offered_psks_check_identity_match(). They are positive to
|
||||
* not collide with error codes that are negative. Zero
|
||||
* (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated
|
||||
* up by the callers of this function as a generic success condition.
|
||||
*
|
||||
* The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means
|
||||
* that the pre-shared-key identity matches that of a ticket or an externally-
|
||||
* provisioned pre-shared-key. We have thus been able to retrieve the
|
||||
* attributes of the pre-shared-key but at least one of them does not meet
|
||||
* some criteria and the pre-shared-key cannot be used. For example, a ticket
|
||||
* is expired or its version is not TLS 1.3. Note eventually that the return
|
||||
* value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have
|
||||
* anything to do with binder check. A binder check is done only when a
|
||||
* suitable pre-shared-key has been selected and only for that selected
|
||||
* pre-shared-key: if the binder check fails, we fail the handshake and we do
|
||||
* not try to find another pre-shared-key for which the binder check would
|
||||
* succeed as recommended by the specification.
|
||||
*/
|
||||
#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2
|
||||
#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1
|
||||
#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
@ -109,7 +188,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *ticket_buffer;
|
||||
unsigned int key_exchanges;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_ms_time_t now;
|
||||
mbedtls_ms_time_t server_age;
|
||||
@ -123,7 +201,7 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
|
||||
/* Ticket parser is not configured, Skip */
|
||||
if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) {
|
||||
return 0;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
|
||||
}
|
||||
|
||||
/* We create a copy of the encrypted ticket since the ticket parsing
|
||||
@ -133,63 +211,51 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
*/
|
||||
ticket_buffer = mbedtls_calloc(1, identity_len);
|
||||
if (ticket_buffer == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
|
||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||
}
|
||||
memcpy(ticket_buffer, identity, identity_len);
|
||||
|
||||
if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
|
||||
session,
|
||||
ticket_buffer, identity_len)) != 0) {
|
||||
if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
|
||||
} else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) {
|
||||
ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
|
||||
session,
|
||||
ticket_buffer, identity_len);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired"));
|
||||
} else {
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_INVALID_MAC:
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
|
||||
break;
|
||||
|
||||
default:
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret);
|
||||
}
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
|
||||
}
|
||||
|
||||
/* We delete the temporary buffer */
|
||||
mbedtls_free(ticket_buffer);
|
||||
|
||||
if (ret == 0 && session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
|
||||
/* TODO: Define new return value for this case. */
|
||||
ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* RFC 8446 section 4.2.9
|
||||
*
|
||||
* Servers SHOULD NOT send NewSessionTicket with tickets that are not
|
||||
* compatible with the advertised modes; however, if a server does so,
|
||||
* the impact will just be that the client's attempts at resumption fail.
|
||||
*
|
||||
* We regard the ticket with incompatible key exchange modes as not match.
|
||||
/*
|
||||
* The identity matches that of a ticket. Now check that it has suitable
|
||||
* attributes and bet it will not be the case.
|
||||
*/
|
||||
ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
|
||||
MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
|
||||
|
||||
key_exchanges = 0;
|
||||
if (mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral(session) &&
|
||||
ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
|
||||
key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
}
|
||||
if (mbedtls_ssl_tls13_session_ticket_allow_psk(session) &&
|
||||
ssl_tls13_key_exchange_is_psk_available(ssl)) {
|
||||
key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
}
|
||||
|
||||
if (key_exchanges == 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
|
||||
if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
now = mbedtls_ms_time();
|
||||
|
||||
@ -242,13 +308,15 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
age_diff));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
/*
|
||||
* All good, we have found a suitable ticket.
|
||||
*/
|
||||
ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
|
||||
|
||||
exit:
|
||||
if (ret != 0) {
|
||||
if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
|
||||
mbedtls_ssl_session_free(session);
|
||||
}
|
||||
|
||||
@ -273,13 +341,11 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "identity", identity, identity_len);
|
||||
ssl->handshake->resume = 0;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if (ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
ssl, identity, identity_len, obfuscated_ticket_age,
|
||||
session) == SSL_TLS1_3_OFFERED_PSK_MATCH) {
|
||||
ssl->handshake->resume = 1;
|
||||
ret = ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
ssl, identity, identity_len, obfuscated_ticket_age, session);
|
||||
if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) {
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
|
||||
ret = mbedtls_ssl_set_hs_psk(ssl,
|
||||
session->resumption_key,
|
||||
@ -294,7 +360,9 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
session->resumption_key_len);
|
||||
MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u",
|
||||
(unsigned) obfuscated_ticket_age));
|
||||
return SSL_TLS1_3_OFFERED_PSK_MATCH;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_MATCH;
|
||||
} else if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE) {
|
||||
return SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
@ -302,9 +370,9 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
if (ssl->conf->f_psk != NULL) {
|
||||
if (ssl->conf->f_psk(
|
||||
ssl->conf->p_psk, ssl, identity, identity_len) == 0) {
|
||||
return SSL_TLS1_3_OFFERED_PSK_MATCH;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_MATCH;
|
||||
}
|
||||
return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(5, "identity", identity, identity_len);
|
||||
@ -318,12 +386,20 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
|
||||
return ret;
|
||||
}
|
||||
return SSL_TLS1_3_OFFERED_PSK_MATCH;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_MATCH;
|
||||
}
|
||||
|
||||
return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
|
||||
return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-error return values of ssl_tls13_offered_psks_check_binder_match().
|
||||
* They are positive to not collide with error codes that are negative. Zero
|
||||
* (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up
|
||||
* by the callers of this function as a generic success condition.
|
||||
*/
|
||||
#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1
|
||||
#define SSL_TLS1_3_BINDER_MATCH 0
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_binder_match(
|
||||
mbedtls_ssl_context *ssl,
|
||||
@ -368,99 +444,15 @@ static int ssl_tls13_offered_psks_check_binder_match(
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( received ): ", binder, binder_len);
|
||||
|
||||
if (mbedtls_ct_memcmp(server_computed_binder, binder, binder_len) == 0) {
|
||||
return SSL_TLS1_3_OFFERED_PSK_MATCH;
|
||||
return SSL_TLS1_3_BINDER_MATCH;
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(server_computed_binder,
|
||||
sizeof(server_computed_binder));
|
||||
return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_ciphersuite_for_psk(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *cipher_suites,
|
||||
const unsigned char *cipher_suites_end,
|
||||
uint16_t *selected_ciphersuite,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
|
||||
{
|
||||
psa_algorithm_t psk_hash_alg = PSA_ALG_SHA_256;
|
||||
|
||||
*selected_ciphersuite = 0;
|
||||
*selected_ciphersuite_info = NULL;
|
||||
|
||||
/* RFC 8446, page 55.
|
||||
*
|
||||
* For externally established PSKs, the Hash algorithm MUST be set when the
|
||||
* PSK is established or default to SHA-256 if no such algorithm is defined.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Search for a matching ciphersuite
|
||||
*/
|
||||
for (const unsigned char *p = cipher_suites;
|
||||
p < cipher_suites_end; p += 2) {
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
|
||||
cipher_suite);
|
||||
if (ciphersuite_info == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* MAC of selected ciphersuite MUST be same with PSK binder if exist.
|
||||
* Otherwise, client should reject.
|
||||
*/
|
||||
if (psk_hash_alg ==
|
||||
mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)) {
|
||||
*selected_ciphersuite = cipher_suite;
|
||||
*selected_ciphersuite_info = ciphersuite_info;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite"));
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
return SSL_TLS1_3_BINDER_DOES_NOT_MATCH;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_ciphersuite_for_resumption(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *cipher_suites,
|
||||
const unsigned char *cipher_suites_end,
|
||||
mbedtls_ssl_session *session,
|
||||
uint16_t *selected_ciphersuite,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
|
||||
{
|
||||
|
||||
*selected_ciphersuite = 0;
|
||||
*selected_ciphersuite_info = NULL;
|
||||
for (const unsigned char *p = cipher_suites; p < cipher_suites_end; p += 2) {
|
||||
uint16_t cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
if (cipher_suite != session->ciphersuite) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
|
||||
cipher_suite);
|
||||
if (ciphersuite_info == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*selected_ciphersuite = cipher_suite;
|
||||
*selected_ciphersuite_info = ciphersuite_info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
|
||||
const mbedtls_ssl_session *src)
|
||||
@ -481,6 +473,13 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
struct psk_attributes {
|
||||
int type;
|
||||
int key_exchange_mode;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
};
|
||||
#define PSK_ATTRIBUTES_INIT { 0, 0, NULL }
|
||||
|
||||
/* Parser for pre_shared_key extension in client hello
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
@ -507,7 +506,8 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
const unsigned char *pre_shared_key_ext,
|
||||
const unsigned char *pre_shared_key_ext_end,
|
||||
const unsigned char *ciphersuites,
|
||||
const unsigned char *ciphersuites_end)
|
||||
const unsigned char *ciphersuites_end,
|
||||
struct psk_attributes *psk)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned char *identities = pre_shared_key_ext;
|
||||
@ -558,9 +558,10 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
uint32_t obfuscated_ticket_age;
|
||||
const unsigned char *binder;
|
||||
size_t binder_len;
|
||||
int psk_type;
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
int psk_ciphersuite_id;
|
||||
psa_algorithm_t psk_hash_alg;
|
||||
int allowed_key_exchange_modes;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_session session;
|
||||
mbedtls_ssl_session_init(&session);
|
||||
@ -586,47 +587,74 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
|
||||
ret = ssl_tls13_offered_psks_check_identity_match(
|
||||
ssl, identity, identity_len, obfuscated_ticket_age,
|
||||
&psk_type, &session);
|
||||
if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
|
||||
&psk->type, &session);
|
||||
if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity"));
|
||||
switch (psk_type) {
|
||||
|
||||
switch (psk->type) {
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL:
|
||||
ret = ssl_tls13_select_ciphersuite_for_psk(
|
||||
ssl, ciphersuites, ciphersuites_end,
|
||||
&cipher_suite, &ciphersuite_info);
|
||||
psk_ciphersuite_id = 0;
|
||||
psk_hash_alg = PSA_ALG_SHA_256;
|
||||
allowed_key_exchange_modes =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
|
||||
break;
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
ret = ssl_tls13_select_ciphersuite_for_resumption(
|
||||
ssl, ciphersuites, ciphersuites_end, &session,
|
||||
&cipher_suite, &ciphersuite_info);
|
||||
if (ret != 0) {
|
||||
mbedtls_ssl_session_free(&session);
|
||||
}
|
||||
#else
|
||||
ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||
#endif
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
|
||||
psk_ciphersuite_id = session.ciphersuite;
|
||||
psk_hash_alg = PSA_ALG_NONE;
|
||||
ssl->session_negotiate->ticket_flags = session.ticket_flags;
|
||||
allowed_key_exchange_modes =
|
||||
session.ticket_flags &
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
if (ret != 0) {
|
||||
/* See below, no cipher_suite available, abort handshake */
|
||||
|
||||
psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
|
||||
|
||||
if ((allowed_key_exchange_modes &
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
|
||||
ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
|
||||
psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
} else if ((allowed_key_exchange_modes &
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
|
||||
ssl_tls13_key_exchange_is_psk_available(ssl)) {
|
||||
psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
}
|
||||
|
||||
if (psk->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode"));
|
||||
continue;
|
||||
}
|
||||
|
||||
ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end,
|
||||
psk_ciphersuite_id, psk_hash_alg,
|
||||
&psk->ciphersuite_info);
|
||||
|
||||
if (psk->ciphersuite_info == NULL) {
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_session_free(&session);
|
||||
#endif
|
||||
/*
|
||||
* We consider finding a ciphersuite suitable for the PSK as part
|
||||
* of the validation of its binder. Thus if we do not find one, we
|
||||
* abort the handshake with a decrypt_error alert.
|
||||
*/
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
2, "ssl_tls13_select_ciphersuite", ret);
|
||||
return ret;
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
|
||||
ret = ssl_tls13_offered_psks_check_binder_match(
|
||||
ssl, binder, binder_len, psk_type,
|
||||
mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac));
|
||||
if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
|
||||
ssl, binder, binder_len, psk->type,
|
||||
mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) psk->ciphersuite_info->mac));
|
||||
if (ret != SSL_TLS1_3_BINDER_MATCH) {
|
||||
/* For security reasons, the handshake should be aborted when we
|
||||
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
|
||||
* and appendix E.6. */
|
||||
@ -644,13 +672,8 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
|
||||
matched_identity = identity_id;
|
||||
|
||||
/* Update handshake parameters */
|
||||
ssl->handshake->ciphersuite_info = ciphersuite_info;
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("overwrite ciphersuite: %04x - %s",
|
||||
cipher_suite, ciphersuite_info->name));
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
|
||||
if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
|
||||
ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate,
|
||||
&session);
|
||||
mbedtls_ssl_session_free(&session);
|
||||
@ -676,7 +699,7 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
||||
return ret;
|
||||
}
|
||||
if (matched_identity == -1) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket."));
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("No usable PSK or ticket."));
|
||||
return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
|
||||
}
|
||||
|
||||
@ -1003,21 +1026,29 @@ static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl,
|
||||
unsigned int kex_mode)
|
||||
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if (ssl->handshake->resume) {
|
||||
if (!mbedtls_ssl_tls13_session_ticket_has_flags(
|
||||
ssl->session_negotiate, kex_mode)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
|
||||
return mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) &&
|
||||
mbedtls_ssl_tls13_is_psk_supported(ssl) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
|
||||
#else
|
||||
((void) ssl);
|
||||
((void) kex_mode);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
|
||||
return mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) &&
|
||||
mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
|
||||
#else
|
||||
((void) ssl);
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
|
||||
|
||||
@ -1033,83 +1064,6 @@ static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ss
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
|
||||
return ssl_tls13_ticket_is_kex_mode_permitted(
|
||||
ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
|
||||
mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) &&
|
||||
mbedtls_ssl_tls13_is_psk_supported(ssl) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
|
||||
#else
|
||||
((void) ssl);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
|
||||
return ssl_tls13_ticket_is_kex_mode_permitted(
|
||||
ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
|
||||
mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) &&
|
||||
mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) &&
|
||||
ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
|
||||
#else
|
||||
((void) ssl);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
/*
|
||||
* Determine the key exchange algorithm to use.
|
||||
* There are three types of key exchanges supported in TLS 1.3:
|
||||
* - (EC)DH with ECDSA,
|
||||
* - (EC)DH with PSK,
|
||||
* - plain PSK.
|
||||
*
|
||||
* The PSK-based key exchanges may additionally be used with 0-RTT.
|
||||
*
|
||||
* Our built-in order of preference is
|
||||
* 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
|
||||
* 2 ) Certificate Mode ( ephemeral )
|
||||
* 3 ) Plain PSK Mode ( psk )
|
||||
*/
|
||||
|
||||
ssl->handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
|
||||
|
||||
if (ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
|
||||
ssl->handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
|
||||
} else
|
||||
if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
|
||||
ssl->handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
|
||||
} else
|
||||
if (ssl_tls13_key_exchange_is_psk_available(ssl)) {
|
||||
ssl->handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1,
|
||||
("ClientHello message misses mandatory extensions."));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
|
||||
|
||||
@ -1301,6 +1255,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
int no_usable_share_for_key_agreement = 0;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
int got_psk = 0;
|
||||
struct psk_attributes psk = PSK_ATTRIBUTES_INIT;
|
||||
const unsigned char *pre_shared_key_ext = NULL;
|
||||
const unsigned char *pre_shared_key_ext_end = NULL;
|
||||
#endif
|
||||
@ -1437,12 +1393,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
* We negotiate TLS 1.3.
|
||||
*/
|
||||
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/* Store minor version for later use with ticket serialization. */
|
||||
ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are negotiating the version 1.3 of the protocol. Do what we have
|
||||
@ -1468,37 +1420,20 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
*/
|
||||
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites",
|
||||
cipher_suites, cipher_suites_len);
|
||||
for (const unsigned char *cipher_suites_p = cipher_suites;
|
||||
cipher_suites_p < cipher_suites_end; cipher_suites_p += 2) {
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
/*
|
||||
* "cipher_suites_end - cipher_suites_p is even" is an invariant of the
|
||||
* loop. As cipher_suites_end - cipher_suites_p > 0, we have
|
||||
* cipher_suites_end - cipher_suites_p >= 2 and it is thus safe to read
|
||||
* two bytes.
|
||||
*/
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE(cipher_suites_p, 0);
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
|
||||
ssl, cipher_suite);
|
||||
if (ciphersuite_info == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
handshake->ciphersuite_info = ciphersuite_info;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
|
||||
cipher_suite,
|
||||
ciphersuite_info->name));
|
||||
break;
|
||||
}
|
||||
ssl_tls13_select_ciphersuite(ssl, cipher_suites, cipher_suites_end,
|
||||
0, PSA_ALG_NONE, &handshake->ciphersuite_info);
|
||||
|
||||
if (handshake->ciphersuite_info == NULL) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
|
||||
((unsigned) handshake->ciphersuite_info->id),
|
||||
handshake->ciphersuite_info->name));
|
||||
|
||||
/* ...
|
||||
* opaque legacy_compression_methods<1..2^8-1>;
|
||||
@ -1535,7 +1470,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *extension_data_end;
|
||||
uint32_t allowed_exts = MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CH;
|
||||
|
||||
if (ssl->handshake->hello_retry_request_count > 0) {
|
||||
if (ssl->handshake->hello_retry_request_flag) {
|
||||
/* Do not accept early data extension in 2nd ClientHello */
|
||||
allowed_exts &= ~MBEDTLS_SSL_EXT_MASK(EARLY_DATA);
|
||||
}
|
||||
@ -1738,10 +1673,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
/* Update checksum with either
|
||||
* - The entire content of the CH message, if no PSK extension is present
|
||||
* - The content up to but excluding the PSK extension, if present.
|
||||
* Always parse the pre-shared-key extension when present in the
|
||||
* ClientHello even if some pre-requisites for PSK key exchange modes are
|
||||
* not met. That way we always validate the syntax of the extension.
|
||||
*/
|
||||
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
|
||||
if (ssl_tls13_key_exchange_is_psk_available(ssl) ||
|
||||
ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
|
||||
if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) {
|
||||
ret = handshake->update_checksum(ssl, buf,
|
||||
pre_shared_key_ext - buf);
|
||||
if (0 != ret) {
|
||||
@ -1752,10 +1688,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
pre_shared_key_ext,
|
||||
pre_shared_key_ext_end,
|
||||
cipher_suites,
|
||||
cipher_suites_end);
|
||||
if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
|
||||
handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY);
|
||||
} else if (ret != 0) {
|
||||
cipher_suites_end,
|
||||
&psk);
|
||||
if (ret == 0) {
|
||||
got_psk = 1;
|
||||
} else if (ret != MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
1, "ssl_tls13_parse_pre_shared_key_ext", ret);
|
||||
return ret;
|
||||
@ -1770,12 +1707,68 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
}
|
||||
}
|
||||
|
||||
ret = ssl_tls13_determine_key_exchange_mode(ssl);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
/*
|
||||
* Determine the key exchange algorithm to use.
|
||||
* There are three types of key exchanges supported in TLS 1.3:
|
||||
* - (EC)DH with ECDSA,
|
||||
* - (EC)DH with PSK,
|
||||
* - plain PSK.
|
||||
*
|
||||
* The PSK-based key exchanges may additionally be used with 0-RTT.
|
||||
*
|
||||
* Our built-in order of preference is
|
||||
* 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
|
||||
* 2 ) Certificate Mode ( ephemeral )
|
||||
* 3 ) Plain PSK Mode ( psk )
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
if (got_psk && (psk.key_exchange_mode ==
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL)) {
|
||||
handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
|
||||
|
||||
} else
|
||||
#endif
|
||||
if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
|
||||
handshake->key_exchange_mode =
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
|
||||
|
||||
}
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
else if (got_psk && (psk.key_exchange_mode ==
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK)) {
|
||||
handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1,
|
||||
("ClientHello message misses mandatory extensions."));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
|
||||
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
if (ssl->handshake->key_exchange_mode !=
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
if (handshake->key_exchange_mode &
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) {
|
||||
handshake->ciphersuite_info = psk.ciphersuite_info;
|
||||
ssl->session_negotiate->ciphersuite = psk.ciphersuite_info->id;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("Select PSK ciphersuite: %04x - %s",
|
||||
((unsigned) psk.ciphersuite_info->id),
|
||||
psk.ciphersuite_info->name));
|
||||
|
||||
if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
|
||||
handshake->resume = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (handshake->key_exchange_mode !=
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) {
|
||||
hrr_required = (no_usable_share_for_key_agreement != 0);
|
||||
}
|
||||
@ -1977,10 +1970,6 @@ static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl)
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *server_randbytes =
|
||||
ssl->handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
|
||||
if (ssl->conf->f_rng == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
|
||||
return MBEDTLS_ERR_SSL_NO_RNG;
|
||||
}
|
||||
|
||||
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, server_randbytes,
|
||||
MBEDTLS_SERVER_HELLO_RANDOM_LEN)) != 0) {
|
||||
@ -2431,7 +2420,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_prepare_hello_retry_request(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
if (ssl->handshake->hello_retry_request_count > 0) {
|
||||
if (ssl->handshake->hello_retry_request_flag) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Too many HRRs"));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
@ -2478,7 +2467,7 @@ static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl)
|
||||
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len,
|
||||
msg_len));
|
||||
|
||||
ssl->handshake->hello_retry_request_count++;
|
||||
ssl->handshake->hello_retry_request_flag = 1;
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
/* The server sends a dummy change_cipher_spec record immediately
|
||||
@ -2917,17 +2906,14 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
|
||||
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
|
||||
/* RFC 8446 section 4.6.1
|
||||
*
|
||||
* A server receiving more than max_early_data_size bytes of 0-RTT data
|
||||
* SHOULD terminate the connection with an "unexpected_message" alert.
|
||||
*
|
||||
* TODO: Add received data size check here.
|
||||
*/
|
||||
if (ssl->in_offt == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
|
||||
/* Set the reading pointer */
|
||||
ssl->in_offt = ssl->in_msg;
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return SSL_GOT_EARLY_DATA;
|
||||
}
|
||||
@ -3132,10 +3118,6 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg"));
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
session->ticket_creation_time = mbedtls_ms_time();
|
||||
#endif
|
||||
|
||||
/* Set ticket_flags depends on the advertised psk key exchange mode */
|
||||
mbedtls_ssl_tls13_session_clear_ticket_flags(
|
||||
session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
|
||||
@ -3149,6 +3131,7 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
||||
ssl->conf->max_early_data_size > 0) {
|
||||
mbedtls_ssl_tls13_session_set_ticket_flags(
|
||||
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
|
||||
session->max_early_data_size = ssl->conf->max_early_data_size;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
@ -3270,6 +3253,9 @@ static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + 4 + 1 + ticket_nonce_size + 2);
|
||||
|
||||
/* Generate ticket and ticket_lifetime */
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
session->ticket_creation_time = mbedtls_ms_time();
|
||||
#endif
|
||||
ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
|
||||
session,
|
||||
p + 9 + ticket_nonce_size + 2,
|
||||
@ -3482,12 +3468,9 @@ int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
|
||||
ret = 0;
|
||||
if (ssl->handshake->ccs_count == 0) {
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
|
||||
break;
|
||||
|
@ -3290,4 +3290,12 @@ void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx)
|
||||
}
|
||||
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
|
||||
{
|
||||
if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) {
|
||||
return crt->MBEDTLS_PRIVATE(ca_istrue);
|
||||
}
|
||||
return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
@ -21,133 +21,6 @@
|
||||
#include "mbedtls/rsa.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Return the next relative DN in an X509 name.
|
||||
*
|
||||
* \note Intended use is to compare function result to dn->next
|
||||
* in order to detect boundaries of multi-valued RDNs.
|
||||
*
|
||||
* \param dn Current node in the X509 name
|
||||
*
|
||||
* \return Pointer to the first attribute-value pair of the
|
||||
* next RDN in sequence, or NULL if end is reached.
|
||||
*/
|
||||
static inline mbedtls_x509_name *mbedtls_x509_dn_get_next(
|
||||
mbedtls_x509_name *dn)
|
||||
{
|
||||
while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) {
|
||||
dn = dn->next;
|
||||
}
|
||||
return dn->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store the certificate serial in printable form into buf;
|
||||
* no more than size characters will be written.
|
||||
*
|
||||
* \param buf Buffer to write to
|
||||
* \param size Maximum size of buffer
|
||||
* \param serial The X509 serial to represent
|
||||
*
|
||||
* \return The length of the string written (not including the
|
||||
* terminated nul byte), or a negative error code.
|
||||
*/
|
||||
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial);
|
||||
|
||||
/**
|
||||
* \brief Compare pair of mbedtls_x509_time.
|
||||
*
|
||||
* \param t1 mbedtls_x509_time to compare
|
||||
* \param t2 mbedtls_x509_time to compare
|
||||
*
|
||||
* \return < 0 if t1 is before t2
|
||||
* 0 if t1 equals t2
|
||||
* > 0 if t1 is after t2
|
||||
*/
|
||||
int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2);
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
/**
|
||||
* \brief Fill mbedtls_x509_time with provided mbedtls_time_t.
|
||||
*
|
||||
* \param tt mbedtls_time_t to convert
|
||||
* \param now mbedtls_x509_time to fill with converted mbedtls_time_t
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return A non-zero return value on failure.
|
||||
*/
|
||||
int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now);
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
/**
|
||||
* \brief Check a given mbedtls_x509_time against the system time
|
||||
* and tell if it's in the past.
|
||||
*
|
||||
* \note Intended usage is "if( is_past( valid_to ) ) ERROR".
|
||||
* Hence the return value of 1 if on internal errors.
|
||||
*
|
||||
* \param to mbedtls_x509_time to check
|
||||
*
|
||||
* \return 1 if the given time is in the past or an error occurred,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to);
|
||||
|
||||
/**
|
||||
* \brief Check a given mbedtls_x509_time against the system time
|
||||
* and tell if it's in the future.
|
||||
*
|
||||
* \note Intended usage is "if( is_future( valid_from ) ) ERROR".
|
||||
* Hence the return value of 1 if on internal errors.
|
||||
*
|
||||
* \param from mbedtls_x509_time to check
|
||||
*
|
||||
* \return 1 if the given time is in the future or an error occurred,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
|
||||
|
||||
/**
|
||||
* \brief This function parses an item in the SubjectAlternativeNames
|
||||
* extension. Please note that this function might allocate
|
||||
* additional memory for a subject alternative name, thus
|
||||
* mbedtls_x509_free_subject_alt_name has to be called
|
||||
* to dispose of this additional memory afterwards.
|
||||
*
|
||||
* \param san_buf The buffer holding the raw data item of the subject
|
||||
* alternative name.
|
||||
* \param san The target structure to populate with the parsed presentation
|
||||
* of the subject alternative name encoded in \p san_buf.
|
||||
*
|
||||
* \note Supported GeneralName types, as defined in RFC 5280:
|
||||
* "rfc822Name", "dnsName", "directoryName",
|
||||
* "uniformResourceIdentifier" and "hardware_module_name"
|
||||
* of type "otherName", as defined in RFC 4108.
|
||||
*
|
||||
* \note This function should be called on a single raw data of
|
||||
* subject alternative name. For example, after successful
|
||||
* certificate parsing, one must iterate on every item in the
|
||||
* \c crt->subject_alt_names sequence, and pass it to
|
||||
* this function.
|
||||
*
|
||||
* \warning The target structure contains pointers to the raw data of the
|
||||
* parsed certificate, and its lifetime is restricted by the
|
||||
* lifetime of the certificate.
|
||||
*
|
||||
* \return \c 0 on success
|
||||
* \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
|
||||
* SAN type.
|
||||
* \return Another negative value for any other failure.
|
||||
*/
|
||||
int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
|
||||
mbedtls_x509_subject_alternative_name *san);
|
||||
/**
|
||||
* \brief Unallocate all data related to subject alternative name
|
||||
*
|
||||
* \param san SAN structure - extra memory owned by this structure will be freed
|
||||
*/
|
||||
void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san);
|
||||
|
||||
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_x509_name *cur);
|
||||
int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
|
||||
|
25
pkgconfig/CMakeLists.txt
Normal file
25
pkgconfig/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
include(JoinPaths.cmake)
|
||||
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
join_paths(PKGCONFIG_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
#define these manually since minimum CMAKE version is not 3.9 for DESCRIPTION and 3.12 for HOMEPAGE_URL usage in project() below.
|
||||
# Prefix with something that won't clash with newer versions of CMAKE.
|
||||
set(PKGCONFIG_PROJECT_DESCRIPTION "Mbed TLS is a C library that implements cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols. Its small code footprint makes it suitable for embedded systems.")
|
||||
set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://www.trustedfirmware.org/projects/mbed-tls/")
|
||||
|
||||
configure_file(mbedcrypto.pc.in mbedcrypto.pc @ONLY)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mbedcrypto.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
configure_file(mbedtls.pc.in mbedtls.pc @ONLY)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mbedtls.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
configure_file(mbedx509.pc.in mbedx509.pc @ONLY)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mbedx509.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
27
pkgconfig/JoinPaths.cmake
Normal file
27
pkgconfig/JoinPaths.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
# This module provides function for joining paths
|
||||
# known from most languages
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
#
|
||||
# This script originates from:
|
||||
# - https://github.com/jtojnar/cmake-snips
|
||||
# Jan has provided re-licensing under Apache 2.0 and GPL 2.0+ and
|
||||
# allowed for the change of Copyright.
|
||||
#
|
||||
# Modelled after Python’s os.path.join
|
||||
# https://docs.python.org/3.7/library/os.path.html#os.path.join
|
||||
# Windows not supported
|
||||
function(join_paths joined_path first_path_segment)
|
||||
set(temp_path "${first_path_segment}")
|
||||
foreach(current_segment IN LISTS ARGN)
|
||||
if(NOT ("${current_segment}" STREQUAL ""))
|
||||
if(IS_ABSOLUTE "${current_segment}")
|
||||
set(temp_path "${current_segment}")
|
||||
else()
|
||||
set(temp_path "${temp_path}/${current_segment}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${joined_path} "${temp_path}" PARENT_SCOPE)
|
||||
endfunction()
|
10
pkgconfig/mbedcrypto.pc.in
Normal file
10
pkgconfig/mbedcrypto.pc.in
Normal file
@ -0,0 +1,10 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||
libdir=@PKGCONFIG_LIBDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||
Version: @PROJECT_VERSION@
|
||||
Cflags: -I"${includedir}"
|
||||
Libs: -L"${libdir}" -lmbedcrypto
|
11
pkgconfig/mbedtls.pc.in
Normal file
11
pkgconfig/mbedtls.pc.in
Normal file
@ -0,0 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||
libdir=@PKGCONFIG_LIBDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||
Version: @PROJECT_VERSION@
|
||||
Requires.private: mbedcrypto mbedx509
|
||||
Cflags: -I"${includedir}"
|
||||
Libs: -L"${libdir}" -lmbedtls
|
11
pkgconfig/mbedx509.pc.in
Normal file
11
pkgconfig/mbedx509.pc.in
Normal file
@ -0,0 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=@PKGCONFIG_INCLUDEDIR@
|
||||
libdir=@PKGCONFIG_LIBDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PKGCONFIG_PROJECT_DESCRIPTION@
|
||||
URL: @PKGCONFIG_PROJECT_HOMEPAGE_URL@
|
||||
Version: @PROJECT_VERSION@
|
||||
Requires.private: mbedcrypto
|
||||
Cflags: -I"${includedir}"
|
||||
Libs: -L"${libdir}" -lmbedx509
|
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