Merge branch 'development' into safer-ct5

Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
This commit is contained in:
Dave Rodgman 2023-08-07 11:47:35 +01:00 committed by GitHub
commit c98f8d996a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
257 changed files with 20700 additions and 8475 deletions

2
.gitignore vendored
View file

@ -1,5 +1,7 @@
# Random seed file created by test scripts and sample programs # Random seed file created by test scripts and sample programs
seedfile seedfile
# MBEDTLS_PSA_INJECT_ENTROPY seed file created by the test framework
00000000ffffff52.psa_its
# CMake build artifacts: # CMake build artifacts:
CMakeCache.txt CMakeCache.txt

View file

@ -118,6 +118,10 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
FORCE) FORCE)
endif() endif()
# Make MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE into PATHs
set(MBEDTLS_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS config file (overrides default).")
set(MBEDTLS_USER_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS user config file (appended to default).")
# Create a symbolic link from ${base_name} in the binary directory # Create a symbolic link from ${base_name} in the binary directory
# to the corresponding path in the source directory. # to the corresponding path in the source directory.
# Note: Copies the file(s) on Windows. # Note: Copies the file(s) on Windows.
@ -297,6 +301,20 @@ if(ENABLE_TESTING OR ENABLE_PROGRAMS)
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/everest/include) PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/everest/include)
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
if(MBEDTLS_CONFIG_FILE)
target_compile_definitions(mbedtls_test
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
target_compile_definitions(mbedtls_test_helpers
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
endif()
if(MBEDTLS_USER_CONFIG_FILE)
target_compile_definitions(mbedtls_test
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
target_compile_definitions(mbedtls_test_helpers
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
endif()
endif() endif()
if(ENABLE_PROGRAMS) if(ENABLE_PROGRAMS)
@ -354,7 +372,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file( write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake" "cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion COMPATIBILITY SameMajorVersion
VERSION 3.4.0) VERSION 3.4.1)
install( install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake" FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"

View file

@ -1,5 +1,13 @@
Mbed TLS ChangeLog (Sorted per branch, date) Mbed TLS ChangeLog (Sorted per branch, date)
= Mbed TLS 3.4.1 branch released 2023-08-04
Bugfix
* Fix builds on Windows with clang
Changes
* Update test data to avoid failures of unit tests after 2023-08-07.
= Mbed TLS 3.4.0 branch released 2023-03-28 = Mbed TLS 3.4.0 branch released 2023-03-28
Default behavior changes Default behavior changes

View file

@ -21,6 +21,9 @@ We generally don't include changelog entries for:
* Performance improvements, unless they are particularly significant. * Performance improvements, unless they are particularly significant.
* Changes to parts of the code base that users don't interact with directly, * Changes to parts of the code base that users don't interact with directly,
such as test code and test data. such as test code and test data.
* Fixes for compiler warnings. Releases typically contain a number of fixes
of this kind, so we will only mention them in the Changelog if they are
particularly significant.
Until Mbed TLS 2.24.0, we required changelog entries in more cases. Until Mbed TLS 2.24.0, we required changelog entries in more cases.
Looking at older changelog entries is good practice for how to write a Looking at older changelog entries is good practice for how to write a

View file

@ -2,13 +2,17 @@ New deprecations
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and * PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR, where xxx is either ECC or RSA, MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR, where xxx is either ECC or RSA,
are now being deprecated in favor of PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and are now being deprecated in favor of PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy. Here yyy can be: USE, IMPORT, MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy. Here yyy can be: BASIC,
EXPORT, GENERATE, DERIVE. The goal is to have a finer detail about the IMPORT, EXPORT, GENERATE, DERIVE. The goal is to have a finer detail about
capabilities of the PSA side for either key. the capabilities of the PSA side for either key.
Features Features
* New symbols PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and * New symbols PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy (where xxx is either ECC, RSA MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy (where xxx is either ECC, RSA
or DH) were introduced in order to have finer accuracy in defining the or DH) were introduced in order to have finer accuracy in defining the
PSA capabilities for each key. These capabilities, named yyy above, can be PSA capabilities for each key. These capabilities, named yyy above, can be
any of: USE, IMPORT, EXPORT, GENERATE, DERIVE. any of: BASIC, IMPORT, EXPORT, GENERATE, DERIVE.
- DERIVE is only available for ECC keys, not for RSA or DH ones.
- implementations are free to enable more than what it was strictly
requested. For example BASIC internally enables IMPORT and EXPORT
(useful for testing purposes), but this might change in the future.

View file

@ -0,0 +1,7 @@
Features
* Add getter (mbedtls_ssl_cache_get_timeout()) to access
`mbedtls_ssl_cache_context.timeout`.
* Add getter (mbedtls_ssl_get_hostname()) to access
`mbedtls_ssl_context.hostname`.
* Add getter (mbedtls_ssl_conf_get_endpoint()) to access
`mbedtls_ssl_config.endpoint`.

View file

@ -1,4 +1,7 @@
Features Features
* AES performance improvements on 64-bit architectures. Uplift * AES performance improvements. Uplift varies by platform,
varies by platform, toolchain, optimisation flags and mode, toolchain, optimisation flags and mode.
in the 0 - 84% range. Aarch64, gcc and GCM/XTS benefit the most. Aarch64, gcc -Os and CCM, GCM and XTS benefit the most.
On Aarch64, uplift is typically around 20 - 110%.
When compiling with gcc -Os on Aarch64, AES-XTS improves
by 4.5x.

View file

@ -0,0 +1,3 @@
Features
* Allow MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE to be set by
setting the CMake variable of the same name at configuration time.

View file

@ -5,3 +5,6 @@ Features
MBEDTLS_USE_PSA_CRYPTO. Restartable/interruptible ECDHE operations in MBEDTLS_USE_PSA_CRYPTO. Restartable/interruptible ECDHE operations in
TLS 1.2 (ECDHE-ECDSA key exchange) are not supported in those builds yet, TLS 1.2 (ECDHE-ECDSA key exchange) are not supported in those builds yet,
as PSA does not have an API for restartable ECDH yet. as PSA does not have an API for restartable ECDH yet.
* When all of ECDH, ECDSA and EC J-PAKE are either disabled or provided by
a driver, it is possible to disable MBEDTLS_ECP_C and still get support
for ECC keys and algorithms in PSA. See docs/driver-only-builds.txt.

View file

@ -0,0 +1,3 @@
Changes
* Enforce minimum RSA key size when generating a key
to avoid accidental misuse.

View file

@ -0,0 +1,6 @@
Features
* Support for "opaque" (PSA-held) ECC keys in the PK module has been
extended: it is now possible to use mbedtls_pk_write_key_der(),
mbedtls_pk_write_key_pem(), mbedtls_pk_check_pair(), and
mbedtls_pk_verify() with opaque ECC keys (provided the PSA attributes
allow it).

View file

@ -0,0 +1,6 @@
Features
* Add support for FFDH key exchange in TLS 1.3.
This is automatically enabled as soon as PSA_WANT_ALG_FFDH
and the ephemeral or psk-ephemeral key exchange mode are enabled.
By default, all groups are offered; the list of groups can be
configured using the existing API function mbedtls_ssl_conf_groups().

View file

@ -0,0 +1,4 @@
Bugfix
* Fix crypt_and_hash decryption fail when used with a stream cipher
mode of operation due to the input not being multiple of block size.
Resolves #7417.

View file

@ -0,0 +1,5 @@
Bugfix
* In TLS 1.3, fix handshake failure when a client in its ClientHello
proposes an handshake based on PSK only key exchange mode or at least
one of the key exchange modes using ephemeral keys to a server that
supports only the PSK key exchange mode.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix a bug in which mbedtls_x509_string_to_names() would return success
when given a invalid name string if it did not contain '=' or ','.

View file

@ -0,0 +1,5 @@
Bugfix
* Fix compilation warnings in aes.c, which prevented the
example TF-M configuration in configs/ from building cleanly:
tfm_mbedcrypto_config_profile_medium.h with
crypto_config_profile_medium.h.

View file

@ -0,0 +1,2 @@
Bugfix
* Fix the build with MBEDTLS_PSA_INJECT_ENTROPY. Fixes #7516.

View file

@ -0,0 +1,3 @@
Features
* Improve mbedtls_x509_time performance and reduce memory use.
* Reduce syscalls to time() during certificate verification.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix CCM* with no tag being not supported in a build with CCM as the only
symmetric encryption algorithm and the PSA configuration enabled.

View file

@ -0,0 +1,2 @@
Requirement changes
* Officially require Python 3.8 now that earlier versions are out of support.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix a compilation error on some platforms when including mbedtls/ssl.h
with all TLS support disabled. Fixes #6628.

View file

@ -48,7 +48,7 @@ You need the following tools to build the library with the provided makefiles:
* GNU Make 3.82 or a build tool that CMake supports. * GNU Make 3.82 or a build tool that CMake supports.
* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, IAR 8 and Visual Studio 2013. More recent versions should work. Slightly older versions may work. * A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, IAR 8 and Visual Studio 2013. More recent versions should work. Slightly older versions may work.
* Python 3.6 to generate the test code, and to generate sample programs in the development branch. * Python 3.8 to generate the test code. Python is also needed to integrate PSA drivers and to build the development branch (see next section).
* Perl to run the tests, and to generate some source files in the development branch. * Perl to run the tests, and to generate some source files in the development branch.
* CMake 3.10.2 or later (if using CMake). * CMake 3.10.2 or later (if using CMake).
* Microsoft Visual Studio 2013 or later (if using Visual Studio). * Microsoft Visual Studio 2013 or later (if using Visual Studio).
@ -61,7 +61,7 @@ The source code of Mbed TLS includes some files that are automatically generated
The following tools are required: The following tools are required:
* Perl, for some library source files and for Visual Studio build files. * Perl, for some library source files and for Visual Studio build files.
* Python 3 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run: * Python 3.8 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
``` ```
python3 -m pip install --user -r scripts/basic.requirements.txt python3 -m pip install --user -r scripts/basic.requirements.txt
``` ```
@ -293,14 +293,16 @@ However, it does not aim to implement the whole specification; in particular it
The X.509 and TLS code can use PSA cryptography for most operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `mbedtls_config.h`. Note that TLS 1.3 uses PSA cryptography for most operations regardless of this option. See `docs/use-psa-crypto.md` for details. The X.509 and TLS code can use PSA cryptography for most operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `mbedtls_config.h`. Note that TLS 1.3 uses PSA cryptography for most operations regardless of this option. See `docs/use-psa-crypto.md` for details.
### Upcoming features ### PSA drivers
Future releases of this library will include: Mbed TLS supports drivers for cryptographic accelerators, secure elements and random generators. This is work in progress. Please note that the driver interfaces are not fully stable yet and may change without notice. We intend to preserve backward compatibility for application code (using the PSA Crypto API), but the code of the drivers may have to change in future minor releases of Mbed TLS.
* A driver programming interface, which makes it possible to use hardware accelerators instead of the default software implementation for chosen algorithms. Please see the [PSA driver example and guide](docs/psa-driver-example-and-guide.md) for information on writing a driver.
* Support for external keys to be stored and manipulated exclusively in a separate cryptoprocessor.
* A configuration mechanism to compile only the algorithms you need for your application. When using drivers, you will generally want to enable two compilation options (see the reference manual for more information):
* A wider set of cryptographic algorithms.
* `MBEDTLS_USE_PSA_CRYPTO` is necessary so that the X.509 and TLS code calls the PSA drivers rather than the built-in software implementation.
* `MBEDTLS_PSA_CRYPTO_CONFIG` allows you to enable PSA cryptographic mechanisms without including the code of the corresponding software implementation. This is not yet supported for all mechanisms.
License License
------- -------

View file

@ -0,0 +1,37 @@
/**
* \file configs/crypto-config-ccm-aes-sha256.h
*
* \brief PSA crypto configuration with only symmetric cryptography: CCM-AES,
* SHA-256, HMAC and key derivation
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PSA_CRYPTO_CONFIG_H
#define PSA_CRYPTO_CONFIG_H
#define PSA_WANT_ALG_CCM 1
#define PSA_WANT_ALG_HMAC 1
#define PSA_WANT_ALG_SHA_256 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_HMAC 1
#define PSA_WANT_KEY_TYPE_AES 1
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
#endif /* PSA_CRYPTO_CONFIG_H */

View file

@ -106,10 +106,33 @@
//#define PSA_WANT_KEY_TYPE_CAMELLIA 1 //#define PSA_WANT_KEY_TYPE_CAMELLIA 1
//#define PSA_WANT_KEY_TYPE_CHACHA20 1 //#define PSA_WANT_KEY_TYPE_CHACHA20 1
//#define PSA_WANT_KEY_TYPE_DES 1 //#define PSA_WANT_KEY_TYPE_DES 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 #define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_RAW_DATA 1 #define PSA_WANT_KEY_TYPE_RAW_DATA 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 //#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 //#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
/***********************************************************************
* Local edits below this delimiter
**********************************************************************/
/* Between Mbed TLS 3.4 and 3.5, the PSA_WANT_KEY_TYPE_RSA_KEY_PAIR macro
* (commented-out above) has been replaced with the following new macros: */
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE 1 /* Not supported */
/* Between Mbed TLS 3.4 and 3.5, the following macros have been added: */
//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC 1
//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
//#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE 1 // Not supported
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */ #endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */

View file

@ -43,8 +43,11 @@ record() {
fi fi
} }
# save current HEAD # save current HEAD.
HEAD=$(git branch --show-current) # Note: this can optionally be updated to
# HEAD=$(git branch --show-current)
# when using a Git version above 2.22
HEAD=$(git rev-parse --abbrev-ref HEAD)
# get the numbers before this PR for default and full # get the numbers before this PR for default and full
cleanup cleanup

View file

@ -0,0 +1,536 @@
# PSA storage resilience design
## Introduction
The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if the underlying storage exhibits non-nominal behavior. In this document, _resilience_ means correct behavior of the key store even under if the underlying platform behaves in a non-nominal, but still partially controlled way.
At this point, we are only concerned about one specific form of resilience: to a system crash or power loss. That is, we assume that the underlying platform behaves nominally, except that occasionally it may restart. In the field, this can happen due to a sudden loss of power.
This document explores the problem space, defines a library design and a test design.
## Resilience goals for API functions
**Goal: PSA Crypto API functions are atomic and committing.**
_Atomic_ means that when an application calls an API function, as far as the application is concerned, at any given point in time, the system is either in a state where the function has not started yet, or in a state where the function has returned. The application never needs to worry about an intermediate state.
_Committing_ means that when a function returns, the data has been written to the persistent storage. As a consequence, if the system restarts during a sequence of storage modifications $M_1, M_2, \ldots, M_n$, we know that when the system restarts, a prefix of the sequence has been performed. For example, there will never be a situation where $M_2$ has been performed but not $M_1$.
The committing property is important not only for sequences of operations, but also when reporting the result of an operation to an external system. For example, if a key creation function in the PSA Crypto API reports to the application that a key has been created, and the application reports to a server that the key has been created, it is guaranteed that the key exists even if the system restarts.
## Assumptions on the underlying file storage
PSA relies on a PSA ITS (Internal Trusted Storage) interface, which exposes a simple API. There are two functions to modify files:
* `set()` writes a whole file (either creating it, or replacing the previous content).
* `remove()` removes a file (returning a specific error code if the file does not exist).
**Assumption: the underlying ITS functions are atomic and committing.**
Since the underlying functions are atomic, the content of a file is always a version that was previously passed to `set()`. We do not try to handle the case where a file might be partially written.
## Overview of API functions
For a transparent key, all key management operations (creation or destruction) on persistent keys rely on a single call to the underlying storage (`set()` for a key creation, `remove()` for a key destruction). This also holds for an opaque key stored in a secure element that does not have its own key store: in this case, the core stores a wrapped (i.e. encrypted) copy of the key material, but this does not impact how the core interacts with the storage. Other API functions do not modify the storage.
The following case requires extra work related to resilience:
* [Key management for stateful secure element keys](#designing-key-management-for-secure-element-keys).
As a consequence, apart from the listed cases, the API calls inherit directly from the [resilience properties of the underyling storage](#assumptions-on-the-underlying-file-storage). We do not need to take any special precautions in the library design, and we do not need to perform any testing of resilience for transparent keys.
(This section was last updated for Mbed TLS 3.4.0 implementing PSA Crypto API 1.1.)
## Designing key management for secure element keys
In this section, we use “(stateful) secure element key” to mean a key stored in a stateful secure element, i.e. a secure element that stores keys. This excludes keys in a stateleess secure element for which the core stores a wrapped copy of the key. We study the problem of how key management in stateful secure elements interacts with storage and explore the design space.
### Assumptions on stateful secure elements
**Assumption: driver calls for key management in stateful secure elements are atomic and committing.**
(For stateless secure elements, this assumption is vacuously true.)
### Dual management of keys: the problem
For a secure element key, key management requires a commitment on both sites. For example, consider a successful key creation operation:
1. The core sends a request to the secure element to create a key.
2. The secure element modifies its key store to create the key.
3. The secure element reports to the core that the key has been created.
4. The core reports to the application that the key has been created.
If the core loses power between steps 1 and 2, the key does not exist yet. This is fine from an application's perspective since the core has not committed to the key's existence, but the core needs to take care not to leave resources in storage that are related to the non-existent key. If the core loses power between steps 2 and 3, the key exists in the secure element. From an application's perspective, the core may either report that the key exists or that it does not exist, but in the latter case, the core needs to free the key in the secure element, to avoid leaving behind inaccessible resources.
As a consequence, the content of the storage cannot remain the same between the end of step 1 and the end of step 3, since the core must behave differently depending on whether step 2 has taken place.
Accomplishing a transaction across system boundaries is a well-known problem in database management, with a well-known solution: two-phase commit.
### Overview of two-phase commit with stateful secure elements
With a key in a stateful secure element, a successful creation process goes as follows (see [“Key management in a secure element with storage” in the driver interface specification](../../proposed/psa-driver-interface.html#key-management-in-a-secure-element-with-storage)):
1. The core calls the driver's `"allocate_key"` entry point.
2. The driver allocates a unique identifier _D_ for the key. This is unrelated to the key identifier _A_ used by the application interface. This step must not modify the state of the secure element.
3. The core updates the storage to indicate that key identifier _A_ has the identifier _D_ in the driver, and that _A_ is in a half-created state.
4. The core calls the driver's key creation entry point, passing it the driver's chosen identifier _D_.
5. The driver creates the key in the secure element. When this happens, it concludes the voting phase of the two-phase commit: effectively, the secure element decides to commit. (It is however possible to revert this commitment by giving the secure element the order to destroy the key.)
6. The core updates the storage to indicate that _A_ is now in a fully created state. This concludes the commit phase of the two-phase commit.
If there is a loss of power:
* Before step 3: the system state has not changed at all. As far as the world is concerned, the key creation attempt never happened.
* Between step 3 and step 6: upon restart, the core needs to find out whether the secure element completed step 5 or not, and reconcile the state of the storage with the state of the secure element.
* After step 6: the key has been created successfully.
Key destruction goes as follows:
1. The core updates the storage indicating that the key is being destroyed.
2. The core calls the driver's `"destroy_key"` entry point.
3. The secure element destroys the key.
4. The core updates the storage to indicate that the key has been destroyed.
If there is a loss of power:
* Before step 1: the system state has not changed at all. As far as the world is concerned, the key destruction attempt never happened.
* Between step 1 and step 4: upon restart, the core needs to find out whether the secure element completed step 3 or not, and reconcile the state of the storage with the state of the secure element.
* After step 4: the key has been destroyed successfully.
In both cases, upon restart, the core needs to perform a transaction recovery. When a power loss happens, the core decides whether to commit or abort the transaction.
Note that the analysis in this section assumes that the driver does not update its persistent state during a key management operation (or at least not in a way that is influences the key management process — for example, it might renew an authorization token).
### Optimization considerations for transactions
We assume that power failures are rare. Therefore we will primarily optimize for the normal case. Transaction recovery needs to be practical, but does not have to be fully optimized.
The main quantity we will optimize for is the number of storage updates in the nominal case. This is good for performance because storage writes are likely to dominate the runtime in some hardware configurations where storage writes are slow and communication with the secure element is fast, for key management operations that require a small amount of computation. In addition, minimizing the number of storage updates is good for the longevity of flash media.
#### Information available during recovery
The PSA ITS API does not support enumerating files in storage: an ITS call can only access one file identifier. Therefore transaction recovery cannot be done by traversing files whose name is or encodes the key identifier. It must start by traversing a small number of files whose names are independent of the key identifiers involved.
#### Minimum effort for a transaction
Per the [assumptions on the underlying file storage](#assumptions-on-the-underlying-file-storage), each atomic operation in the internal storage concerns a single file: either removing it, or setting its content. Furthermore there is no way to enumerate the files in storage.
A key creation function must transform the internal storage from a state where file `id` does not exist, to a state where file `id` exists and has its desired final content (containing the key attributes and the driver's key identifier). The situation is similar with key destruction, except that the initial and final states are exchanged. Neither the initial state nor the final state reference `id` otherwise.
For a key that is not in a stateful element, the transaction consists of a single write operation. As discussed previously, this is not possible with a stateful secure element because the state of the internal storage needs to change both before and after the state change in the secure element. No other single-write algorithm works.
If there is a power failure around the time of changing the state of the secure element, there must be information in the internal storage that indicates that key `id` has a transaction in progress. The file `id` cannot be used for this purpose because there is no way to enumerate all keys (and even if there was, it would not be practical). Therefore the transaction will need to modify some other file `t` with a fixed name (a name that doesn't depend on the key). Since the final system state should be identical to the initial state except for the file `id`, the minimum number of storage operations for a transaction is 3:
* Write (create or update) a file `t` referencing `id`.
* Write the final state of `id`.
* Restore `t` to its initial state.
The strategies discussed in the [overview above](#overview-of-two-phase-commit-with-stateful-secure-elements) follow this pattern, with `t` being the file containing the transaction list that the recovery consults. We have just proved that this pattern is optimal.
Note that this pattern requires the state of `id` to be modified only once. In particular, if a key management involves writing an intermediate state for `id` before modifying the secure element state and writing a different state after that, this will require a total of 4 updates to internal storage. Since we want to minimize the number of storage updates, we will not explore designs that involved updating `id` twice or more.
### Recovery strategies
When the core starts, it needs to know about transaction(s) that need to be resumed. This information will be stored in a persistent “transaction list”, with one entry per key. In this section, we explore recovery strategies, and we determine what the transaction list needs to contain as well as when it needs to be updated. Other sections will explore the format of the transaction list, as well as how many keys it needs to contain.
#### Exploring the recovery decision tree
There are four cases for recovery when a transaction is in progress. In each case, the core can either decide to commit the transaction (which may require replaying the interrupted part) or abort it (which may require a rewind in the secure element). It may call the secure element driver's `"get_key_attributes"` entry point to find out whether the key is present.
* Key creation, key not present in the secure element:
* Committing means replaying the driver call in the key creation. This requires all the input, for example the data to import. This seems impractical in general. Also, the second driver call require a new call to `"allocate_key"` which will in general changing the key's driver identifier, which complicates state management in the core. Given the likely complexity, we exclude this strategy.
* Aborting means removing any trace of the key creation.
* Key creation, key present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted.
* Aborting means destroying the key in the secure element and removing any local storage used for that key.
* Key destruction, key not present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key.
* Aborting would mean re-creating the key in the secure element, which is impossible in general since the key material is no longer present.
* Key destruction, key present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key and destroying the key in the secure element.
* Aborting means keeping the key. This requires no action on the secure element, and is only practical locally if the local storage is intact.
#### Comparing recovery strategies
From the analysis above, assuming that all keys are treated in the same way, there are 4 possible strategies.
* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element driver to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point.
* Minimize the information processing: [always destroy the key](#exploring-the-always-destroy-strategy), i.e. abort all key creations and commit all key destructions. This does not require querying the state of the secure element. This does not require any special precautions to preserve information about the key during the transaction. It simplifies recovery in that the recovery process might not even need to know whether it's recovering a key creation or a key destruction.
* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element driver to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further.
* Always abort key creation, but follow the state of the secure element for key destruction. I can't think of a good reason to choose this strategy.
Requiring the driver to have a `"get_key_attributes"` entry point is potentially problematic because some secure elements don't have room to store key attributes: a key slot always exists, and it's up to the user to remember what, if anything, they put in it. The driver has to remember anyway, so that it can find a free slot when creating a key. But with a recovery strategy that doesn't involve a `"get_key_attributes"` entry point, the driver design is easier: the driver doesn't need to protect the information about slots in use against a power failure, the core takes care of that.
#### Exploring the follow-the-secure-element strategy
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier (not constant-size), and an indication of whether the key is being created or destroyed.
For key creation, we have all the information to store in the key file once the `"allocate_key"` call returns. We must store all the information that will go in the key file before calling the driver's key creation entry point. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list, indicating that it is being created.
3. Write the key file.
4. Call the driver's key creation entry point.
5. Remove the key from the transaction list.
During recovery, for each key in the transaction list that was being created:
* If the key exists in the secure element, just remove it from the transaction list.
* If the key does not exist in the secure element, first remove the key file if it is present, then remove the key from the transaction list.
For key destruction, we need to preserve the key file until after the key has been destroyed. Therefore the normal sequence of operations is:
1. Add the key to the transaction list, indicating that it is being destroyed.
2. Call the driver's `"destroy_key"` entry point.
3. Remove the key file.
4. Remove the key from the transaction list.
During recovery, for each key in the transaction list that was being created:
* If the key exists in the secure element, call the driver's `"destroy_key"` entry point, then remove the key file, and finally remote the key from the transaction lits.
* If the key does not exist in the secure element, remove the key file if it is still present, then remove the key from the transaction list.
#### Exploring the always-destroy strategy
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier (not constant-size).
For key creation, we do not need to store the key's metadata until it has been created in the secure element. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list.
3. Call the driver's key creation entry point.
4. Write the key file.
5. Remove the key from the transaction list.
For key destruction, we can remove the key file before contacting the secure element. Therefore the normal sequence of operations is:
1. Add the key to the transaction list.
2. Remove the key file.
3. Call the driver's `"destroy_key"` entry point.
4. Remove the key from the transaction list.
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
1. Remove the key file, treating `DOES_NOT_EXIST` as a success.
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
3. Remove the key from the transaction list.
#### Always-destroy strategy with a simpler transaction file
We can modify the [always-destroy strategy](#exploring-the-always-destroy-strategy) to make the transaction file simpler: if we ensure that the key file always exists if the key exists in the secure element, then the transaction list does not need to include the driver key identifier: it can be read from the key file.
For key creation, we need to store the key's metadata before creating in the secure element. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list.
3. Write the key file.
4. Call the driver's key creation entry point.
5. Remove the key from the transaction list.
For key destruction, we need to contact the secure element before removing the key file. Therefore the normal sequence of operations is:
1. Add the key to the transaction list.
2. Call the driver's `"destroy_key"` entry point.
3. Remove the key file.
4. Remove the key from the transaction list.
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
1. Load the driver key identifier from the key file. If the key file does not exist, skip to step 4.
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
3. Remove the key file, treating `DOES_NOT_EXIST` as a success.
4. Remove the key from the transaction list.
Compared with the basic always-destroy strategy:
* The transaction file handling is simpler since its entries have a fixed size.
* The flow of information is somewhat different from transparent keys and keys in stateless secure elements: we aren't just replacing “create the key material” by “tell the secure element to create the key material”, those happen at different times. But there's a different flow for stateful secure elements anyway, since the call to `"allocate_key"` has no analog in the stateless secure element or transparent cases.
#### Assisting secure element drivers with recovery
The actions of the secure element driver may themselves be non-atomic. So the driver must be given a chance to perform recovery.
To simplify the design of the driver, the core should guarantee that the driver will know if a transaction was in progress and the core cannot be sure about the state of the secure element. Merely calling a read-only entry point such as `"get_key_attributes"` does not provide enough information to the driver for it to know that it should actively perform recovery related to that key.
This gives an advantage to the “always destroy” strategy. Under this strategy, if the key might be in a transitional state, the core will request a key destruction from the driver. This means that, if the driver has per-key auxiliary data to clean up, it can bundle that as part of the key's destruction.
### Testing non-atomic processes
In this section, we discuss how to test non-atomic processes that must implement an atomic and committing interface. As discussed in [“Overview of API functions”](#overview-of-api-functions), this concerns key management in stateful secure elements.
#### Naive test strategy for non-atomic processes
Non-atomic processes consist of a series of atomic, committing steps.
Our general strategy to test them is as follows: every time there is a modification of persistent state, either in storage or in the (simulated) secure element, try both the nominal case and simulating a power loss. If a power loss occurs, restart the system (i.e. clean up and call `psa_crypto_init()`), and check that the system ends up in a consistent state.
Note that this creates a binary tree of possibilities: after each state modification, there may or may not be a restart, and after that different state modifications may occur, each of which may or may not be followed by a restart.
For example, consider testing of one key creation operation (see [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements), under the simplifying assumption that each storage update step, as well as the recovery after a restart, each make a single (atomic) storage modification and no secure element access. The nominal case consists of three state modifications: storage modification (start transaction), creation on the secure element, storage modification (commit transaction). We need to test the following sequences:
* Start transaction, restart, recovery.
* Start transaction, secure element operation, restart, recovery.
* Start transaction, secure element operation, commit transaction.
If, for example, recovery consists of two atomic steps, the tree of possibilities expands and may be infinite:
* Start transaction, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* etc.
* Start transaction, secure element operation, restart, ...
* Start transaction, secure element operation, commit transaction.
In order to limit the possibilities, we need to make some assumptions about the recovery step. For example, if we have confidence that recovery step 1 is idempotent (i.e. doing it twice is the same as doing it once), we don't need to test what happens in execution sequences that take recovery step 1 more than twice in a row.
### Splitting normal behavior and transaction recovery
We introduce an abstraction level in transaction recovery:
* Normal operation must maintain a certain invariant on the state of the world (internal storage and secure element).
* Transaction recovery is defined over all states of the world that satisfy this invariant.
This separation of concerns greatly facilitates testing, since it is now split into two parts:
* During the testing of normal operation, we can use read-only invasive testing to ensure that the invariant is maintained. No modification of normal behavior (such as simulated power failures) is necessary.
* Testing of transaction recovery is independent of how the system state was reached. We only need to artificially construct a representative sample of system states that match the invariant. Transaction recovery is itself an operation that must respect the invariant, and so we do not need any special testing for the case of an interrupted recovery.
Another benefit of this approach is that it is easier to specify and test what happens if the library is updated on a device with leftovers from an interrupted transaction. We will require and test that the new version of the library supports recovery of the old library's states, without worrying how those states were reached.
#### Towards an invariant for transactions
As discussed in the section [“Recovery strategies”](#recovery-strategies), the information about active transactions is stored in a transaction list file. The name of the transaction list file does not depend on the identifiers of the keys in the list, but there may be more than one transaction list, for example one per secure element. If so, each transaction list can be considered independently.
When no transaction is in progress, the transaction list does not exist, or is empty. The empty case must be supported because this is the initial state of the filesystem. When no transaction is in progress, the state of the secure element must be consistent with references to keys in that secure element contained in key files. More generally, if a key is not in the transaction list, then the key must be present in the secure element if and only if the key file is in the internal storage.
For the purposes of the state invariant, it matters whether the transaction list file contains the driver key identifier, or if the driver key identifier is only stored in the key file. This is because the core needs to know the driver key id in order to access the secure element. If the transaction list does not contain the driver key identifier, and the key file does not exist, the key must not be present in the secure element.
We thus have two scenarios, each with their own invariant: one where the transaction list contains only key identifiers, and one where it also contains the secure element's key identifier (as well as the location of the secure element if this is not encoded in the name of the transaction list file).
#### Storage invariant if the transaction list contains application key identifiers only
Invariants:
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
If `id` is in the transaction list and the file `id` exists, the key may or may not be present in the secure element.
The invariant imposes constraints on the [order of operations for the two-phase commit](#overview-of-two-phase-commit-with-stateful-secure-elements): key creation must create `id` before calling the secure element's key creation entry point, and key destruction must remove `id` after calling the secure element's key destruction entry point.
For recovery:
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
* If the file `id` exists:
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
#### Storage invariant if the transaction list contains driver key identifiers
Invariants:
* If `id` is not in the transaction list and the file `id` does not exist, then no resources corresponding to that key are in a secure element.
* If `id` is not in the transaction list and the file `id` exists, then the key is present in the secure element.
If `id` is in the transaction list, neither the state of `id` in the internal storage nor the state of the key in the secure element is known.
For recovery:
* If the file `id` does not exist, then destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success).
* If the file `id` exists:
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
#### Coverage of states that respect the invariant
For a given key, we have to consider three a priori independent boolean states:
* Whether the key file exists.
* Whether the key is in the secure element.
* Whether the key is in the transaction list.
There is full coverage for one key if we have tests of recovery for the states among these $2^3 = 8$ possibilities that satisfy the storage invariant.
In addition, testing should adequately cover the case of multiple keys in the transaction list. How much coverage is adequate depends on the layout of the list as well as white-box considerations of how the list is manipulated.
### Choice of a transaction design
#### Chosen transaction algorithm
Based on [“Optimization considerations for transactions”](#optimization-considerations-for-transactions), we choose a transaction algorithm that consists in the following operations:
1. Add the key identifier to the transaction list.
2. Call the secure element's key creation or destruction entry point.
3. Remove the key identifier from the transaction list.
In addition, before or after step 2, create or remove the key file in the internal storage.
In order to conveniently support multiple transactions at the same time, we pick the simplest possible layout for the transaction list: a simple array of key identifiers. Since the transaction list does not contain the driver key identifier:
* During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point.
* During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage.
This choice of algorithm does not require the secure element driver to have a `"get_key_attributes"` entry point.
#### Chosen storage invariant
The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows:
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
* If `id` is in the transaction list and a key exists by that identifier, the key's location is a stateful secure element.
#### Chosen recovery process
To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy with a simple transaction file](#always-destroy-strategy-with-a-simpler-transaction-file). The the recovery process is as follows:
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
* If the file `id` exists, call the secure element's key destruction entry point (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
## Specification of key management in stateful secure elements
This section only concerns stateful secure elements as discussed in [“Designing key management for secure element keys”](#designing-key-management-for-secure-element-keys), i.e. secure elements with an `"allocate_key"` entry point. The design follows the general principle described in [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements) and the specific choices justified in [“Choice of a transaction design”](choice-of-a-transaction-design).
### Transaction list file manipulation
The transaction list is a simple array of key identifiers.
To add a key identifier to the list:
1. Load the current list from the transaction list if it exists and it is not already cached in memory.
2. Append the key identifier to the array.
3. Write the updated list file.
To remove a key identifier from the list:
1. Load the current list if it is not already cached in memory. It is an error if the file does not exist since it must contain this identifier.
2. Remove the key identifier from the array. If it wasn't the last element in array, move array elements to fill the hole.
3. If the list is now empty, remove the transaction list file. Otherwise write the updated list to the file.
### Key creation process in the core
Let _A_ be the application key identifier.
1. Call the driver's `"allocate_key"` entry point, obtaining the driver key identifier _D_ chosen by the driver.
2. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
3. Create the key file _A_ in the internal storage. Note that this is done at a different time from what happens when creating a transparent key or a key in a stateless secure element: in those cases, creating the key file happens after the actual creation of the key material.
4. Call the secure element's key creation entry point.
5. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
If any step fails:
* If the secure element's key creation entry point has been called and succeeded, call the secure element's destroy entry point.
* If the key file has been created in the internal storage, remove it.
* Remove the key from the transaction list.
Note that this process is identical to key destruction, except that the key is already in the transaction list.
### Key destruction process in the core
Let _A_ be the application key identifier.
We assume that the key is loaded in a key slot in memory: the core needs to know the key's location in order to determine whether the key is in a stateful secure element, and if so to know the driver key identifier. A possible optimization would be to load only that information in local variables, without occupying a key store; this has the advantage that key destruction works even if the key store is full.
1. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
2. Call the secure element's `"destroy_key"` entry point.
3. Remove the key file _A_ from the internal storage.
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
5. Free the corresponding key slot in memory.
If any step fails, remember the error but continue the process, to destroy the resources associated with the key as much as is practical.
### Transaction recovery
For each key _A_ in the transaction list file, if the file _A_ exists in the internal storage:
1. Load the key into a key slot in memory (to get its location and the driver key identifier, although we could get the location from the transaction list).
2. Call the secure element's `"destroy_key"` entry point.
3. Remove the key file _A_ from the internal storage.
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
5. Free the corresponding key slot in memory.
The transaction list file can be processed in any order.
It is correct to update the transaction list after recovering each key, or to only delete the transaction list file once the recovery is over.
### Concrete format of the transaction list file
The transaction list file contains a [fixed header](#transaction-list-header-format) followed by a list of [fixed-size elements](#transaction-list-element-format).
The file uid is `PSA_CRYPTO_ITS_TRANSACTION_LIST_UID` = 0xffffff53.
#### Transaction list header format
* Version (2 bytes): 0x0003. (Chosen to differ from the first two bytes of a [dynamic secure element transaction file](#dynamic-secure-element-transaction-file), to reduce the risk of a mix-up.)
* Key name size (2 bytes): `sizeof(psa_storage_uid_t)`. Storing this size avoids reading bad data if Mbed TLS is upgraded to a different integration that names keys differently.
#### Transaction list element format
In practice, there will rarely be more than one active transaction at a time, so the size of an element is not critical for efficiency. Therefore, in addition to the key identifier which is required, we add some potentially useful information in case it becomes useful later. We do not put the driver key identifier because its size is not a constant.
* Key id: `sizeof(psa_storage_uid_t)` bytes.
* Key lifetime: 4 bytes (`sizeof(psa_key_lifetime_t)`). Currently unused during recovery.
* Operation type: 1 byte. Currently unused during recovery.
* 0: destroy key.
* 1: import key.
* 2: generate key.
* 3: derive key.
* 4: import key.
* Padding: 3 bytes. Reserved for future use. Currently unused during recovery.
#### Dynamic secure element transaction file
Note that the code base already references a “transaction file” (`PSA_CRYPTO_ITS_TRANSACTION_UID` = 0xffffff54), used by dynamic secure elements (feature enabled with `MBEDTLS_PSA_CRYPTO_SE_C`). This is a deprecated feature that has not been fully implemented: when this feature is enabled, the transaction file gets written during transactions, but if it exists when PSA crypto starts, `psa_crypto_init()` fails because [recovery has never been implemented](https://github.com/ARMmbed/mbed-crypto/issues/218).
For the new kind of secure element driver, we pick a different file name to avoid any mixup.
## Testing key management in secure elements
### Instrumentation for checking the storage invariant
#### Test hook locations
When `MBEDTLS_TEST_HOOKS` is enabled, each call to `psa_its_set()` or `psa_its_remove()` also calls a test hook, passing the file UID as an argument to the hook.
When a stateful secure element driver is present in the build, we use this hook to verify that the storage respects the [storage invariant](#chosen-storage-invariant). In addition, if there is some information about key ongoing operation (set explicitly by the test function as a global variable in the test framework), the hook tests that the content of the storage is compatible with the ongoing operation.
#### Test hook behavior
The storage invariant check cannot check all keys in storage, and does not need to (for example, it would be pointless to check anything about transparent keys). It checks the following keys:
* When invoked from the test hook on a key file: on that key.
* When invoked from the test hook on the transaction file: on all the keys listed in the transaction file.
* When invoked from a test secure element: on the specified key.
#### Test hook extra data
Some tests set global variables to indicate which persistent keys they manipulate. We instrument at least some of these tests to also indicate what operation is in progress on the key. See the GitHub issues or the source code for details.
### Testing of transaction recovery
When no secure element driver is present in the build, the presence of a transaction list file during initialization is an error.
#### Recovery testing process
When the stateful test secure element driver is present in the build, we run test cases on a representative selection of states of the internal storage and the test secure element. Each test case for transaction recovery has the following form:
1. Create the initial state:
* Create a transaction list file with a certain content.
* Create key files that we want to have in the test.
* Call the secure element test driver to create keys without going throught the PSA API.
2. Call `psa_crypto_init()`. Expect success if the initial state satisfies the [storage invariant](#chosen-storage-invariant) and failure otherwise.
3. On success, check that the expected keys exist, and that keys that are expected to have been destroyed by recovery do not exist.
4. Clean up the storage and the secure element test driver's state.
#### States to test recovery on
For a given key located in a secure element, the following combination of states are possible:
* Key file: present, absent.
* Key in secure element: present, absent.
* Key in the transaction file: no, creation (import), destruction.
We test all $2 \times 2 \times 3 = 12$ possibilities, each in its own test case. In each case, call the test function that checks the storage invariant and check that its result is as expected. Then, if the storage invariant is met, follow the [recovery testing process](#recovery-testing-process).
In addition, have at least one positive test case for each creation method other than import, to ensure that we don't reject a valid value.
Note: testing of a damaged filesystem (including a filesystem that doesn't meet the invariant) is out of scope of the present document.

View file

@ -30,17 +30,23 @@ Each test case has a description which succinctly describes for a human audience
#### SSL test case descriptions #### SSL test case descriptions
Each test case in `ssl-opt.sh` has a description which succinctly describes for a human audience what the test does. The test description is the first parameter to `run_tests`. Each test case in `ssl-opt.sh` has a description which succinctly describes for a human audience what the test does. The test description is the first parameter to `run_test`.
The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, the description must be written on the same line as `run_test`, in double quotes, for the sake of `check_test_cases.py`. The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, the description must be written on the same line as `run_test`, in double quotes, for the sake of `check_test_cases.py`.
### SSL cipher suite tests
Each test case in `compat.sh` has a description which succinctly describes for a human audience what the test does. The test description is `$TITLE` defined in `run_client`.
The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, failure cause in `compat.sh` is not classified as `ssl-opt.sh`, so the information of failed log files are followed as prompt.
## Running tests ## Running tests
### Outcome file ### Outcome file
#### Generating an outcome file #### Generating an outcome file
Unit tests and `ssl-opt.sh` record the outcome of each test case in a **test outcome file**. This feature is enabled if the environment variable `MBEDTLS_TEST_OUTCOME_FILE` is set. Set it to the path of the desired file. Unit tests, `ssl-opt.sh` and `compat.sh` record the outcome of each test case in a **test outcome file**. This feature is enabled if the environment variable `MBEDTLS_TEST_OUTCOME_FILE` is set. Set it to the path of the desired file.
If you run `all.sh --outcome-file test-outcome.csv`, this collects the outcome of all the test cases in `test-outcome.csv`. If you run `all.sh --outcome-file test-outcome.csv`, this collects the outcome of all the test cases in `test-outcome.csv`.
@ -52,7 +58,7 @@ The outcome file has 6 fields:
* **Platform**: a description of the platform, e.g. `Linux-x86_64` or `Linux-x86_64-gcc7-msan`. * **Platform**: a description of the platform, e.g. `Linux-x86_64` or `Linux-x86_64-gcc7-msan`.
* **Configuration**: a unique description of the configuration (`mbedtls_config.h`). * **Configuration**: a unique description of the configuration (`mbedtls_config.h`).
* **Test suite**: `test_suite_xxx` or `ssl-opt`. * **Test suite**: `test_suite_xxx`, `ssl-opt` or `compat`.
* **Test case**: the description of the test case. * **Test case**: the description of the test case.
* **Result**: one of `PASS`, `SKIP` or `FAIL`. * **Result**: one of `PASS`, `SKIP` or `FAIL`.
* **Cause**: more information explaining the result. * **Cause**: more information explaining the result.

153
docs/driver-only-builds.md Normal file
View file

@ -0,0 +1,153 @@
This document explains how to create builds of Mbed TLS where some
cryptographic mechanisms are provided only by PSA drivers (that is, no
built-in implementation of those algorithms), from a user's perspective.
This is useful to save code size for people who are using either a hardware
accelerator, or an alternative software implementation that's more
aggressively optimized for code size than the default one in Mbed TLS.
General considerations
----------------------
This document assumes that you already have a working driver.
Otherwise, please see the [PSA driver example and
guide](psa-driver-example-and-guide.md) for information on writing a
driver.
In order to have some mechanism provided only by a driver, you'll want
the following compile-time configuration options enabled:
- `MBEDTLS_PSA_CRYPTO_C` (enabled by default) - this enables PSA Crypto.
- `MBEDTLS_USE_PSA_CRYPTO` (disabled by default) - this makes PK, X.509 and
TLS use PSA Crypto. You need to enable this if you're using PK, X.509 or TLS
and want them to have access to the algorithms provided by your driver. (See
[the dedicated document](use-psa-crypto.md) for details.)
- `MBEDTLS_PSA_CRYPTO_CONFIG` (disabled by default) - this enables
configuration of cryptographic algorithms using `PSA_WANT` macros in
`include/psa/crypto_config.h`. See [Conditional inclusion of cryptographic
mechanism through the PSA API in Mbed
TLS](proposed/psa-conditional-inclusion-c.md) for details.
In addition, for each mechanism you want provided only by your driver:
- Define the corresponding `PSA_WANT` macro in `psa/crypto_config.h` - this
means the algorithm will be available in the PSA Crypto API.
- Define the corresponding `MBEDTLS_PSA_ACCEL` in your build. This could be
defined in `psa/crypto_config.h` or your compiler's command line. This
informs the PSA code that an accelerator is available for this mechanism.
- Undefine / comment out the corresponding `MBEDTLS_xxx_C` macro in
`mbedtls/mbedtls_config.h`. This ensures the built-in implementation is not
included in the build.
For example, if you want SHA-256 to be provided only by a driver, you'll want
`PSA_WANT_ALG_SHA_256` and `MBEDTLS_PSA_ACCEL_SHA_256` defined, and
`MBEDTLS_SHA256_C` undefined.
In addition to these compile-time considerations, at runtime you'll need to
make sure you call `psa_crypto_init()` before any function that uses the
driver-only mechanisms. Note that this is already a requirement for any use of
the PSA Crypto API, as well as for use of the PK, X.509 and TLS modules when
`MBEDTLS_USE_PSA_CRYPTO` is enabled, so in most cases your application will
already be doing this.
Mechanisms covered
------------------
For now, only the following (families of) mechanisms are supported:
- hashes: SHA-3, SHA-2, SHA-1, MD5, etc.
- elliptic-curve cryptography (ECC): ECDH, ECDSA, EC J-PAKE, ECC key types.
- finite-field Diffie-Hellman: FFDH algorithm, DH key types.
Supported means that when those are provided only by drivers, everything
(including PK, X.509 and TLS if `MBEDTLS_USE_PSA_CRYPTO` is enabled) should
work in the same way as if the mechanisms where built-in, except as documented
in the "Limitations" sub-sections of the sections dedicated to each family
below.
In the near future (end of 2023), we are planning to also add support for
ciphers (AES) and AEADs (GCM, CCM, ChachaPoly).
Currently (mid-2023) we don't have plans to extend this to RSA. If
you're interested in driver-only support for RSA, please let us know.
Hashes
------
TODO
Elliptic-curve cryptography (ECC)
---------------------------------
Note: things are still evolving. This section describes the situation right
after #7452 has been merged. It will be updated again in #7757 when bignum is
done.
It is possible to have most ECC operations provided only by a driver:
- the ECDH, ECDSA and EC J-PAKE algorithms;
- key import, export, and random generation.
More precisely:
- you can enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C` provided
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled;
- you can enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C` provided
`MBEDTLS_PSA_ACCEL_ALG_ECDSA` is enabled;
- you can enable `PSA_WANT_ALG_JPAKE` without `MBEDTLS_ECJPAKE_C` provided
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
In addition, if none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`,
`MBEDTLS_ECJPAKE_C` are enabled, you can enable:
- `PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT`;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE`;
without `MBEDTLS_ECP_C` provided the corresponding
`MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx` are enabled.
[Coming soon] If `MBEDTLS_ECP_C` is disabled and `ecp.c` is fully removed (see
"Limitations regarding fully removing `ecp.c`" below), and you're not using
RSA or FFDH, then you can also disable `MBEDTLS_BIGNUM_C` for further code
size saving.
### Limitations regarding fully removing `ecp.c`
A limited subset of `ecp.c` will still be automatically re-enabled if any of
the following is enabled:
- `MBEDTLS_PK_PARSE_EC_COMPRESSED` - support for parsing ECC keys where the
public part is in compressed format;
- `MBEDTLS_PK_PARSE_EC_EXTENDED` - support for parsing ECC keys where the
curve is identified not by name, but by explicit parameters;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE` - support for deterministic
derivation of an ECC keypair with `psa_key_derivation_output_key()`.
Note: when any of the above options is enabled, a subset of `ecp.c` will
automatically be included in the build in order to support it. Therefore
you can still disable `MBEDTLS_ECP_C` in `mbedtls_config.h` and this will
result in some code size savings, but not as much as when none of the
above features are enabled.
We do have plans to support each of these with `ecp.c` fully removed in the
future, however there is no established timeline. If you're interested, please
let us know, so we can take it into consideration in our planning.
### Limitations regarding restartable / interruptible ECC operations
At the moment, there is not driver support for interruptible operations
(see `psa_sign_hash_start()` + `psa_sign_hash_complete()` etc.) so as a
consequence these are not supported in builds without `MBEDTLS_ECDSA_C`.
Similarly, there is no PSA support for interruptible ECDH operations so these
are not supported without `ECDH_C`. See also limitations regarding
restartable operations with `MBEDTLS_USE_PSA_CRYPTO` in [its
documentation](use-psa-crypto.md).
Again, we have plans to support this in the future but not with an established
timeline, please let us know if you're interested.
### Limitations regarding the selection of curves
TODO: apparently we don't really support having some curves built-in and
others driver-only... investigate and describe the situation. See also #7899.
Finite-field Diffie-Hellman
---------------------------
TODO

View file

@ -22,7 +22,7 @@
*/ */
/** /**
* @mainpage Mbed TLS v3.4.0 API Documentation * @mainpage Mbed TLS v3.4.1 API Documentation
* *
* This documentation describes the internal structure of Mbed TLS. It was * This documentation describes the internal structure of Mbed TLS. It was
* automatically generated from specially formatted comment blocks in * automatically generated from specially formatted comment blocks in

View file

@ -1,4 +1,4 @@
PROJECT_NAME = "mbed TLS v3.4.0" PROJECT_NAME = "mbed TLS v3.4.1"
OUTPUT_DIRECTORY = ../apidoc/ OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_FOR_C = YES

View file

@ -259,10 +259,6 @@ int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
* \brief This function performs an ARIA-CTR encryption or decryption * \brief This function performs an ARIA-CTR encryption or decryption
* operation. * operation.
* *
* This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
*
* Due to the nature of CTR, you must use the same key schedule * Due to the nature of CTR, you must use the same key schedule
* for both encryption and decryption operations. Therefore, you * for both encryption and decryption operations. Therefore, you
* must use the context initialized with mbedtls_aria_setkey_enc() * must use the context initialized with mbedtls_aria_setkey_enc()

View file

@ -474,7 +474,7 @@ void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq);
* on a successful invocation. * on a successful invocation.
* \param end The end of the ASN.1 SEQUENCE container. * \param end The end of the ASN.1 SEQUENCE container.
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within * \param tag_must_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_must_value. * the SEQUENCE before comparing to \p tag_must_val.
* \param tag_must_val The required value of each ASN.1 tag found in the * \param tag_must_val The required value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_must_mask. * SEQUENCE, after masking with \p tag_must_mask.
* Mismatching tags lead to an error. * Mismatching tags lead to an error.
@ -483,7 +483,7 @@ void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq);
* while a value of \c 0xFF for \p tag_must_mask means * while a value of \c 0xFF for \p tag_must_mask means
* that \p tag_must_val is the only allowed tag. * that \p tag_must_val is the only allowed tag.
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within * \param tag_may_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_may_value. * the SEQUENCE before comparing to \p tag_may_val.
* \param tag_may_val The desired value of each ASN.1 tag found in the * \param tag_may_val The desired value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_may_mask. * SEQUENCE, after masking with \p tag_may_mask.
* Mismatching tags will be silently ignored. * Mismatching tags will be silently ignored.

View file

@ -129,6 +129,7 @@
#endif /* !MBEDTLS_HAVE_INT64 */ #endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint; typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint; typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#elif defined(__GNUC__) && ( \ #elif defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \ defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \ defined(__ppc64__) || defined(__powerpc64__) || \
@ -141,6 +142,7 @@ typedef uint64_t mbedtls_mpi_uint;
#endif /* MBEDTLS_HAVE_INT64 */ #endif /* MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint; typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint; typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION) #if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */ /* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
@ -156,6 +158,7 @@ typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#endif /* !MBEDTLS_HAVE_INT64 */ #endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint; typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint; typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION) #if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */ /* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef __uint128_t mbedtls_t_udbl; typedef __uint128_t mbedtls_t_udbl;
@ -165,6 +168,7 @@ typedef __uint128_t mbedtls_t_udbl;
/* Force 64-bit integers with unknown compiler */ /* Force 64-bit integers with unknown compiler */
typedef int64_t mbedtls_mpi_sint; typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint; typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#endif #endif
#endif /* !MBEDTLS_HAVE_INT32 */ #endif /* !MBEDTLS_HAVE_INT32 */
@ -175,6 +179,7 @@ typedef uint64_t mbedtls_mpi_uint;
#endif /* !MBEDTLS_HAVE_INT32 */ #endif /* !MBEDTLS_HAVE_INT32 */
typedef int32_t mbedtls_mpi_sint; typedef int32_t mbedtls_mpi_sint;
typedef uint32_t mbedtls_mpi_uint; typedef uint32_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT32_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION) #if !defined(MBEDTLS_NO_UDBL_DIVISION)
typedef uint64_t mbedtls_t_udbl; typedef uint64_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL #define MBEDTLS_HAVE_UDBL
@ -203,6 +208,12 @@ extern "C" {
* \brief MPI structure * \brief MPI structure
*/ */
typedef struct mbedtls_mpi { typedef struct mbedtls_mpi {
/** Pointer to limbs.
*
* This may be \c NULL if \c n is 0.
*/
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p);
/** Sign: -1 if the mpi is negative, 1 otherwise. /** Sign: -1 if the mpi is negative, 1 otherwise.
* *
* The number 0 must be represented with `s = +1`. Although many library * The number 0 must be represented with `s = +1`. Although many library
@ -214,16 +225,19 @@ typedef struct mbedtls_mpi {
* Note that this implies that calloc() or `... = {0}` does not create * Note that this implies that calloc() or `... = {0}` does not create
* a valid MPI representation. You must call mbedtls_mpi_init(). * a valid MPI representation. You must call mbedtls_mpi_init().
*/ */
int MBEDTLS_PRIVATE(s); signed short MBEDTLS_PRIVATE(s);
/** Total number of limbs in \c p. */ /** Total number of limbs in \c p. */
size_t MBEDTLS_PRIVATE(n); unsigned short MBEDTLS_PRIVATE(n);
/* Make sure that MBEDTLS_MPI_MAX_LIMBS fits in n.
/** Pointer to limbs. * Use the same limit value on all platforms so that we don't have to
* * think about different behavior on the rare platforms where
* This may be \c NULL if \c n is 0. * unsigned short can store values larger than the minimum required by
* the C language, which is 65535.
*/ */
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); #if MBEDTLS_MPI_MAX_LIMBS > 65535
#error "MBEDTLS_MPI_MAX_LIMBS > 65535 is not supported"
#endif
} }
mbedtls_mpi; mbedtls_mpi;
@ -530,7 +544,7 @@ int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X,
* \param X The destination MPI. This must point to an initialized MPI. * \param X The destination MPI. This must point to an initialized MPI.
* \param buf The input buffer. This must be a readable buffer of length * \param buf The input buffer. This must be a readable buffer of length
* \p buflen Bytes. * \p buflen Bytes.
* \param buflen The length of the input buffer \p p in Bytes. * \param buflen The length of the input buffer \p buf in Bytes.
* *
* \return \c 0 if successful. * \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@ -545,7 +559,7 @@ int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf,
* \param X The destination MPI. This must point to an initialized MPI. * \param X The destination MPI. This must point to an initialized MPI.
* \param buf The input buffer. This must be a readable buffer of length * \param buf The input buffer. This must be a readable buffer of length
* \p buflen Bytes. * \p buflen Bytes.
* \param buflen The length of the input buffer \p p in Bytes. * \param buflen The length of the input buffer \p buf in Bytes.
* *
* \return \c 0 if successful. * \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@ -985,8 +999,8 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A,
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
* or equal to one. * or equal to one.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p A has no modular
* with respect to \p N. * inverse with respect to \p N.
*/ */
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *N); const mbedtls_mpi *N);

View file

@ -38,16 +38,16 @@
*/ */
#define MBEDTLS_VERSION_MAJOR 3 #define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 4 #define MBEDTLS_VERSION_MINOR 4
#define MBEDTLS_VERSION_PATCH 0 #define MBEDTLS_VERSION_PATCH 1
/** /**
* The single version number has the following structure: * The single version number has the following structure:
* MMNNPP00 * MMNNPP00
* Major version | Minor version | Patch version * Major version | Minor version | Patch version
*/ */
#define MBEDTLS_VERSION_NUMBER 0x03040000 #define MBEDTLS_VERSION_NUMBER 0x03040100
#define MBEDTLS_VERSION_STRING "3.4.0" #define MBEDTLS_VERSION_STRING "3.4.1"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.0" #define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.1"
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1 #define _CRT_SECURE_NO_DEPRECATE 1
@ -161,6 +161,37 @@
#define MBEDTLS_PK_PARSE_EC_COMPRESSED #define MBEDTLS_PK_PARSE_EC_COMPRESSED
#endif #endif
/* Helper symbol to state that there is support for ECDH, either through
* library implementation (ECDH_C) or through PSA. */
#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \
(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C))
#define MBEDTLS_CAN_ECDH
#endif
/* PK module can achieve ECDSA functionalities by means of either software
* implementations (ECDSA_C) or through a PSA driver. The following defines
* are meant to list these capabilities in a general way which abstracts how
* they are implemented under the hood. */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif /* MBEDTLS_ECDSA_C */
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(PSA_WANT_ALG_ECDSA)
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* PSA_WANT_ALG_ECDSA */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT /* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code. * is defined as well to include all PSA code.
*/ */
@ -222,14 +253,10 @@
#undef MBEDTLS_SSL_EARLY_DATA #undef MBEDTLS_SSL_EARLY_DATA
#endif #endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) || \ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) (defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED))
#endif #define MBEDTLS_SSL_TLS1_2_SOME_ECC
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED
#endif #endif
/* Make sure all configuration symbols are set before including check_config.h, /* Make sure all configuration symbols are set before including check_config.h,

View file

@ -220,7 +220,7 @@ int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
* *note Due to the nature of CTR mode, you should use the same * *note Due to the nature of CTR mode, you should use the same
* key for both encryption and decryption. In particular, calls * key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via * to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode * mbedtls_camellia_setkey_enc() regardless of whether the mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT. * is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* *
* \warning You must never reuse a nonce value with the same key. Doing so * \warning You must never reuse a nonce value with the same key. Doing so

View file

@ -35,7 +35,7 @@
#include <stdint.h> #include <stdint.h>
#if defined(_WIN32) #if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#if !defined(MBEDTLS_PLATFORM_C) #if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows" #error "MBEDTLS_PLATFORM_C is required on Windows"
#endif #endif
@ -51,7 +51,7 @@
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT #define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif #endif
#endif /* _WIN32 */ #endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C) #if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS" #error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
@ -275,22 +275,9 @@
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif #endif
/* Helper for ECDSA dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if (defined(PSA_WANT_ALG_ECDSA) || \
defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for JPAKE dependencies, will be undefined at the end of the file */ /* Helper for JPAKE dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_JPAKE) && defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY) #if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define MBEDTLS_PK_HAVE_JPAKE #define MBEDTLS_PK_HAVE_JPAKE
#endif #endif
#else /* MBEDTLS_USE_PSA_CRYPTO */ #else /* MBEDTLS_USE_PSA_CRYPTO */
@ -299,17 +286,6 @@
#endif #endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for ECDH dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_ECDH) && defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY)
#define MBEDTLS_PK_HAVE_ECDH
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECDH_C)
#define MBEDTLS_PK_HAVE_ECDH
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for curve SECP256R1 */ /* Helper for curve SECP256R1 */
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ECC_SECP_R1_256) #if defined(PSA_WANT_ECC_SECP_R1_256)
@ -322,14 +298,14 @@
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \ ( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \ !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) ) !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || !defined(MBEDTLS_RSA_C) || \ ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) ) !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif #endif
@ -339,7 +315,7 @@
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_PK_HAVE_ECDH) !defined(MBEDTLS_CAN_ECDH)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif #endif
@ -350,14 +326,14 @@
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || !defined(MBEDTLS_RSA_C) || \ ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \ ( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \ !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) ) !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif #endif
@ -814,14 +790,15 @@
#endif #endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#if !( defined(PSA_WANT_ALG_ECDH) && defined(MBEDTLS_X509_CRT_PARSE_C) && \ #if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
( defined(MBEDTLS_PK_HAVE_ECDSA) || defined(MBEDTLS_PKCS1_V21) ) ) defined(MBEDTLS_X509_CRT_PARSE_C) && \
( defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || defined(MBEDTLS_PKCS1_V21) ) )
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites" #error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites"
#endif #endif
#endif #endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#if !( defined(PSA_WANT_ALG_ECDH) ) #if !( defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) )
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites" #error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites"
#endif #endif
#endif #endif
@ -1129,9 +1106,7 @@
#endif #endif
/* Undefine helper symbols */ /* Undefine helper symbols */
#undef MBEDTLS_PK_HAVE_ECDSA
#undef MBEDTLS_PK_HAVE_JPAKE #undef MBEDTLS_PK_HAVE_JPAKE
#undef MBEDTLS_PK_HAVE_ECDH
#undef MBEDTLS_MD_HAVE_SHA256 #undef MBEDTLS_MD_HAVE_SHA256
#undef MBEDTLS_MD_HAVE_SHA384 #undef MBEDTLS_MD_HAVE_SHA384
#undef MBEDTLS_MD_HAVE_SHA512 #undef MBEDTLS_MD_HAVE_SHA512

View file

@ -270,45 +270,58 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
* mbedtls_cipher_info_from_type(), * mbedtls_cipher_info_from_type(),
* mbedtls_cipher_info_from_values(), * mbedtls_cipher_info_from_values(),
* mbedtls_cipher_info_from_psa(). * mbedtls_cipher_info_from_psa().
*
* \note Some fields store a value that has been right-shifted to save
* code-size, so should not be used directly. The accessor
* functions adjust for this and return the "natural" value.
*/ */
typedef struct mbedtls_cipher_info_t { typedef struct mbedtls_cipher_info_t {
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
mbedtls_cipher_type_t MBEDTLS_PRIVATE(type);
/** The cipher mode. For example, MBEDTLS_MODE_CBC. */
mbedtls_cipher_mode_t MBEDTLS_PRIVATE(mode);
/** The cipher key length, in bits. This is the
* default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int MBEDTLS_PRIVATE(key_bitlen);
/** Name of the cipher. */ /** Name of the cipher. */
const char *MBEDTLS_PRIVATE(name); const char *MBEDTLS_PRIVATE(name);
/** IV or nonce size, in Bytes. /** The block size, in bytes. */
unsigned int MBEDTLS_PRIVATE(block_size) : 5;
/** IV or nonce size, in bytes (right shifted by #MBEDTLS_IV_SIZE_SHIFT).
* For ciphers that accept variable IV sizes, * For ciphers that accept variable IV sizes,
* this is the recommended size. * this is the recommended size.
*/ */
unsigned int MBEDTLS_PRIVATE(iv_size); unsigned int MBEDTLS_PRIVATE(iv_size) : 3;
/** The cipher key length, in bits (right shifted by #MBEDTLS_KEY_BITLEN_SHIFT).
* This is the default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int MBEDTLS_PRIVATE(key_bitlen) : 4;
/** The cipher mode (as per mbedtls_cipher_mode_t).
* For example, MBEDTLS_MODE_CBC.
*/
unsigned int MBEDTLS_PRIVATE(mode) : 4;
/** Full cipher identifier (as per mbedtls_cipher_type_t).
* For example, MBEDTLS_CIPHER_AES_256_CBC.
*
* This could be 7 bits, but 8 bits retains byte alignment for the
* next field, which reduces code size to access that field.
*/
unsigned int MBEDTLS_PRIVATE(type) : 8;
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
* cipher supports variable IV or variable key sizes, respectively. * cipher supports variable IV or variable key sizes, respectively.
*/ */
int MBEDTLS_PRIVATE(flags); unsigned int MBEDTLS_PRIVATE(flags) : 2;
/** The block size, in Bytes. */ /** Index to LUT for base cipher information and functions. */
unsigned int MBEDTLS_PRIVATE(block_size); unsigned int MBEDTLS_PRIVATE(base_idx) : 5;
/** Struct for base cipher information and functions. */
const mbedtls_cipher_base_t *MBEDTLS_PRIVATE(base);
} mbedtls_cipher_info_t; } mbedtls_cipher_info_t;
/* For internal use only.
* These are used to more compactly represent the fields above. */
#define MBEDTLS_KEY_BITLEN_SHIFT 6
#define MBEDTLS_IV_SIZE_SHIFT 2
/** /**
* Generic cipher context. * Generic cipher context.
*/ */
@ -353,7 +366,7 @@ typedef struct mbedtls_cipher_context_t {
mbedtls_cmac_context_t *MBEDTLS_PRIVATE(cmac_ctx); mbedtls_cmac_context_t *MBEDTLS_PRIVATE(cmac_ctx);
#endif #endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
/** Indicates whether the cipher operations should be performed /** Indicates whether the cipher operations should be performed
* by Mbed TLS' own crypto library or an external implementation * by Mbed TLS' own crypto library or an external implementation
* of the PSA Crypto API. * of the PSA Crypto API.
@ -362,7 +375,7 @@ typedef struct mbedtls_cipher_context_t {
* mbedtls_cipher_setup_psa(). * mbedtls_cipher_setup_psa().
*/ */
unsigned char MBEDTLS_PRIVATE(psa_enabled); unsigned char MBEDTLS_PRIVATE(psa_enabled);
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
} mbedtls_cipher_context_t; } mbedtls_cipher_context_t;
@ -439,7 +452,7 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type(
if (info == NULL) { if (info == NULL) {
return MBEDTLS_CIPHER_NONE; return MBEDTLS_CIPHER_NONE;
} else { } else {
return info->MBEDTLS_PRIVATE(type); return (mbedtls_cipher_type_t) info->MBEDTLS_PRIVATE(type);
} }
} }
@ -458,7 +471,7 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode(
if (info == NULL) { if (info == NULL) {
return MBEDTLS_MODE_NONE; return MBEDTLS_MODE_NONE;
} else { } else {
return info->MBEDTLS_PRIVATE(mode); return (mbedtls_cipher_mode_t) info->MBEDTLS_PRIVATE(mode);
} }
} }
@ -479,7 +492,7 @@ static inline size_t mbedtls_cipher_info_get_key_bitlen(
if (info == NULL) { if (info == NULL) {
return 0; return 0;
} else { } else {
return info->MBEDTLS_PRIVATE(key_bitlen); return info->MBEDTLS_PRIVATE(key_bitlen) << MBEDTLS_KEY_BITLEN_SHIFT;
} }
} }
@ -492,7 +505,7 @@ static inline size_t mbedtls_cipher_info_get_key_bitlen(
* *
* \return The cipher name, which is a human readable string, * \return The cipher name, which is a human readable string,
* with static storage duration. * with static storage duration.
* \return \c NULL if \c info is \p NULL. * \return \c NULL if \p info is \c NULL.
*/ */
static inline const char *mbedtls_cipher_info_get_name( static inline const char *mbedtls_cipher_info_get_name(
const mbedtls_cipher_info_t *info) const mbedtls_cipher_info_t *info)
@ -521,7 +534,7 @@ static inline size_t mbedtls_cipher_info_get_iv_size(
return 0; return 0;
} }
return (size_t) info->MBEDTLS_PRIVATE(iv_size); return ((size_t) info->MBEDTLS_PRIVATE(iv_size)) << MBEDTLS_IV_SIZE_SHIFT;
} }
/** /**
@ -541,7 +554,7 @@ static inline size_t mbedtls_cipher_info_get_block_size(
return 0; return 0;
} }
return (size_t) info->MBEDTLS_PRIVATE(block_size); return (size_t) (info->MBEDTLS_PRIVATE(block_size));
} }
/** /**
@ -583,7 +596,7 @@ static inline int mbedtls_cipher_info_has_variable_iv_size(
} }
/** /**
* \brief This function initializes a \p cipher_context as NONE. * \brief This function initializes a \p ctx as NONE.
* *
* \param ctx The context to be initialized. This must not be \c NULL. * \param ctx The context to be initialized. This must not be \c NULL.
*/ */
@ -682,7 +695,7 @@ static inline unsigned int mbedtls_cipher_get_block_size(
return 0; return 0;
} }
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size); return (unsigned int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size);
} }
/** /**
@ -702,7 +715,7 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
return MBEDTLS_MODE_NONE; return MBEDTLS_MODE_NONE;
} }
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode); return (mbedtls_cipher_mode_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode);
} }
/** /**
@ -727,7 +740,8 @@ static inline int mbedtls_cipher_get_iv_size(
return (int) ctx->MBEDTLS_PRIVATE(iv_size); return (int) ctx->MBEDTLS_PRIVATE(iv_size);
} }
return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size); return (int) (((int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size)) <<
MBEDTLS_IV_SIZE_SHIFT);
} }
/** /**
@ -747,7 +761,7 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
return MBEDTLS_CIPHER_NONE; return MBEDTLS_CIPHER_NONE;
} }
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type); return (mbedtls_cipher_type_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type);
} }
/** /**
@ -776,7 +790,7 @@ static inline const char *mbedtls_cipher_get_name(
* \param ctx The context of the cipher. This must be initialized. * \param ctx The context of the cipher. This must be initialized.
* *
* \return The key length of the cipher in bits. * \return The key length of the cipher in bits.
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been * \return #MBEDTLS_KEY_LENGTH_NONE if \p ctx has not been
* initialized. * initialized.
*/ */
static inline int mbedtls_cipher_get_key_bitlen( static inline int mbedtls_cipher_get_key_bitlen(
@ -788,7 +802,8 @@ static inline int mbedtls_cipher_get_key_bitlen(
return MBEDTLS_KEY_LENGTH_NONE; return MBEDTLS_KEY_LENGTH_NONE;
} }
return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen); return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen) <<
MBEDTLS_KEY_BITLEN_SHIFT;
} }
/** /**
@ -975,7 +990,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* \param ctx The generic cipher context. This must be initialized and * \param ctx The generic cipher context. This must be initialized and
* bound to a key. * bound to a key.
* \param output The buffer to write data to. This needs to be a writable * \param output The buffer to write data to. This needs to be a writable
* buffer of at least \p block_size Bytes. * buffer of at least block_size Bytes.
* \param olen The length of the data written to the \p output buffer. * \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL. * This may not be \c NULL.
* *

View file

@ -743,10 +743,16 @@ extern "C" {
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
/* Normally we wouldn't enable this because it's not implemented in ecp.c,
* but since it used to be available any time ECP_C was enabled, let's enable
* it anyway for the sake of backwards compatibility */
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
/* See comment for PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE above. */
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 #define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
@ -828,14 +834,16 @@ extern "C" {
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 #define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define PSA_WANT_ALG_RSA_PSS 1 #define PSA_WANT_ALG_RSA_PSS 1
#endif /* MBEDTLS_PKCS1_V21 */ #endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_GENPRIME)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#endif /* MBEDTLS_GENPRIME */
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 #define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 #define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 #define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 #define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
#endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_RSA_C */
@ -1003,54 +1011,46 @@ extern "C" {
#define PSA_WANT_ALG_SOME_PAKE 1 #define PSA_WANT_ALG_SOME_PAKE 1
#endif #endif
/* Temporary internal migration helpers */ /* Even though KEY_PAIR symbols' feature several level of support (BASIC, IMPORT,
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ * EXPORT, GENERATE, DERIVE) we're not planning to have support only for BASIC
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ * without IMPORT/EXPORT since these last 2 features are strongly used in tests.
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ * In general it is allowed to include more feature than what is strictly
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \ * requested.
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) * As a consequence IMPORT and EXPORT features will be automatically enabled
#define MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY * as soon as the BASIC one is. */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#endif #endif
/* Temporary internal migration helpers */ /* See description above */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY
#endif #endif
/* Temporary internal migration helpers */ /* See description above */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) || \ #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ #define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ #define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY
#endif #endif
/* Temporary internal migration helpers */ /* See description above */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC)
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_LEGACY
#endif #endif
/* Temporary internal migration helpers */ /* See description above */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \ #if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \ #define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \ #define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY
#endif #endif
/* Temporary internal migration helpers */ /* See description above */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC) || \ #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC)
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \ #define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY
#endif #endif
/* These features are always enabled. */ /* These features are always enabled. */

View file

@ -280,7 +280,10 @@ void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
const char *text, const mbedtls_x509_crt *crt); const char *text, const mbedtls_x509_crt *crt);
#endif #endif
#if defined(MBEDTLS_ECDH_C) /* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function
only works for the built-in implementation. */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
defined(MBEDTLS_ECDH_C)
typedef enum { typedef enum {
MBEDTLS_DEBUG_ECDH_Q, MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP, MBEDTLS_DEBUG_ECDH_QP,
@ -307,7 +310,8 @@ void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const mbedtls_ecdh_context *ecdh, const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr); mbedtls_debug_ecdh_attr attr);
#endif #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -325,7 +325,7 @@ size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx);
* initialized. * initialized.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_DHM_BAD_INPUT_DATA if \p field is invalid. * \return #MBEDTLS_ERR_DHM_BAD_INPUT_DATA if \p param is invalid.
* \return An \c MBEDTLS_ERR_MPI_XXX error code if the copy fails. * \return An \c MBEDTLS_ERR_MPI_XXX error code if the copy fails.
*/ */
int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx, int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,

View file

@ -207,8 +207,9 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
* \param md_alg The hash algorithm used to hash the original data. * \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be * \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL. * \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This
* \c NULL if \p f_rng doesn't need a context parameter. * may be \c NULL if \p f_rng_blind doesn't need a context
* parameter.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
@ -326,8 +327,8 @@ int mbedtls_ecdsa_sign_restartable(
* \param md_alg The hash algorithm used to hash the original data. * \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be * \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL. * \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be
* \c NULL if \p f_rng doesn't need a context parameter. * \c NULL if \p f_rng_blind doesn't need a context parameter.
* \param rs_ctx The restart context to use. This may be \c NULL * \param rs_ctx The restart context to use. This may be \c NULL
* to disable restarting. If it is not \c NULL, it * to disable restarting. If it is not \c NULL, it
* must point to an initialized restart context. * must point to an initialized restart context.
@ -459,7 +460,7 @@ int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message. * \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable * \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes. * buffer of length \p hlen Bytes.
* \param hlen The length of the hash \p hash in Bytes. * \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a * \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the * writable buffer of length at least twice as large as the
@ -502,7 +503,7 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message. * \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable * \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes. * buffer of length \p hlen Bytes.
* \param hlen The length of the hash \p hash in Bytes. * \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a * \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the * writable buffer of length at least twice as large as the
@ -549,7 +550,7 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
* \param ctx The ECDSA context to use. This must be initialized * \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it. * and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable * \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes. * buffer of length \p hlen Bytes.
* \param hlen The size of the hash \p hash. * \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable * \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes. * buffer of length \p slen Bytes.
@ -579,7 +580,7 @@ int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
* \param ctx The ECDSA context to use. This must be initialized * \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it. * and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable * \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes. * buffer of length \p hlen Bytes.
* \param hlen The size of the hash \p hash. * \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable * \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes. * buffer of length \p slen Bytes.

View file

@ -1083,7 +1083,7 @@ int mbedtls_ecp_muladd_restartable(
* *
* It only checks that the point is non-zero, has * It only checks that the point is non-zero, has
* valid coordinates and lies on the curve. It does not verify * valid coordinates and lies on the curve. It does not verify
* that it is indeed a multiple of \p G. This additional * that it is indeed a multiple of \c G. This additional
* check is computationally more expensive, is not required * check is computationally more expensive, is not required
* by standards, and should not be necessary if the group * by standards, and should not be necessary if the group
* used has a small cofactor. In particular, it is useless for * used has a small cofactor. In particular, it is useless for
@ -1108,7 +1108,7 @@ int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *pt); const mbedtls_ecp_point *pt);
/** /**
* \brief This function checks that an \p mbedtls_mpi is a * \brief This function checks that an \c mbedtls_mpi is a
* valid private key for this curve. * valid private key for this curve.
* *
* \note This function uses bare components rather than an * \note This function uses bare components rather than an

View file

@ -183,8 +183,8 @@ void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx);
* \param len The length of the personalization string. * \param len The length of the personalization string.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most * and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len * 3 / 2
* where \p entropy_len is the entropy length * where \c entropy_len is the entropy length
* described above. * described above.
* *
* \return \c 0 if successful. * \return \c 0 if successful.
@ -313,8 +313,8 @@ int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
* \param len The length of the additional data. * \param len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most * and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \p entropy_len is the entropy length * where \c entropy_len is the entropy length
* (see mbedtls_hmac_drbg_set_entropy_len()). * (see mbedtls_hmac_drbg_set_entropy_len()).
* *
* \return \c 0 if successful. * \return \c 0 if successful.

View file

@ -1283,8 +1283,8 @@
* ); * );
* ``` * ```
* The \c context value is initialized to 0 before the first call. * The \c context value is initialized to 0 before the first call.
* The function must fill the \c output buffer with \p output_size bytes * The function must fill the \c output buffer with \c output_size bytes
* of random data and set \c *output_length to \p output_size. * of random data and set \c *output_length to \c output_size.
* *
* Requires: MBEDTLS_PSA_CRYPTO_C * Requires: MBEDTLS_PSA_CRYPTO_C
* *
@ -1671,7 +1671,7 @@
* *
* Enable TLS 1.3 ephemeral key exchange mode. * Enable TLS 1.3 ephemeral key exchange mode.
* *
* Requires: PSA_WANT_ALG_ECDH * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH
* MBEDTLS_X509_CRT_PARSE_C * MBEDTLS_X509_CRT_PARSE_C
* and at least one of: * and at least one of:
* MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA)
@ -1689,7 +1689,7 @@
* *
* Enable TLS 1.3 PSK ephemeral key exchange mode. * Enable TLS 1.3 PSK ephemeral key exchange mode.
* *
* Requires: PSA_WANT_ALG_ECDH * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH
* *
* Comment to disable support for the PSK ephemeral key exchange mode in * Comment to disable support for the PSK ephemeral key exchange mode in
* TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not * TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not
@ -2113,7 +2113,10 @@
* the CPU when this option is enabled. * the CPU when this option is enabled.
* *
* \note Minimum compiler versions for this feature are Clang 4.0, * \note Minimum compiler versions for this feature are Clang 4.0,
* GCC 6.0 or MSVC 2019 version 16.11.2. * armclang 6.6, GCC 6.0 or MSVC 2019 version 16.11.2.
*
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
* armclang <= 6.9
* *
* This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems. * This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems.
*/ */
@ -3130,6 +3133,12 @@
* \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building
* for a non-Aarch64 build it will be silently ignored. * for a non-Aarch64 build it will be silently ignored.
* *
* \note Minimum compiler versions for this feature are Clang 4.0,
* armclang 6.6 or GCC 6.0.
*
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
* armclang <= 6.9
*
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the
* same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. * same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY.
* *
@ -3152,6 +3161,12 @@
* \note This allows builds with a smaller code size than with * \note This allows builds with a smaller code size than with
* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
* *
* \note Minimum compiler versions for this feature are Clang 4.0,
* armclang 6.6 or GCC 6.0.
*
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
* armclang <= 6.9
*
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same
* time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. * time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT.
* *
@ -3216,8 +3231,11 @@
* \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building
* for a non-Aarch64 build it will be silently ignored. * for a non-Aarch64 build it will be silently ignored.
* *
* \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or * \note Minimum compiler versions for this feature are Clang 7.0,
* Clang >= 7. * armclang 6.9 or GCC 8.0.
*
* \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for
* armclang 6.9
* *
* \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the
* same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY.
@ -3241,8 +3259,11 @@
* \note This allows builds with a smaller code size than with * \note This allows builds with a smaller code size than with
* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
* *
* \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or * \note Minimum compiler versions for this feature are Clang 7.0,
* Clang >= 7. * armclang 6.9 or GCC 8.0.
*
* \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for
* armclang 6.9
* *
* \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same
* time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT.
@ -3760,6 +3781,9 @@
*/ */
//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 //#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
/* RSA OPTIONS */
#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 /**< Minimum RSA key size that can be generated in bits (Minimum possible value is 128 bits) */
/* SSL Cache options */ /* SSL Cache options */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
@ -3976,4 +4000,13 @@
*/ */
//#define MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED //#define MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
/**
* Uncomment to enable using new bignum code in the ECC modules.
*
* \warning This is currently experimental, incomplete and therefore should not
* be used in production.
*/
//#define MBEDTLS_ECP_WITH_MPI_UINT
/** \} name SECTION: Module configuration options */ /** \} name SECTION: Module configuration options */

View file

@ -146,19 +146,22 @@ extern "C" {
* stronger message digests instead. * stronger message digests instead.
* *
*/ */
/* Note: these are aligned with the definitions of PSA_ALG_ macros for hashes,
* in order to enable an efficient implementation of conversion functions.
* This is tested by md_to_from_psa() in test_suite_md. */
typedef enum { typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */ MBEDTLS_MD_NONE=0, /**< None. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */ MBEDTLS_MD_MD5=0x03, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */ MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */ MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */ MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */
MBEDTLS_MD_SHA3_224, /**< The SHA3-224 message digest. */ MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */
MBEDTLS_MD_SHA3_256, /**< The SHA3-256 message digest. */ MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */
MBEDTLS_MD_SHA3_384, /**< The SHA3-384 message digest. */ MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */
MBEDTLS_MD_SHA3_512, /**< The SHA3-512 message digest. */ MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */
} mbedtls_md_type_t; } mbedtls_md_type_t;
/* Note: this should always be >= PSA_HASH_MAX_SIZE /* Note: this should always be >= PSA_HASH_MAX_SIZE
@ -464,8 +467,8 @@ const int *mbedtls_md_list(void);
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name); const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
/** /**
* \brief This function extracts the message-digest name from the * \brief This function returns the name of the message digest for
* message-digest information structure. * the message-digest information structure given.
* *
* \param md_info The information structure of the message-digest algorithm * \param md_info The information structure of the message-digest algorithm
* to use. * to use.

View file

@ -171,37 +171,6 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#endif #endif
#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */ #endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
/**
* \brief The following defines are meant to list ECDSA capabilities of the
* PK module in a general way (without any reference to how this
* is achieved, which can be either through PSA driver or
* MBEDTLS_ECDSA_C)
*/
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(PSA_WANT_ALG_ECDSA)
#if defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#endif /* PSA_WANT_ALG_ECDSA */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \
(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C))
#define MBEDTLS_PK_CAN_ECDH
#endif
/* Internal helper to define which fields in the pk_context structure below /* Internal helper to define which fields in the pk_context structure below
* should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly) * should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
* format. It should be noticed that this only affect how data is stored, not * format. It should be noticed that this only affect how data is stored, not
@ -552,7 +521,7 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
* *
* \return 0 on success (signature is valid), * \return 0 on success (signature is valid),
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen, * signature in \p sig but its length is less than \p sig_len,
* or a specific error code. * or a specific error code.
* *
* \note For RSA keys, the default padding type is PKCS#1 v1.5. * \note For RSA keys, the default padding type is PKCS#1 v1.5.
@ -606,7 +575,7 @@ int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be * #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
* used for this type of signatures, * used for this type of signatures,
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen, * signature in \p sig but its length is less than \p sig_len,
* or a specific error code. * or a specific error code.
* *
* \note If hash_len is 0, then the length associated with md_alg * \note If hash_len is 0, then the length associated with md_alg

View file

@ -2,9 +2,6 @@
* \file psa_util.h * \file psa_util.h
* *
* \brief Utility functions for the use of the PSA Crypto library. * \brief Utility functions for the use of the PSA Crypto library.
*
* \warning This function is not part of the public API and may
* change at any time.
*/ */
/* /*
* Copyright The Mbed TLS Contributors * Copyright The Mbed TLS Contributors
@ -29,212 +26,8 @@
#include "mbedtls/build_info.h" #include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include "psa/crypto.h"
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
#include "mbedtls/pk.h"
#include "mbedtls/oid.h"
#include "mbedtls/error.h"
#include <string.h>
/* Translations for symmetric crypto. */
static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
mbedtls_cipher_type_t cipher)
{
switch (cipher) {
case MBEDTLS_CIPHER_AES_128_CCM:
case MBEDTLS_CIPHER_AES_192_CCM:
case MBEDTLS_CIPHER_AES_256_CCM:
case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_128_GCM:
case MBEDTLS_CIPHER_AES_192_GCM:
case MBEDTLS_CIPHER_AES_256_GCM:
case MBEDTLS_CIPHER_AES_128_CBC:
case MBEDTLS_CIPHER_AES_192_CBC:
case MBEDTLS_CIPHER_AES_256_CBC:
case MBEDTLS_CIPHER_AES_128_ECB:
case MBEDTLS_CIPHER_AES_192_ECB:
case MBEDTLS_CIPHER_AES_256_ECB:
return PSA_KEY_TYPE_AES;
/* ARIA not yet supported in PSA. */
/* case MBEDTLS_CIPHER_ARIA_128_CCM:
case MBEDTLS_CIPHER_ARIA_192_CCM:
case MBEDTLS_CIPHER_ARIA_256_CCM:
case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_128_GCM:
case MBEDTLS_CIPHER_ARIA_192_GCM:
case MBEDTLS_CIPHER_ARIA_256_GCM:
case MBEDTLS_CIPHER_ARIA_128_CBC:
case MBEDTLS_CIPHER_ARIA_192_CBC:
case MBEDTLS_CIPHER_ARIA_256_CBC:
return( PSA_KEY_TYPE_ARIA ); */
default:
return 0;
}
}
static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
mbedtls_cipher_mode_t mode, size_t taglen)
{
switch (mode) {
case MBEDTLS_MODE_ECB:
return PSA_ALG_ECB_NO_PADDING;
case MBEDTLS_MODE_GCM:
return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);
case MBEDTLS_MODE_CCM:
return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);
case MBEDTLS_MODE_CCM_STAR_NO_TAG:
return PSA_ALG_CCM_STAR_NO_TAG;
case MBEDTLS_MODE_CBC:
if (taglen == 0) {
return PSA_ALG_CBC_NO_PADDING;
} else {
return 0;
}
default:
return 0;
}
}
static inline psa_key_usage_t mbedtls_psa_translate_cipher_operation(
mbedtls_operation_t op)
{
switch (op) {
case MBEDTLS_ENCRYPT:
return PSA_KEY_USAGE_ENCRYPT;
case MBEDTLS_DECRYPT:
return PSA_KEY_USAGE_DECRYPT;
default:
return 0;
}
}
/* Translations for ECC. */
static inline int mbedtls_psa_get_ecc_oid_from_id(
psa_ecc_family_t curve, size_t bits,
char const **oid, size_t *oid_len)
{
switch (curve) {
case PSA_ECC_FAMILY_SECP_R1:
switch (bits) {
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
case 192:
*oid = MBEDTLS_OID_EC_GRP_SECP192R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP192R1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
case 224:
*oid = MBEDTLS_OID_EC_GRP_SECP224R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP224R1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_SECP256R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP256R1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
case 384:
*oid = MBEDTLS_OID_EC_GRP_SECP384R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP384R1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
case 521:
*oid = MBEDTLS_OID_EC_GRP_SECP521R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP521R1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
}
break;
case PSA_ECC_FAMILY_SECP_K1:
switch (bits) {
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
case 192:
*oid = MBEDTLS_OID_EC_GRP_SECP192K1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP192K1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
case 224:
*oid = MBEDTLS_OID_EC_GRP_SECP224K1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP224K1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_SECP256K1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_SECP256K1);
return 0;
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
}
break;
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
switch (bits) {
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_BP256R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_BP256R1);
return 0;
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
case 384:
*oid = MBEDTLS_OID_EC_GRP_BP384R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_BP384R1);
return 0;
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
case 512:
*oid = MBEDTLS_OID_EC_GRP_BP512R1;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_EC_GRP_BP512R1);
return 0;
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
}
break;
case PSA_ECC_FAMILY_MONTGOMERY:
switch (bits) {
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
case 255:
*oid = MBEDTLS_OID_X25519;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_X25519);
return 0;
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
case 448:
*oid = MBEDTLS_OID_X448;
*oid_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_X448);
return 0;
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
}
break;
}
(void) oid;
(void) oid_len;
return -1;
}
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
#define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
/* Expose whatever RNG the PSA subsystem uses to applications using the /* Expose whatever RNG the PSA subsystem uses to applications using the
* mbedtls_xxx API. The declarations and definitions here need to be * mbedtls_xxx API. The declarations and definitions here need to be
* consistent with the implementation in library/psa_crypto_random_impl.h. * consistent with the implementation in library/psa_crypto_random_impl.h.
@ -319,58 +112,5 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ #endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
typedef struct {
/* Error codes used by PSA crypto are in -255..-128, fitting in 16 bits. */
int16_t psa_status;
/* Error codes used by Mbed TLS are in one of the ranges
* -127..-1 (low-level) or -32767..-4096 (high-level with a low-level
* code optionally added), fitting in 16 bits. */
int16_t mbedtls_error;
} mbedtls_error_pair_t;
#if defined(MBEDTLS_MD_LIGHT)
extern const mbedtls_error_pair_t psa_to_md_errors[4];
#endif
#if defined(MBEDTLS_LMS_C)
extern const mbedtls_error_pair_t psa_to_lms_errors[3];
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
extern const mbedtls_error_pair_t psa_to_ssl_errors[7];
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
extern const mbedtls_error_pair_t psa_to_pk_rsa_errors[8];
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
extern const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[7];
#endif
/* Generic fallback function for error translation,
* when the received state was not module-specific. */
int psa_generic_status_to_mbedtls(psa_status_t status);
/* This function iterates over provided local error translations,
* and if no match was found - calls the fallback error translation function. */
int psa_status_to_mbedtls(psa_status_t status,
const mbedtls_error_pair_t *local_translations,
size_t local_errors_num,
int (*fallback_f)(psa_status_t));
/* The second out of three-stage error handling functions of the pk module,
* acts as a fallback after RSA / ECDSA error translation, and if no match
* is found, it itself calls psa_generic_status_to_mbedtls. */
int psa_pk_status_to_mbedtls(psa_status_t status);
/* Utility macro to shorten the defines of error translator in modules. */
#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \
psa_status_to_mbedtls(status, error_list, \
sizeof(error_list)/sizeof(error_list[0]), \
fallback_f)
#endif /* MBEDTLS_PSA_CRYPTO_C */ #endif /* MBEDTLS_PSA_CRYPTO_C */
#endif /* MBEDTLS_PSA_UTIL_H */ #endif /* MBEDTLS_PSA_UTIL_H */

View file

@ -85,6 +85,12 @@ extern "C" {
// Regular implementation // Regular implementation
// //
#if !defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS)
#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024
#elif MBEDTLS_RSA_GEN_KEY_MIN_BITS < 128
#error "MBEDTLS_RSA_GEN_KEY_MIN_BITS must be at least 128 bits"
#endif
/** /**
* \brief The RSA context structure. * \brief The RSA context structure.
*/ */
@ -282,15 +288,15 @@ int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx,
* \brief This function completes an RSA context from * \brief This function completes an RSA context from
* a set of imported core parameters. * a set of imported core parameters.
* *
* To setup an RSA public key, precisely \p N and \p E * To setup an RSA public key, precisely \c N and \c E
* must have been imported. * must have been imported.
* *
* To setup an RSA private key, sufficient information must * To setup an RSA private key, sufficient information must
* be present for the other parameters to be derivable. * be present for the other parameters to be derivable.
* *
* The default implementation supports the following: * The default implementation supports the following:
* <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li> * <ul><li>Derive \c P, \c Q from \c N, \c D, \c E.</li>
* <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul> * <li>Derive \c N, \c D from \c P, \c Q, \c E.</li></ul>
* Alternative implementations need not support these. * Alternative implementations need not support these.
* *
* If this function runs successfully, it guarantees that * If this function runs successfully, it guarantees that
@ -547,7 +553,7 @@ int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub,
* \note This function does not handle message padding. * \note This function does not handle message padding.
* *
* \note Make sure to set \p input[0] = 0 or ensure that * \note Make sure to set \p input[0] = 0 or ensure that
* input is smaller than \p N. * input is smaller than \c N.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
@ -984,8 +990,8 @@ int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
* verification. * verification.
* *
* \note For PKCS#1 v2.1 encoding, see comments on * \note For PKCS#1 v2.1 encoding, see comments on
* mbedtls_rsa_rsassa_pss_verify() about \p md_alg and * mbedtls_rsa_rsassa_pss_verify() about \c md_alg and
* \p hash_id. * \c hash_id.
* *
* \param ctx The initialized RSA public key context to use. * \param ctx The initialized RSA public key context to use.
* \param md_alg The message-digest algorithm used to hash the original data. * \param md_alg The message-digest algorithm used to hash the original data.

View file

@ -42,7 +42,7 @@
#include "mbedtls/md.h" #include "mbedtls/md.h"
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED)
#include "mbedtls/ecdh.h" #include "mbedtls/ecdh.h"
#endif #endif
@ -619,6 +619,7 @@
/* Dummy type used only for its size */ /* Dummy type used only for its size */
union mbedtls_ssl_premaster_secret { union mbedtls_ssl_premaster_secret {
unsigned char dummy; /* Make the union non-empty even with SSL disabled */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */
#endif #endif
@ -1486,7 +1487,7 @@ struct mbedtls_ssl_config {
const uint16_t *MBEDTLS_PRIVATE(sig_algs); /*!< allowed signature algorithms */ const uint16_t *MBEDTLS_PRIVATE(sig_algs); /*!< allowed signature algorithms */
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECP_LIGHT) && !defined(MBEDTLS_DEPRECATED_REMOVED) #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_DEPRECATED_REMOVED)
const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */ const mbedtls_ecp_group_id *MBEDTLS_PRIVATE(curve_list); /*!< allowed curves */
#endif #endif
@ -1918,6 +1919,19 @@ int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl);
*/ */
void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint); void mbedtls_ssl_conf_endpoint(mbedtls_ssl_config *conf, int endpoint);
/**
* \brief Get the current endpoint type
*
* \param conf SSL configuration
*
* \return Endpoint type, either MBEDTLS_SSL_IS_CLIENT
* or MBEDTLS_SSL_IS_SERVER
*/
static inline int mbedtls_ssl_conf_get_endpoint(const mbedtls_ssl_config *conf)
{
return conf->MBEDTLS_PRIVATE(endpoint);
}
/** /**
* \brief Set the transport type (TLS or DTLS). * \brief Set the transport type (TLS or DTLS).
* Default: TLS * Default: TLS
@ -2157,10 +2171,10 @@ void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl,
* \param own_cid The address of the readable buffer holding the CID we want * \param own_cid The address of the readable buffer holding the CID we want
* the peer to use when sending encrypted messages to us. * the peer to use when sending encrypted messages to us.
* This may be \c NULL if \p own_cid_len is \c 0. * This may be \c NULL if \p own_cid_len is \c 0.
* This parameter is unused if \p enabled is set to * This parameter is unused if \p enable is set to
* MBEDTLS_SSL_CID_DISABLED. * MBEDTLS_SSL_CID_DISABLED.
* \param own_cid_len The length of \p own_cid. * \param own_cid_len The length of \p own_cid.
* This parameter is unused if \p enabled is set to * This parameter is unused if \p enable is set to
* MBEDTLS_SSL_CID_DISABLED. * MBEDTLS_SSL_CID_DISABLED.
* *
* \note The value of \p own_cid_len must match the value of the * \note The value of \p own_cid_len must match the value of the
@ -3111,8 +3125,8 @@ int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
* *
* \param session The session structure to be saved. * \param session The session structure to be saved.
* \param buf The buffer to write the serialized data to. It must be a * \param buf The buffer to write the serialized data to. It must be a
* writeable buffer of at least \p len bytes, or may be \c * writeable buffer of at least \p buf_len bytes, or may be \c
* NULL if \p len is \c 0. * NULL if \p buf_len is \c 0.
* \param buf_len The number of bytes available for writing in \p buf. * \param buf_len The number of bytes available for writing in \p buf.
* \param olen The size in bytes of the data that has been or would have * \param olen The size in bytes of the data that has been or would have
* been written. It must point to a valid \c size_t. * been written. It must point to a valid \c size_t.
@ -3253,7 +3267,7 @@ void mbedtls_ssl_conf_tls13_key_exchange_modes(mbedtls_ssl_config *conf,
* record headers. * record headers.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p len
* is too large. * is too large.
*/ */
int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf, size_t len, int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf, size_t len,
@ -3621,7 +3635,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
unsigned int bitlen); unsigned int bitlen);
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_ECP_LIGHT) #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#if !defined(MBEDTLS_DEPRECATED_REMOVED) #if !defined(MBEDTLS_DEPRECATED_REMOVED)
/** /**
* \brief Set the allowed curves in order of preference. * \brief Set the allowed curves in order of preference.
@ -3667,7 +3681,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen(mbedtls_ssl_config *conf,
void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf, void MBEDTLS_DEPRECATED mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
const mbedtls_ecp_group_id *curves); const mbedtls_ecp_group_id *curves);
#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECP_LIGHT */ #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
/** /**
* \brief Set the allowed groups in order of preference. * \brief Set the allowed groups in order of preference.
@ -3777,13 +3791,28 @@ void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
* On too long input failure, old hostname is unchanged. * On too long input failure, old hostname is unchanged.
*/ */
int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname); int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname);
/**
* \brief Get the hostname that checked against the received
* server certificate. It is used to set the ServerName
* TLS extension, too, if that extension is enabled.
* (client-side only)
*
* \param ssl SSL context
*
* \return const pointer to the hostname value
*/
static inline const char *mbedtls_ssl_get_hostname(mbedtls_ssl_context *ssl)
{
return ssl->MBEDTLS_PRIVATE(hostname);
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/** /**
* \brief Retrieve SNI extension value for the current handshake. * \brief Retrieve SNI extension value for the current handshake.
* Available in \p f_cert_cb of \c mbedtls_ssl_conf_cert_cb(), * Available in \c f_cert_cb of \c mbedtls_ssl_conf_cert_cb(),
* this is the same value passed to \p f_sni callback of * this is the same value passed to \c f_sni callback of
* \c mbedtls_ssl_conf_sni() and may be used instead of * \c mbedtls_ssl_conf_sni() and may be used instead of
* \c mbedtls_ssl_conf_sni(). * \c mbedtls_ssl_conf_sni().
* *
@ -3792,10 +3821,10 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname);
* 0 if SNI extension is not present or not yet processed. * 0 if SNI extension is not present or not yet processed.
* *
* \return const pointer to SNI extension value. * \return const pointer to SNI extension value.
* - value is valid only when called in \p f_cert_cb * - value is valid only when called in \c f_cert_cb
* registered with \c mbedtls_ssl_conf_cert_cb(). * registered with \c mbedtls_ssl_conf_cert_cb().
* - value is NULL if SNI extension is not present. * - value is NULL if SNI extension is not present.
* - value is not '\0'-terminated. Use \c name_len for len. * - value is not '\0'-terminated. Use \c name_len for len.
* - value must not be freed. * - value must not be freed.
*/ */
const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl, const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl,
@ -4088,7 +4117,7 @@ void MBEDTLS_DEPRECATED mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, i
* negotiated. * negotiated.
* *
* \param conf SSL configuration * \param conf SSL configuration
* \param tls_version TLS protocol version number (\p mbedtls_ssl_protocol_version) * \param tls_version TLS protocol version number (\c mbedtls_ssl_protocol_version)
* (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid)
*/ */
static inline void mbedtls_ssl_conf_max_tls_version(mbedtls_ssl_config *conf, static inline void mbedtls_ssl_conf_max_tls_version(mbedtls_ssl_config *conf,
@ -4145,7 +4174,7 @@ void MBEDTLS_DEPRECATED mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, i
* negotiated. * negotiated.
* *
* \param conf SSL configuration * \param conf SSL configuration
* \param tls_version TLS protocol version number (\p mbedtls_ssl_protocol_version) * \param tls_version TLS protocol version number (\c mbedtls_ssl_protocol_version)
* (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid)
*/ */
static inline void mbedtls_ssl_conf_min_tls_version(mbedtls_ssl_config *conf, static inline void mbedtls_ssl_conf_min_tls_version(mbedtls_ssl_config *conf,

View file

@ -137,7 +137,7 @@ int mbedtls_ssl_cache_set(void *data,
* *
* \param data The SSL cache context to use. * \param data The SSL cache context to use.
* \param session_id The pointer to the buffer holding the session ID * \param session_id The pointer to the buffer holding the session ID
* associated to \p session. * associated to session.
* \param session_id_len The length of \p session_id in bytes. * \param session_id_len The length of \p session_id in bytes.
* *
* \return \c 0 on success. This indicates the cache entry for * \return \c 0 on success. This indicates the cache entry for
@ -160,6 +160,20 @@ int mbedtls_ssl_cache_remove(void *data,
* \param timeout cache entry timeout in seconds * \param timeout cache entry timeout in seconds
*/ */
void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout); void mbedtls_ssl_cache_set_timeout(mbedtls_ssl_cache_context *cache, int timeout);
/**
* \brief Get the cache timeout
*
* A timeout of 0 indicates no timeout.
*
* \param cache SSL cache context
*
* \return cache entry timeout in seconds
*/
static inline int mbedtls_ssl_cache_get_timeout(mbedtls_ssl_cache_context *cache)
{
return cache->MBEDTLS_PRIVATE(timeout);
}
#endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_HAVE_TIME */
/** /**

View file

@ -346,11 +346,6 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED #define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#define MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED
#endif
/* Key exchanges using DHE */ /* Key exchanges using DHE */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
@ -364,6 +359,62 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED #define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED
#endif #endif
/* TLS 1.2 key exchanges using ECDH or ECDHE*/
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED
#endif
/* TLS 1.3 PSK key exchanges */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED
#endif
/* TLS 1.2 or 1.3 key exchanges with PSK */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
#define MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED
#endif
/* TLS 1.3 ephemeral key exchanges */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED
#endif
/* TLS 1.3 key exchanges using ECDHE */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
defined(PSA_WANT_ALG_ECDH)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_ECDHE_ENABLED
#endif
/* TLS 1.2 or 1.3 key exchanges using ECDH or ECDHE */
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_ECDHE_ENABLED)
#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED
#endif
/* TLS 1.2 XXDH key exchanges: ECDH or ECDHE or FFDH */
#if (defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED))
#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_1_2_ENABLED
#endif
/* The handshake params structure has a set of fields called xxdh_psa which are used:
* - by TLS 1.2 with `USE_PSA` to do ECDH or ECDHE;
* - by TLS 1.3 to do ECDHE or FFDHE.
* The following macros can be used to guard their declaration and use.
*/
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_1_2_ENABLED
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_1_2_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
#define MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED
#endif
typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ #define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */

View file

@ -366,6 +366,31 @@ static inline mbedtls_x509_name *mbedtls_x509_dn_get_next(
*/ */
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial); 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 * \brief Check a given mbedtls_x509_time against the system time
* and tell if it's in the past. * and tell if it's in the past.
@ -404,7 +429,7 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
* \param san_buf The buffer holding the raw data item of the subject * \param san_buf The buffer holding the raw data item of the subject
* alternative name. * alternative name.
* \param san The target structure to populate with the parsed presentation * \param san The target structure to populate with the parsed presentation
* of the subject alternative name encoded in \p san_raw. * of the subject alternative name encoded in \p san_buf.
* *
* \note Supported GeneralName types, as defined in RFC 5280: * \note Supported GeneralName types, as defined in RFC 5280:
* "rfc822Name", "dnsName", "directoryName", * "rfc822Name", "dnsName", "directoryName",
@ -414,7 +439,7 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
* \note This function should be called on a single raw data of * \note This function should be called on a single raw data of
* subject alternative name. For example, after successful * subject alternative name. For example, after successful
* certificate parsing, one must iterate on every item in the * certificate parsing, one must iterate on every item in the
* \p crt->subject_alt_names sequence, and pass it to * \c crt->subject_alt_names sequence, and pass it to
* this function. * this function.
* *
* \warning The target structure contains pointers to the raw data of the * \warning The target structure contains pointers to the raw data of the

View file

@ -4407,9 +4407,9 @@ psa_status_t psa_sign_hash_start(
* \retval #PSA_ERROR_BUFFER_TOO_SMALL * \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can * The size of the \p signature buffer is too small. You can
* determine a sufficient buffer size by calling * determine a sufficient buffer size by calling
* #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \c alg)
* where \c key_type and \c key_bits are the type and bit-size * where \c key_type and \c key_bits are the type and bit-size
* respectively of \p key. * respectively of \c key.
* *
* \retval #PSA_ERROR_BAD_STATE * \retval #PSA_ERROR_BAD_STATE
* An operation was not previously started on this context via * An operation was not previously started on this context via

View file

@ -94,7 +94,8 @@ typedef struct {
defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
#define MBEDTLS_PSA_BUILTIN_CIPHER 1 #define MBEDTLS_PSA_BUILTIN_CIPHER 1
#endif #endif

View file

@ -1036,12 +1036,12 @@ typedef uint32_t psa_pake_primitive_t;
* (value of type ::psa_pake_primitive_type_t). * (value of type ::psa_pake_primitive_type_t).
* \param pake_family The family of the primitive * \param pake_family The family of the primitive
* (the type and interpretation of this parameter depends * (the type and interpretation of this parameter depends
* on \p type, for more information consult the * on \p pake_type, for more information consult the
* documentation of individual ::psa_pake_primitive_type_t * documentation of individual ::psa_pake_primitive_type_t
* constants). * constants).
* \param pake_bits The bit-size of the primitive * \param pake_bits The bit-size of the primitive
* (Value of type \c size_t. The interpretation * (Value of type \c size_t. The interpretation
* of this parameter depends on \p family, for more * of this parameter depends on \p pake_family, for more
* information consult the documentation of individual * information consult the documentation of individual
* ::psa_pake_primitive_type_t constants). * ::psa_pake_primitive_type_t constants).
* *
@ -1545,7 +1545,7 @@ psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
* \retval #PSA_SUCCESS * \retval #PSA_SUCCESS
* Success. * Success.
* \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INVALID_ARGUMENT
* \p user_id is not valid for the \p operation's algorithm and cipher * \p peer_id is not valid for the \p operation's algorithm and cipher
* suite. * suite.
* \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_NOT_SUPPORTED
* The algorithm doesn't associate a second identity with the session. * The algorithm doesn't associate a second identity with the session.
@ -1627,8 +1627,8 @@ psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
* \c PSA_PAKE_STEP_XXX constants for more * \c PSA_PAKE_STEP_XXX constants for more
* information. * information.
* \param output_size Size of the \p output buffer in bytes. This must * \param output_size Size of the \p output buffer in bytes. This must
* be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p * be at least #PSA_PAKE_OUTPUT_SIZE(\c alg, \c
* primitive, \p step) where \p alg and * primitive, \p output_step) where \c alg and
* \p primitive are the PAKE algorithm and primitive * \p primitive are the PAKE algorithm and primitive
* in the operation's cipher suite, and \p step is * in the operation's cipher suite, and \p step is
* the output step. * the output step.
@ -1693,9 +1693,9 @@ psa_status_t psa_pake_output(psa_pake_operation_t *operation,
* \retval #PSA_ERROR_INVALID_SIGNATURE * \retval #PSA_ERROR_INVALID_SIGNATURE
* The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step. * The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step.
* \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INVALID_ARGUMENT
* \p is not compatible with the \p operations algorithm, or the * \p input_length is not compatible with the \p operations algorithm,
* \p input is not valid for the \p operation's algorithm, cipher suite * or the \p input is not valid for the \p operation's algorithm,
* or \p step. * cipher suite or \p step.
* \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_NOT_SUPPORTED
* \p step p is not supported with the \p operation's algorithm, or the * \p step p is not supported with the \p operation's algorithm, or the
* \p input is not supported for the \p operation's algorithm, cipher * \p input is not supported for the \p operation's algorithm, cipher
@ -1744,7 +1744,7 @@ psa_status_t psa_pake_input(psa_pake_operation_t *operation,
* *
* When this function returns successfully, \p operation becomes inactive. * When this function returns successfully, \p operation becomes inactive.
* If this function returns an error status, both \p operation * If this function returns an error status, both \p operation
* and \p key_derivation operations enter an error state and must be aborted by * and \c key_derivation operations enter an error state and must be aborted by
* calling psa_pake_abort() and psa_key_derivation_abort() respectively. * calling psa_pake_abort() and psa_key_derivation_abort() respectively.
* *
* \param[in,out] operation Active PAKE operation. * \param[in,out] operation Active PAKE operation.
@ -1877,7 +1877,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
* The value of this macro must be at least as large as the largest value * The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_OUTPUT_SIZE() * returned by PSA_PAKE_OUTPUT_SIZE()
* *
* See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p step). * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
*/ */
#define PSA_PAKE_OUTPUT_MAX_SIZE 65 #define PSA_PAKE_OUTPUT_MAX_SIZE 65
@ -1889,7 +1889,7 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
* The value of this macro must be at least as large as the largest value * The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_INPUT_SIZE() * returned by PSA_PAKE_INPUT_SIZE()
* *
* See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p step). * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
*/ */
#define PSA_PAKE_INPUT_MAX_SIZE 65 #define PSA_PAKE_INPUT_MAX_SIZE 65

View file

@ -4,8 +4,8 @@
* \brief Add temporary suppport for deprecated symbols before they are * \brief Add temporary suppport for deprecated symbols before they are
* removed from the library. * removed from the library.
* *
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_LEGACY and * PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR
* MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_LEGACY symbols are deprecated. * symbols are deprecated.
* New symols add a suffix to that base name in order to clearly state what is * New symols add a suffix to that base name in order to clearly state what is
* the expected use for the key (use, import, export, generate, derive). * the expected use for the key (use, import, export, generate, derive).
* Here we define some backward compatibility support for uses stil using * Here we define some backward compatibility support for uses stil using

View file

@ -208,6 +208,18 @@
* operations, and does not need to accept all key sizes up to the limit. */ * operations, and does not need to accept all key sizes up to the limit. */
#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096 #define PSA_VENDOR_RSA_MAX_KEY_BITS 4096
/* The minimum size of an RSA key on this implementation, in bits.
* This is a vendor-specific macro.
*
* Limits RSA key generation to a minimum due to avoid accidental misuse.
* This value cannot be less than 128 bits.
*/
#if defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS)
#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS MBEDTLS_RSA_GEN_KEY_MIN_BITS
#else
#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS 1024
#endif
/* The maximum size of an DH key on this implementation, in bits. /* The maximum size of an DH key on this implementation, in bits.
* *
* Note that an implementation may set different size limits for different * Note that an implementation may set different size limits for different
@ -633,10 +645,18 @@
* This macro expands to a compile-time constant integer. This value * This macro expands to a compile-time constant integer. This value
* is the maximum size of a signature in bytes. * is the maximum size of a signature in bytes.
*/ */
#define PSA_SIGNATURE_MAX_SIZE \ #define PSA_SIGNATURE_MAX_SIZE 1
(PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE ? \
PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ #if (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE) (PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE > PSA_SIGNATURE_MAX_SIZE)
#undef PSA_SIGNATURE_MAX_SIZE
#define PSA_SIGNATURE_MAX_SIZE PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE
#endif
#if (defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) || defined(PSA_WANT_ALG_RSA_PSS)) && \
(PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_SIGNATURE_MAX_SIZE)
#undef PSA_SIGNATURE_MAX_SIZE
#define PSA_SIGNATURE_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)
#endif
/** Sufficient output buffer size for psa_asymmetric_encrypt(). /** Sufficient output buffer size for psa_asymmetric_encrypt().
* *
@ -948,10 +968,29 @@
* *
* See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
*/ */
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ #define PSA_EXPORT_KEY_PAIR_MAX_SIZE 1
PSA_MAX_OF_THREE(PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS), \
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS), \ #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)) (PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
PSA_EXPORT_KEY_PAIR_MAX_SIZE)
#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) && \
(PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
PSA_EXPORT_KEY_PAIR_MAX_SIZE)
#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
#endif
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \
(PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
PSA_EXPORT_KEY_PAIR_MAX_SIZE)
#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
#endif
/** Sufficient buffer size for exporting any asymmetric public key. /** Sufficient buffer size for exporting any asymmetric public key.
* *
@ -962,11 +1001,29 @@
* *
* See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
*/ */
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ #define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 1
PSA_MAX_OF_THREE(PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS), \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS), \
PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS))
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) && \
(PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
#endif
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \
(PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
#endif
/** Sufficient output buffer size for psa_raw_key_agreement(). /** Sufficient output buffer size for psa_raw_key_agreement().
* *
@ -1002,11 +1059,18 @@
* *
* See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits).
*/ */
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ #define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE 1
(PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) ? \ #if defined(PSA_WANT_ALG_ECDH) && \
PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \ (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE)
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)) #undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)
#endif
#if defined(PSA_WANT_ALG_FFDH) && \
(PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE)
#undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)
#endif
/** The default IV size for a cipher algorithm, in bytes. /** The default IV size for a cipher algorithm, in bytes.
* *

View file

@ -38,6 +38,7 @@ set(src_crypto
ecjpake.c ecjpake.c
ecp.c ecp.c
ecp_curves.c ecp_curves.c
ecp_curves_new.c
entropy.c entropy.c
entropy_poll.c entropy_poll.c
error.c error.c
@ -289,7 +290,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
add_library(${mbedcrypto_target} SHARED ${src_crypto}) add_library(${mbedcrypto_target} SHARED ${src_crypto})
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.4.0 SOVERSION 14) set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.4.1 SOVERSION 14)
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs}) target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
if(TARGET everest) if(TARGET everest)
@ -301,11 +302,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
endif() endif()
add_library(${mbedx509_target} SHARED ${src_x509}) add_library(${mbedx509_target} SHARED ${src_x509})
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.4.0 SOVERSION 5) set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.4.1 SOVERSION 5)
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target}) target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
add_library(${mbedtls_target} SHARED ${src_tls}) add_library(${mbedtls_target} SHARED ${src_tls})
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.4.0 SOVERSION 19) set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.4.1 SOVERSION 19)
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target}) target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
endif(USE_SHARED_MBEDTLS_LIBRARY) endif(USE_SHARED_MBEDTLS_LIBRARY)
@ -320,6 +321,15 @@ foreach(target IN LISTS target_libraries)
PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/> PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/>
$<INSTALL_INTERFACE:include/> $<INSTALL_INTERFACE:include/>
PRIVATE ${MBEDTLS_DIR}/library/) PRIVATE ${MBEDTLS_DIR}/library/)
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
if(MBEDTLS_CONFIG_FILE)
target_compile_definitions(${target}
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
endif()
if(MBEDTLS_USER_CONFIG_FILE)
target_compile_definitions(${target}
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
endif()
install( install(
TARGETS ${target} TARGETS ${target}
EXPORT MbedTLSTargets EXPORT MbedTLSTargets

View file

@ -103,6 +103,7 @@ OBJS_CRYPTO= \
ecjpake.o \ ecjpake.o \
ecp.o \ ecp.o \
ecp_curves.o \ ecp_curves.o \
ecp_curves_new.o \
entropy.o \ entropy.o \
entropy_poll.o \ entropy_poll.o \
error.o \ error.o \

View file

@ -55,6 +55,8 @@ static int aes_padlock_ace = -1;
/* /*
* Forward S-box * Forward S-box
*/ */
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_DEC_ALT)
static const unsigned char FSb[256] = static const unsigned char FSb[256] =
{ {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
@ -90,6 +92,8 @@ static const unsigned char FSb[256] =
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
}; };
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
/* /*
* Forward tables * Forward tables
@ -161,6 +165,7 @@ static const unsigned char FSb[256] =
V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \ V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C) V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
#define V(a, b, c, d) 0x##a##b##c##d #define V(a, b, c, d) 0x##a##b##c##d
static const uint32_t FT0[256] = { FT }; static const uint32_t FT0[256] = { FT };
#undef V #undef V
@ -181,8 +186,11 @@ static const uint32_t FT3[256] = { FT };
#endif /* !MBEDTLS_AES_FEWER_TABLES */ #endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
#undef FT #undef FT
#if !defined(MBEDTLS_AES_DECRYPT_ALT)
/* /*
* Reverse S-box * Reverse S-box
*/ */
@ -221,6 +229,7 @@ static const unsigned char RSb[256] =
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
}; };
#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
/* /*
* Reverse tables * Reverse tables
@ -292,6 +301,8 @@ static const unsigned char RSb[256] =
V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \ V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0) V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
#define V(a, b, c, d) 0x##a##b##c##d #define V(a, b, c, d) 0x##a##b##c##d
static const uint32_t RT0[256] = { RT }; static const uint32_t RT0[256] = { RT };
#undef V #undef V
@ -312,8 +323,11 @@ static const uint32_t RT3[256] = { RT };
#endif /* !MBEDTLS_AES_FEWER_TABLES */ #endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
#undef RT #undef RT
#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
/* /*
* Round constants * Round constants
*/ */
@ -323,31 +337,44 @@ static const uint32_t RCON[10] =
0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000010, 0x00000020, 0x00000040, 0x00000080,
0x0000001B, 0x00000036 0x0000001B, 0x00000036
}; };
#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
#else /* MBEDTLS_AES_ROM_TABLES */ #else /* MBEDTLS_AES_ROM_TABLES */
/* /*
* Forward S-box & tables * Forward S-box & tables
*/ */
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_DEC_ALT)
static unsigned char FSb[256]; static unsigned char FSb[256];
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
static uint32_t FT0[256]; static uint32_t FT0[256];
#if !defined(MBEDTLS_AES_FEWER_TABLES) #if !defined(MBEDTLS_AES_FEWER_TABLES)
static uint32_t FT1[256]; static uint32_t FT1[256];
static uint32_t FT2[256]; static uint32_t FT2[256];
static uint32_t FT3[256]; static uint32_t FT3[256];
#endif /* !MBEDTLS_AES_FEWER_TABLES */ #endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
/* /*
* Reverse S-box & tables * Reverse S-box & tables
*/ */
#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
static unsigned char RSb[256]; static unsigned char RSb[256];
#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
static uint32_t RT0[256]; static uint32_t RT0[256];
#if !defined(MBEDTLS_AES_FEWER_TABLES) #if !defined(MBEDTLS_AES_FEWER_TABLES)
static uint32_t RT1[256]; static uint32_t RT1[256];
static uint32_t RT2[256]; static uint32_t RT2[256];
static uint32_t RT3[256]; static uint32_t RT3[256];
#endif /* !MBEDTLS_AES_FEWER_TABLES */ #endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
/* /*
* Round constants * Round constants
*/ */
@ -364,25 +391,26 @@ static int aes_init_done = 0;
static void aes_gen_tables(void) static void aes_gen_tables(void)
{ {
int i, x, y, z; int i;
int pow[256]; uint8_t x, y, z;
int log[256]; uint8_t pow[256];
uint8_t log[256];
/* /*
* compute pow and log tables over GF(2^8) * compute pow and log tables over GF(2^8)
*/ */
for (i = 0, x = 1; i < 256; i++) { for (i = 0, x = 1; i < 256; i++) {
pow[i] = x; pow[i] = x;
log[x] = i; log[x] = (uint8_t) i;
x = MBEDTLS_BYTE_0(x ^ XTIME(x)); x ^= XTIME(x);
} }
/* /*
* calculate the round constants * calculate the round constants
*/ */
for (i = 0, x = 1; i < 10; i++) { for (i = 0, x = 1; i < 10; i++) {
RCON[i] = (uint32_t) x; RCON[i] = x;
x = MBEDTLS_BYTE_0(XTIME(x)); x = XTIME(x);
} }
/* /*
@ -394,13 +422,13 @@ static void aes_gen_tables(void)
for (i = 1; i < 256; i++) { for (i = 1; i < 256; i++) {
x = pow[255 - log[i]]; x = pow[255 - log[i]];
y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7)); y = x; y = (y << 1) | (y >> 7);
x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7)); x ^= y; y = (y << 1) | (y >> 7);
x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7)); x ^= y; y = (y << 1) | (y >> 7);
x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7)); x ^= y; y = (y << 1) | (y >> 7);
x ^= y ^ 0x63; x ^= y ^ 0x63;
FSb[i] = (unsigned char) x; FSb[i] = x;
RSb[x] = (unsigned char) i; RSb[x] = (unsigned char) i;
} }
@ -409,8 +437,8 @@ static void aes_gen_tables(void)
*/ */
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
x = FSb[i]; x = FSb[i];
y = MBEDTLS_BYTE_0(XTIME(x)); y = XTIME(x);
z = MBEDTLS_BYTE_0(y ^ x); z = y ^ x;
FT0[i] = ((uint32_t) y) ^ FT0[i] = ((uint32_t) y) ^
((uint32_t) x << 8) ^ ((uint32_t) x << 8) ^
@ -425,6 +453,7 @@ static void aes_gen_tables(void)
x = RSb[i]; x = RSb[i];
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
RT0[i] = ((uint32_t) MUL(0x0E, x)) ^ RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
((uint32_t) MUL(0x09, x) << 8) ^ ((uint32_t) MUL(0x09, x) << 8) ^
((uint32_t) MUL(0x0D, x) << 16) ^ ((uint32_t) MUL(0x0D, x) << 16) ^
@ -435,9 +464,12 @@ static void aes_gen_tables(void)
RT2[i] = ROTL8(RT1[i]); RT2[i] = ROTL8(RT1[i]);
RT3[i] = ROTL8(RT2[i]); RT3[i] = ROTL8(RT2[i]);
#endif /* !MBEDTLS_AES_FEWER_TABLES */ #endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
} }
} }
#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
#undef ROTL8 #undef ROTL8
#endif /* MBEDTLS_AES_ROM_TABLES */ #endif /* MBEDTLS_AES_ROM_TABLES */
@ -514,6 +546,9 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
(defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2) (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
#define MAY_NEED_TO_ALIGN #define MAY_NEED_TO_ALIGN
#endif #endif
#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_ENC_ALT)
static unsigned mbedtls_aes_rk_offset(uint32_t *buf) static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
{ {
#if defined(MAY_NEED_TO_ALIGN) #if defined(MAY_NEED_TO_ALIGN)
@ -550,6 +585,8 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
return 0; return 0;
} }
#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
!defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
/* /*
* AES key schedule (encryption) * AES key schedule (encryption)
@ -1040,23 +1077,6 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
#if defined(MBEDTLS_CIPHER_MODE_CBC) #if defined(MBEDTLS_CIPHER_MODE_CBC)
#if defined(__ARM_NEON) && defined(__aarch64__)
/* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
* the result for the next block in CBC, and the cost of transferring that data from
* NEON registers, it is faster to use the following on aarch64.
* For 32-bit arm, NEON should be faster. */
#define CBC_XOR_16(r, a, b) do { \
mbedtls_put_unaligned_uint64(r, \
mbedtls_get_unaligned_uint64(a) ^ \
mbedtls_get_unaligned_uint64(b)); \
mbedtls_put_unaligned_uint64(r + 8, \
mbedtls_get_unaligned_uint64(a + 8) ^ \
mbedtls_get_unaligned_uint64(b + 8)); \
} while (0)
#else
#define CBC_XOR_16(r, a, b) mbedtls_xor(r, a, b, 16)
#endif
/* /*
* AES-CBC buffer encryption/decryption * AES-CBC buffer encryption/decryption
*/ */
@ -1099,7 +1119,10 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
if (ret != 0) { if (ret != 0) {
goto exit; goto exit;
} }
CBC_XOR_16(output, output, iv); /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
* the result for the next block in CBC, and the cost of transferring that data from
* NEON registers, NEON is slower on aarch64. */
mbedtls_xor_no_simd(output, output, iv, 16);
memcpy(iv, temp, 16); memcpy(iv, temp, 16);
@ -1109,7 +1132,7 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
} }
} else { } else {
while (length > 0) { while (length > 0) {
CBC_XOR_16(output, input, ivp); mbedtls_xor_no_simd(output, input, ivp, 16);
ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output); ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
if (ret != 0) { if (ret != 0) {
@ -1142,8 +1165,11 @@ typedef unsigned char mbedtls_be128[16];
* for machine endianness and hence works correctly on both big and little * for machine endianness and hence works correctly on both big and little
* endian machines. * endian machines.
*/ */
static void mbedtls_gf128mul_x_ble(unsigned char r[16], #if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
const unsigned char x[16]) MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
#endif
static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
const unsigned char x[16])
{ {
uint64_t a, b, ra, rb; uint64_t a, b, ra, rb;
@ -1159,7 +1185,13 @@ static void mbedtls_gf128mul_x_ble(unsigned char r[16],
/* /*
* AES-XTS buffer encryption/decryption * AES-XTS buffer encryption/decryption
*
* Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
* is a 3x performance improvement for gcc -Os, if we have hardware AES support.
*/ */
#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
#endif
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
int mode, int mode,
size_t length, size_t length,
@ -1824,6 +1856,13 @@ int mbedtls_aes_self_test(int verbose)
} else } else
#endif #endif
#if defined(MBEDTLS_AESNI_HAVE_CODE) #if defined(MBEDTLS_AESNI_HAVE_CODE)
#if MBEDTLS_AESNI_HAVE_CODE == 1
mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
#elif MBEDTLS_AESNI_HAVE_CODE == 2
mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
#else
#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
#endif
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
mbedtls_printf(" AES note: using AESNI.\n"); mbedtls_printf(" AES note: using AESNI.\n");
} else } else

View file

@ -66,20 +66,33 @@
# endif # endif
#endif #endif
#if !defined(__ARM_FEATURE_AES) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG) #ifdef __ARM_NEON
# if defined(__clang__) #include <arm_neon.h>
# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) #else
#error "Target does not support NEON instructions"
#endif
#if !(defined(__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)) || \
defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG)
# if defined(__ARMCOMPILER_VERSION)
# if __ARMCOMPILER_VERSION <= 6090000
# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_AESCE_C"
# else
# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function)
# define MBEDTLS_POP_TARGET_PRAGMA
# endif
# elif defined(__clang__)
# pragma clang attribute push (__attribute__((target("aes"))), apply_to=function)
# define MBEDTLS_POP_TARGET_PRAGMA # define MBEDTLS_POP_TARGET_PRAGMA
# elif defined(__GNUC__) # elif defined(__GNUC__)
# pragma GCC push_options # pragma GCC push_options
# pragma GCC target ("arch=armv8-a+crypto") # pragma GCC target ("+crypto")
# define MBEDTLS_POP_TARGET_PRAGMA # define MBEDTLS_POP_TARGET_PRAGMA
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# error "Required feature(__ARM_FEATURE_AES) is not enabled." # error "Required feature(__ARM_FEATURE_AES) is not enabled."
# endif # endif
#endif /* !__ARM_FEATURE_AES || MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */ #endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) ||
MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
#include <arm_neon.h>
#if defined(__linux__) #if defined(__linux__)
#include <asm/hwcap.h> #include <asm/hwcap.h>
@ -101,59 +114,105 @@ int mbedtls_aesce_has_support(void)
#endif #endif
} }
/* Single round of AESCE encryption */
#define AESCE_ENCRYPT_ROUND \
block = vaeseq_u8(block, vld1q_u8(keys)); \
block = vaesmcq_u8(block); \
keys += 16
/* Two rounds of AESCE encryption */
#define AESCE_ENCRYPT_ROUND_X2 AESCE_ENCRYPT_ROUND; AESCE_ENCRYPT_ROUND
MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
static uint8x16_t aesce_encrypt_block(uint8x16_t block, static uint8x16_t aesce_encrypt_block(uint8x16_t block,
unsigned char *keys, unsigned char *keys,
int rounds) int rounds)
{ {
for (int i = 0; i < rounds - 1; i++) { /* 10, 12 or 14 rounds. Unroll loop. */
/* AES AddRoundKey, SubBytes, ShiftRows (in this order). if (rounds == 10) {
* AddRoundKey adds the round key for the previous round. */ goto rounds_10;
block = vaeseq_u8(block, vld1q_u8(keys + i * 16));
/* AES mix columns */
block = vaesmcq_u8(block);
} }
if (rounds == 12) {
goto rounds_12;
}
AESCE_ENCRYPT_ROUND_X2;
rounds_12:
AESCE_ENCRYPT_ROUND_X2;
rounds_10:
AESCE_ENCRYPT_ROUND_X2;
AESCE_ENCRYPT_ROUND_X2;
AESCE_ENCRYPT_ROUND_X2;
AESCE_ENCRYPT_ROUND_X2;
AESCE_ENCRYPT_ROUND;
/* AES AddRoundKey for the previous round. /* AES AddRoundKey for the previous round.
* SubBytes, ShiftRows for the final round. */ * SubBytes, ShiftRows for the final round. */
block = vaeseq_u8(block, vld1q_u8(keys + (rounds -1) * 16)); block = vaeseq_u8(block, vld1q_u8(keys));
keys += 16;
/* Final round: no MixColumns */ /* Final round: no MixColumns */
/* Final AddRoundKey */ /* Final AddRoundKey */
block = veorq_u8(block, vld1q_u8(keys + rounds * 16)); block = veorq_u8(block, vld1q_u8(keys));
return block; return block;
} }
/* Single round of AESCE decryption
*
* AES AddRoundKey, SubBytes, ShiftRows
*
* block = vaesdq_u8(block, vld1q_u8(keys));
*
* AES inverse MixColumns for the next round.
*
* This means that we switch the order of the inverse AddRoundKey and
* inverse MixColumns operations. We have to do this as AddRoundKey is
* done in an atomic instruction together with the inverses of SubBytes
* and ShiftRows.
*
* It works because MixColumns is a linear operation over GF(2^8) and
* AddRoundKey is an exclusive or, which is equivalent to addition over
* GF(2^8). (The inverse of MixColumns needs to be applied to the
* affected round keys separately which has been done when the
* decryption round keys were calculated.)
*
* block = vaesimcq_u8(block);
*/
#define AESCE_DECRYPT_ROUND \
block = vaesdq_u8(block, vld1q_u8(keys)); \
block = vaesimcq_u8(block); \
keys += 16
/* Two rounds of AESCE decryption */
#define AESCE_DECRYPT_ROUND_X2 AESCE_DECRYPT_ROUND; AESCE_DECRYPT_ROUND
static uint8x16_t aesce_decrypt_block(uint8x16_t block, static uint8x16_t aesce_decrypt_block(uint8x16_t block,
unsigned char *keys, unsigned char *keys,
int rounds) int rounds)
{ {
/* 10, 12 or 14 rounds. Unroll loop. */
for (int i = 0; i < rounds - 1; i++) { if (rounds == 10) {
/* AES AddRoundKey, SubBytes, ShiftRows */ goto rounds_10;
block = vaesdq_u8(block, vld1q_u8(keys + i * 16));
/* AES inverse MixColumns for the next round.
*
* This means that we switch the order of the inverse AddRoundKey and
* inverse MixColumns operations. We have to do this as AddRoundKey is
* done in an atomic instruction together with the inverses of SubBytes
* and ShiftRows.
*
* It works because MixColumns is a linear operation over GF(2^8) and
* AddRoundKey is an exclusive or, which is equivalent to addition over
* GF(2^8). (The inverse of MixColumns needs to be applied to the
* affected round keys separately which has been done when the
* decryption round keys were calculated.) */
block = vaesimcq_u8(block);
} }
if (rounds == 12) {
goto rounds_12;
}
AESCE_DECRYPT_ROUND_X2;
rounds_12:
AESCE_DECRYPT_ROUND_X2;
rounds_10:
AESCE_DECRYPT_ROUND_X2;
AESCE_DECRYPT_ROUND_X2;
AESCE_DECRYPT_ROUND_X2;
AESCE_DECRYPT_ROUND_X2;
AESCE_DECRYPT_ROUND;
/* The inverses of AES AddRoundKey, SubBytes, ShiftRows finishing up the /* The inverses of AES AddRoundKey, SubBytes, ShiftRows finishing up the
* last full round. */ * last full round. */
block = vaesdq_u8(block, vld1q_u8(keys + (rounds - 1) * 16)); block = vaesdq_u8(block, vld1q_u8(keys));
keys += 16;
/* Inverse AddRoundKey for inverting the initial round key addition. */ /* Inverse AddRoundKey for inverting the initial round key addition. */
block = veorq_u8(block, vld1q_u8(keys + rounds * 16)); block = veorq_u8(block, vld1q_u8(keys));
return block; return block;
} }

View file

@ -52,6 +52,9 @@ int mbedtls_aesce_has_support(void);
/** /**
* \brief Internal AES-ECB block encryption and decryption * \brief Internal AES-ECB block encryption and decryption
* *
* \warning This assumes that the context specifies either 10, 12 or 14
* rounds and will behave incorrectly if this is not the case.
*
* \param ctx AES context * \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block * \param input 16-byte input block

View file

@ -35,6 +35,8 @@
#if MBEDTLS_AESNI_HAVE_CODE == 2 #if MBEDTLS_AESNI_HAVE_CODE == 2
#if !defined(_WIN32) #if !defined(_WIN32)
#include <cpuid.h> #include <cpuid.h>
#else
#include <intrin.h>
#endif #endif
#include <immintrin.h> #include <immintrin.h>
#endif #endif

View file

@ -59,16 +59,16 @@
#define MBEDTLS_AESNI_HAVE_INTRINSICS #define MBEDTLS_AESNI_HAVE_INTRINSICS
#endif #endif
/* Choose the implementation of AESNI, if one is available. */ /* Choose the implementation of AESNI, if one is available.
#undef MBEDTLS_AESNI_HAVE_CODE *
/* To minimize disruption when releasing the intrinsics-based implementation, * Favor the intrinsics-based implementation if it's available, for better
* favor the assembly-based implementation if it's available. We intend to * maintainability.
* revise this in a later release of Mbed TLS 3.x. In the long run, we will * Performance is about the same (see #7380).
* likely remove the assembly implementation. */ * In the long run, we will likely remove the assembly implementation. */
#if defined(MBEDTLS_HAVE_X86_64) #if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
#elif defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
#elif defined(MBEDTLS_HAVE_X86_64)
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
#endif #endif
#if defined(MBEDTLS_AESNI_HAVE_CODE) #if defined(MBEDTLS_AESNI_HAVE_CODE)

View file

@ -181,6 +181,9 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
/* Detect armcc built-in byteswap routine */ /* Detect armcc built-in byteswap routine */
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32) #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */
#include <arm_acle.h>
#endif
#define MBEDTLS_BSWAP32 __rev #define MBEDTLS_BSWAP32 __rev
#endif #endif

View file

@ -181,10 +181,7 @@ cleanup:
} }
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_mpi_zeroize(mbedtls_mpi_uint *v, size_t n) #define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
{
mbedtls_platform_zeroize(v, ciL * n);
}
/* /*
* Initialize one MPI * Initialize one MPI
@ -208,8 +205,7 @@ void mbedtls_mpi_free(mbedtls_mpi *X)
} }
if (X->p != NULL) { if (X->p != NULL) {
mbedtls_mpi_zeroize(X->p, X->n); mbedtls_mpi_zeroize_and_free(X->p, X->n);
mbedtls_free(X->p);
} }
X->s = 1; X->s = 1;
@ -236,11 +232,12 @@ int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
if (X->p != NULL) { if (X->p != NULL) {
memcpy(p, X->p, X->n * ciL); memcpy(p, X->p, X->n * ciL);
mbedtls_mpi_zeroize(X->p, X->n); mbedtls_mpi_zeroize_and_free(X->p, X->n);
mbedtls_free(X->p);
} }
X->n = nblimbs; /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
* fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
X->n = (unsigned short) nblimbs;
X->p = p; X->p = p;
} }
@ -284,11 +281,12 @@ int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
if (X->p != NULL) { if (X->p != NULL) {
memcpy(p, X->p, i * ciL); memcpy(p, X->p, i * ciL);
mbedtls_mpi_zeroize(X->p, X->n); mbedtls_mpi_zeroize_and_free(X->p, X->n);
mbedtls_free(X->p);
} }
X->n = i; /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
* fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
X->n = (unsigned short) i;
X->p = p; X->p = p;
return 0; return 0;
@ -1022,6 +1020,8 @@ int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t j; size_t j;
mbedtls_mpi_uint *p;
mbedtls_mpi_uint c;
MPI_VALIDATE_RET(X != NULL); MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(A != NULL); MPI_VALIDATE_RET(A != NULL);
MPI_VALIDATE_RET(B != NULL); MPI_VALIDATE_RET(B != NULL);
@ -1055,9 +1055,9 @@ int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
/* j is the number of non-zero limbs of B. Add those to X. */ /* j is the number of non-zero limbs of B. Add those to X. */
mbedtls_mpi_uint *p = X->p; p = X->p;
mbedtls_mpi_uint c = mbedtls_mpi_core_add(p, p, B->p, j); c = mbedtls_mpi_core_add(p, p, B->p, j);
p += j; p += j;
@ -1700,8 +1700,8 @@ static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
{ {
mbedtls_mpi_uint z = 1; mbedtls_mpi_uint z = 1;
mbedtls_mpi U; mbedtls_mpi U;
U.n = 1;
U.n = U.s = (int) z; U.s = 1;
U.p = &z; U.p = &z;
mpi_montmul(A, &U, N, mm, T); mpi_montmul(A, &U, N, mm, T);

View file

@ -36,22 +36,17 @@
size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a) size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)
{ {
#if defined(__has_builtin) #if defined(__has_builtin)
#if __has_builtin(__builtin_clz) #if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_clz)
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned int)) { #define core_clz __builtin_clz
return (size_t) __builtin_clz(a); #elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_clzl)
} #define core_clz __builtin_clzl
#endif #elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_clzll)
#if __has_builtin(__builtin_clzl) #define core_clz __builtin_clzll
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned long)) {
return (size_t) __builtin_clzl(a);
}
#endif
#if __has_builtin(__builtin_clzll)
if (sizeof(mbedtls_mpi_uint) == sizeof(unsigned long long)) {
return (size_t) __builtin_clzll(a);
}
#endif #endif
#endif #endif
#if defined(core_clz)
return (size_t) core_clz(a);
#else
size_t j; size_t j;
mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
@ -64,6 +59,7 @@ size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)
} }
return j; return j;
#endif
} }
size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs) size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs)

View file

@ -80,9 +80,8 @@ void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
switch (N->int_rep) { switch (N->int_rep) {
case MBEDTLS_MPI_MOD_REP_MONTGOMERY: case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
if (N->rep.mont.rr != NULL) { if (N->rep.mont.rr != NULL) {
mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr, mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr,
N->limbs * sizeof(mbedtls_mpi_uint)); N->limbs * sizeof(mbedtls_mpi_uint));
mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
N->rep.mont.rr = NULL; N->rep.mont.rr = NULL;
} }
N->rep.mont.mm = 0; N->rep.mont.mm = 0;
@ -295,9 +294,8 @@ int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
break; break;
} }
mbedtls_platform_zeroize(working_memory, mbedtls_zeroize_and_free(working_memory,
working_limbs * sizeof(mbedtls_mpi_uint)); working_limbs * sizeof(mbedtls_mpi_uint));
mbedtls_free(working_memory);
return ret; return ret;
} }
@ -399,8 +397,7 @@ cleanup:
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY && if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
working_memory != NULL) { working_memory != NULL) {
mbedtls_platform_zeroize(working_memory, working_memory_len); mbedtls_zeroize_and_free(working_memory, working_memory_len);
mbedtls_free(working_memory);
} }
return ret; return ret;

View file

@ -253,8 +253,7 @@ int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs, mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs,
N->rep.mont.mm, N->rep.mont.rr, T); N->rep.mont.mm, N->rep.mont.rr, T);
mbedtls_platform_zeroize(T, t_limbs * ciL); mbedtls_zeroize_and_free(T, t_limbs * ciL);
mbedtls_free(T);
return 0; return 0;
} }
@ -270,8 +269,7 @@ int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T); mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T);
mbedtls_platform_zeroize(T, t_limbs * ciL); mbedtls_zeroize_and_free(T, t_limbs * ciL);
mbedtls_free(T);
return 0; return 0;
} }

View file

@ -673,14 +673,10 @@
#if defined(__arm__) #if defined(__arm__)
#if defined(__thumb__) && !defined(__thumb2__) #if defined(__thumb__) && !defined(__thumb2__)
#if !defined(__ARMCC_VERSION) && !defined(__clang__) \ #if defined(MBEDTLS_COMPILER_IS_GCC)
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/* /*
* Thumb 1 ISA. This code path has only been tested successfully on gcc; * Thumb 1 ISA. This code path has only been tested successfully on gcc;
* it does not compile on clang or armclang. * it does not compile on clang or armclang.
*
* Other compilers which define __GNUC__ may not work. The above macro
* attempts to exclude these untested compilers.
*/ */
#if !defined(__OPTIMIZE__) && defined(__GNUC__) #if !defined(__OPTIMIZE__) && defined(__GNUC__)

View file

@ -70,7 +70,7 @@ int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx,
return MBEDTLS_ERR_CCM_BAD_INPUT; return MBEDTLS_ERR_CCM_BAD_INPUT;
} }
if (cipher_info->block_size != 16) { if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
return MBEDTLS_ERR_CCM_BAD_INPUT; return MBEDTLS_ERR_CCM_BAD_INPUT;
} }

View file

@ -42,13 +42,13 @@
#endif #endif
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ #if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites" #error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites"
#endif #endif
#if defined(PSA_WANT_ALG_ECDSA) && \ #if defined(PSA_WANT_ALG_ECDSA) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites" #error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites"
#endif #endif
@ -60,25 +60,25 @@
#endif #endif
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \ #if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites" #error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
#endif #endif
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \ #if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites" #error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
#endif #endif
#if defined(PSA_WANT_ALG_RSA_OAEP) && \ #if defined(PSA_WANT_ALG_RSA_OAEP) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites" #error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
#endif #endif
#if defined(PSA_WANT_ALG_RSA_PSS) && \ #if defined(PSA_WANT_ALG_RSA_PSS) && \
!(defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \ !(defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)) defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY))
#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites" #error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
#endif #endif

View file

@ -54,10 +54,9 @@
#include "mbedtls/cmac.h" #include "mbedtls/cmac.h"
#endif #endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "psa/crypto.h" #include "psa/crypto.h"
#include "mbedtls/psa_util.h" #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_NIST_KW_C) #if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h" #include "mbedtls/nist_kw.h"
@ -67,6 +66,12 @@
static int supported_init = 0; static int supported_init = 0;
static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base(
const mbedtls_cipher_info_t *info)
{
return mbedtls_cipher_base_lookup_table[info->base_idx];
}
const int *mbedtls_cipher_list(void) const int *mbedtls_cipher_list(void)
{ {
const mbedtls_cipher_definition_t *def; const mbedtls_cipher_definition_t *def;
@ -128,8 +133,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
const mbedtls_cipher_definition_t *def; const mbedtls_cipher_definition_t *def;
for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { for (def = mbedtls_cipher_definitions; def->info != NULL; def++) {
if (def->info->base->cipher == cipher_id && if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id &&
def->info->key_bitlen == (unsigned) key_bitlen && mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen &&
def->info->mode == mode) { def->info->mode == mode) {
return def->info; return def->info;
} }
@ -138,6 +143,72 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
return NULL; return NULL;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
mbedtls_cipher_type_t cipher)
{
switch (cipher) {
case MBEDTLS_CIPHER_AES_128_CCM:
case MBEDTLS_CIPHER_AES_192_CCM:
case MBEDTLS_CIPHER_AES_256_CCM:
case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_AES_128_GCM:
case MBEDTLS_CIPHER_AES_192_GCM:
case MBEDTLS_CIPHER_AES_256_GCM:
case MBEDTLS_CIPHER_AES_128_CBC:
case MBEDTLS_CIPHER_AES_192_CBC:
case MBEDTLS_CIPHER_AES_256_CBC:
case MBEDTLS_CIPHER_AES_128_ECB:
case MBEDTLS_CIPHER_AES_192_ECB:
case MBEDTLS_CIPHER_AES_256_ECB:
return PSA_KEY_TYPE_AES;
/* ARIA not yet supported in PSA. */
/* case MBEDTLS_CIPHER_ARIA_128_CCM:
case MBEDTLS_CIPHER_ARIA_192_CCM:
case MBEDTLS_CIPHER_ARIA_256_CCM:
case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
case MBEDTLS_CIPHER_ARIA_128_GCM:
case MBEDTLS_CIPHER_ARIA_192_GCM:
case MBEDTLS_CIPHER_ARIA_256_GCM:
case MBEDTLS_CIPHER_ARIA_128_CBC:
case MBEDTLS_CIPHER_ARIA_192_CBC:
case MBEDTLS_CIPHER_ARIA_256_CBC:
return( PSA_KEY_TYPE_ARIA ); */
default:
return 0;
}
}
static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
mbedtls_cipher_mode_t mode, size_t taglen)
{
switch (mode) {
case MBEDTLS_MODE_ECB:
return PSA_ALG_ECB_NO_PADDING;
case MBEDTLS_MODE_GCM:
return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen);
case MBEDTLS_MODE_CCM:
return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen);
case MBEDTLS_MODE_CCM_STAR_NO_TAG:
return PSA_ALG_CCM_STAR_NO_TAG;
case MBEDTLS_MODE_CBC:
if (taglen == 0) {
return PSA_ALG_CBC_NO_PADDING;
} else {
return 0;
}
default:
return 0;
}
}
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx) void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx)
{ {
memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
@ -149,7 +220,7 @@ void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
return; return;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
if (ctx->cipher_ctx != NULL) { if (ctx->cipher_ctx != NULL) {
mbedtls_cipher_context_psa * const cipher_psa = mbedtls_cipher_context_psa * const cipher_psa =
@ -160,25 +231,23 @@ void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
(void) psa_destroy_key(cipher_psa->slot); (void) psa_destroy_key(cipher_psa->slot);
} }
mbedtls_platform_zeroize(cipher_psa, sizeof(*cipher_psa)); mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa));
mbedtls_free(cipher_psa);
} }
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
return; return;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_CMAC_C) #if defined(MBEDTLS_CMAC_C)
if (ctx->cmac_ctx) { if (ctx->cmac_ctx) {
mbedtls_platform_zeroize(ctx->cmac_ctx, mbedtls_zeroize_and_free(ctx->cmac_ctx,
sizeof(mbedtls_cmac_context_t)); sizeof(mbedtls_cmac_context_t));
mbedtls_free(ctx->cmac_ctx);
} }
#endif #endif
if (ctx->cipher_ctx) { if (ctx->cipher_ctx) {
ctx->cipher_info->base->ctx_free_func(ctx->cipher_ctx); mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx);
} }
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
@ -193,7 +262,7 @@ int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); memset(ctx, 0, sizeof(mbedtls_cipher_context_t));
if (NULL == (ctx->cipher_ctx = cipher_info->base->ctx_alloc_func())) { if (NULL == (ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func())) {
return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; return MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
} }
@ -213,8 +282,7 @@ int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx,
return 0; return 0;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx, int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info, const mbedtls_cipher_info_t *cipher_info,
size_t taglen) size_t taglen)
@ -228,11 +296,11 @@ int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
/* Check that the underlying cipher mode and cipher type are /* Check that the underlying cipher mode and cipher type are
* supported by the underlying PSA Crypto implementation. */ * supported by the underlying PSA Crypto implementation. */
alg = mbedtls_psa_translate_cipher_mode(cipher_info->mode, taglen); alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen);
if (alg == 0) { if (alg == 0) {
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
if (mbedtls_psa_translate_cipher_type(cipher_info->type) == 0) { if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) {
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
@ -248,8 +316,7 @@ int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
ctx->psa_enabled = 1; ctx->psa_enabled = 1;
return 0; return 0;
} }
#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
const unsigned char *key, const unsigned char *key,
@ -263,7 +330,7 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
mbedtls_cipher_context_psa * const cipher_psa = mbedtls_cipher_context_psa * const cipher_psa =
(mbedtls_cipher_context_psa *) ctx->cipher_ctx; (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
@ -285,7 +352,7 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
} }
key_type = mbedtls_psa_translate_cipher_type( key_type = mbedtls_psa_translate_cipher_type(
ctx->cipher_info->type); ((mbedtls_cipher_type_t) ctx->cipher_info->type));
if (key_type == 0) { if (key_type == 0) {
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
@ -296,7 +363,6 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
* and use it for AEAD decryption. Until tests relying on this * and use it for AEAD decryption. Until tests relying on this
* are changed, allow any usage in PSA. */ * are changed, allow any usage in PSA. */
psa_set_key_usage_flags(&attributes, psa_set_key_usage_flags(&attributes,
/* mbedtls_psa_translate_cipher_operation( operation ); */
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, cipher_psa->alg); psa_set_key_algorithm(&attributes, cipher_psa->alg);
@ -320,10 +386,10 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
ctx->operation = operation; ctx->operation = operation;
return 0; return 0;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 && if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 &&
(int) ctx->cipher_info->key_bitlen != key_bitlen) { (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
@ -334,16 +400,16 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
* For OFB, CFB and CTR mode always use the encryption key schedule * For OFB, CFB and CTR mode always use the encryption key schedule
*/ */
if (MBEDTLS_ENCRYPT == operation || if (MBEDTLS_ENCRYPT == operation ||
MBEDTLS_MODE_CFB == ctx->cipher_info->mode || MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode) { MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
return ctx->cipher_info->base->setkey_enc_func(ctx->cipher_ctx, key, return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key,
ctx->key_bitlen); ctx->key_bitlen);
} }
if (MBEDTLS_DECRYPT == operation) { if (MBEDTLS_DECRYPT == operation) {
return ctx->cipher_info->base->setkey_dec_func(ctx->cipher_ctx, key, return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key,
ctx->key_bitlen); ctx->key_bitlen);
} }
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@ -358,14 +424,14 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
if (ctx->cipher_info == NULL) { if (ctx->cipher_info == NULL) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
/* avoid buffer overflow in ctx->iv */ /* avoid buffer overflow in ctx->iv */
if (iv_len > MBEDTLS_MAX_IV_LENGTH) { if (iv_len > MBEDTLS_MAX_IV_LENGTH) {
@ -375,7 +441,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) { if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) {
actual_iv_size = iv_len; actual_iv_size = iv_len;
} else { } else {
actual_iv_size = ctx->cipher_info->iv_size; actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info);
/* avoid reading past the end of input buffer */ /* avoid reading past the end of input buffer */
if (actual_iv_size > iv_len) { if (actual_iv_size > iv_len) {
@ -384,7 +450,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
} }
#if defined(MBEDTLS_CHACHA20_C) #if defined(MBEDTLS_CHACHA20_C)
if (ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20) { if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) {
/* Even though the actual_iv_size is overwritten with a correct value /* Even though the actual_iv_size is overwritten with a correct value
* of 12 from the cipher info, return an error to indicate that * of 12 from the cipher info, return an error to indicate that
* the input iv_len is wrong. */ * the input iv_len is wrong. */
@ -399,7 +465,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
} }
} }
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 && if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 &&
iv_len != 12) { iv_len != 12) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
@ -407,7 +473,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
#endif #endif
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx, return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx,
ctx->operation, ctx->operation,
iv, iv_len); iv, iv_len);
@ -415,7 +481,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx,
#endif #endif
#if defined(MBEDTLS_CCM_C) #if defined(MBEDTLS_CCM_C)
if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ctx->cipher_info->mode) { if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
int set_lengths_result; int set_lengths_result;
int ccm_star_mode; int ccm_star_mode;
@ -454,13 +520,13 @@ int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx)
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* We don't support resetting PSA-based /* We don't support resetting PSA-based
* cipher contexts, yet. */ * cipher contexts, yet. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
ctx->unprocessed_len = 0; ctx->unprocessed_len = 0;
@ -475,24 +541,24 @@ int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx, return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx,
ad, ad_len); ad, ad_len);
} }
#endif #endif
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type) { if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
int result; int result;
mbedtls_chachapoly_mode_t mode; mbedtls_chachapoly_mode_t mode;
@ -526,14 +592,14 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
*olen = 0; *olen = 0;
block_size = mbedtls_cipher_get_block_size(ctx); block_size = mbedtls_cipher_get_block_size(ctx);
@ -541,15 +607,16 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
} }
if (ctx->cipher_info->mode == MBEDTLS_MODE_ECB) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) {
if (ilen != block_size) { if (ilen != block_size) {
return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
} }
*olen = ilen; *olen = ilen;
if (0 != (ret = ctx->cipher_info->base->ecb_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx,
ctx->operation, input, output))) { ctx->operation, input,
output))) {
return ret; return ret;
} }
@ -557,7 +624,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
} }
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (ctx->cipher_info->mode == MBEDTLS_MODE_GCM) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) {
return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx, return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx,
input, ilen, input, ilen,
output, ilen, olen); output, ilen, olen);
@ -565,7 +632,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif #endif
#if defined(MBEDTLS_CCM_C) #if defined(MBEDTLS_CCM_C)
if (ctx->cipher_info->mode == MBEDTLS_MODE_CCM_STAR_NO_TAG) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) {
return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx, return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx,
input, ilen, input, ilen,
output, ilen, olen); output, ilen, olen);
@ -573,7 +640,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif #endif
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) { if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) {
*olen = ilen; *olen = ilen;
return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx, return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx,
ilen, input, output); ilen, input, output);
@ -586,7 +653,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
} }
#if defined(MBEDTLS_CIPHER_MODE_CBC) #if defined(MBEDTLS_CIPHER_MODE_CBC)
if (ctx->cipher_info->mode == MBEDTLS_MODE_CBC) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) {
size_t copy_len = 0; size_t copy_len = 0;
/* /*
@ -614,9 +681,12 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
copy_len); copy_len);
if (0 != (ret = ctx->cipher_info->base->cbc_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
ctx->operation, block_size, ctx->iv, ctx->operation,
ctx->unprocessed_data, output))) { block_size, ctx->iv,
ctx->
unprocessed_data,
output))) {
return ret; return ret;
} }
@ -654,9 +724,11 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
* Process remaining full blocks * Process remaining full blocks
*/ */
if (ilen) { if (ilen) {
if (0 != (ret = ctx->cipher_info->base->cbc_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
ctx->operation, ilen, ctx->iv, input, ctx->operation,
output))) { ilen, ctx->iv,
input,
output))) {
return ret; return ret;
} }
@ -668,11 +740,12 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif /* MBEDTLS_CIPHER_MODE_CBC */ #endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB) #if defined(MBEDTLS_CIPHER_MODE_CFB)
if (ctx->cipher_info->mode == MBEDTLS_MODE_CFB) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) {
if (0 != (ret = ctx->cipher_info->base->cfb_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx,
ctx->operation, ilen, ctx->operation, ilen,
&ctx->unprocessed_len, ctx->iv, &ctx->unprocessed_len,
input, output))) { ctx->iv,
input, output))) {
return ret; return ret;
} }
@ -683,10 +756,12 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif /* MBEDTLS_CIPHER_MODE_CFB */ #endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB) #if defined(MBEDTLS_CIPHER_MODE_OFB)
if (ctx->cipher_info->mode == MBEDTLS_MODE_OFB) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) {
if (0 != (ret = ctx->cipher_info->base->ofb_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx,
ilen, &ctx->unprocessed_len, ctx->iv, ilen,
input, output))) { &ctx->unprocessed_len,
ctx->iv,
input, output))) {
return ret; return ret;
} }
@ -697,10 +772,13 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif /* MBEDTLS_CIPHER_MODE_OFB */ #endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR) #if defined(MBEDTLS_CIPHER_MODE_CTR)
if (ctx->cipher_info->mode == MBEDTLS_MODE_CTR) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) {
if (0 != (ret = ctx->cipher_info->base->ctr_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx,
ilen, &ctx->unprocessed_len, ctx->iv, ilen,
ctx->unprocessed_data, input, output))) { &ctx->unprocessed_len,
ctx->iv,
ctx->unprocessed_data,
input, output))) {
return ret; return ret;
} }
@ -711,14 +789,18 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif /* MBEDTLS_CIPHER_MODE_CTR */ #endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS) #if defined(MBEDTLS_CIPHER_MODE_XTS)
if (ctx->cipher_info->mode == MBEDTLS_MODE_XTS) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) {
if (ctx->unprocessed_len > 0) { if (ctx->unprocessed_len > 0) {
/* We can only process an entire data unit at a time. */ /* We can only process an entire data unit at a time. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
ret = ctx->cipher_info->base->xts_func(ctx->cipher_ctx, ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx,
ctx->operation, ilen, ctx->iv, input, output); ctx->operation,
ilen,
ctx->iv,
input,
output);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
@ -730,9 +812,10 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *in
#endif /* MBEDTLS_CIPHER_MODE_XTS */ #endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_STREAM) #if defined(MBEDTLS_CIPHER_MODE_STREAM)
if (ctx->cipher_info->mode == MBEDTLS_MODE_STREAM) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) {
if (0 != (ret = ctx->cipher_info->base->stream_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx,
ilen, input, output))) { ilen, input,
output))) {
return ret; return ret;
} }
@ -933,33 +1016,33 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
*olen = 0; *olen = 0;
if (MBEDTLS_MODE_CFB == ctx->cipher_info->mode || if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_GCM == ctx->cipher_info->mode || MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_CCM_STAR_NO_TAG == ctx->cipher_info->mode || MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_XTS == ctx->cipher_info->mode || MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_STREAM == ctx->cipher_info->mode) { MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
return 0; return 0;
} }
if ((MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type) || if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) ||
(MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type)) { (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) {
return 0; return 0;
} }
if (MBEDTLS_MODE_ECB == ctx->cipher_info->mode) { if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
if (ctx->unprocessed_len != 0) { if (ctx->unprocessed_len != 0) {
return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED;
} }
@ -968,7 +1051,7 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
} }
#if defined(MBEDTLS_CIPHER_MODE_CBC) #if defined(MBEDTLS_CIPHER_MODE_CBC)
if (MBEDTLS_MODE_CBC == ctx->cipher_info->mode) { if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
int ret = 0; int ret = 0;
if (MBEDTLS_ENCRYPT == ctx->operation) { if (MBEDTLS_ENCRYPT == ctx->operation) {
@ -996,11 +1079,13 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
} }
/* cipher block */ /* cipher block */
if (0 != (ret = ctx->cipher_info->base->cbc_func(ctx->cipher_ctx, if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx,
ctx->operation, ctx->operation,
mbedtls_cipher_get_block_size(ctx), mbedtls_cipher_get_block_size(
ctx->iv, ctx),
ctx->unprocessed_data, output))) { ctx->iv,
ctx->unprocessed_data,
output))) {
return ret; return ret;
} }
@ -1025,11 +1110,12 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode) mbedtls_cipher_padding_t mode)
{ {
if (NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode) { if (NULL == ctx->cipher_info ||
MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto knows about CBC padding /* While PSA Crypto knows about CBC padding
* schemes, we currently don't make them * schemes, we currently don't make them
@ -1040,7 +1126,7 @@ int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
return 0; return 0;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
switch (mode) { switch (mode) {
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) #if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
@ -1092,17 +1178,17 @@ int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
size_t output_length; size_t output_length;
/* The code here doesn't yet support alternative implementations /* The code here doesn't yet support alternative implementations
* that can delay up to a block of output. */ * that can delay up to a block of output. */
@ -1113,7 +1199,7 @@ int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx,
#endif #endif
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type) { if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
/* Don't allow truncated MAC for Poly1305 */ /* Don't allow truncated MAC for Poly1305 */
if (tag_len != 16U) { if (tag_len != 16U) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@ -1141,20 +1227,20 @@ int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* While PSA Crypto has an API for multipart /* While PSA Crypto has an API for multipart
* operations, we currently don't make it * operations, we currently don't make it
* accessible through the cipher layer. */ * accessible through the cipher layer. */
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
/* Status to return on a non-authenticated algorithm. */ /* Status to return on a non-authenticated algorithm. */
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
size_t output_length; size_t output_length;
/* The code here doesn't yet support alternative implementations /* The code here doesn't yet support alternative implementations
* that can delay up to a block of output. */ * that can delay up to a block of output. */
@ -1179,7 +1265,7 @@ int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx,
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type) { if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
/* Don't allow truncated MAC for Poly1305 */ /* Don't allow truncated MAC for Poly1305 */
if (tag_len != sizeof(check_tag)) { if (tag_len != sizeof(check_tag)) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
@ -1216,7 +1302,7 @@ int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t finish_olen; size_t finish_olen;
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* As in the non-PSA case, we don't check that /* As in the non-PSA case, we don't check that
* a key has been set. If not, the key slot will * a key has been set. If not, the key slot will
@ -1250,7 +1336,7 @@ int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
} }
if (ctx->cipher_info->mode != MBEDTLS_MODE_ECB) { if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) {
status = psa_cipher_set_iv(&cipher_op, iv, iv_len); status = psa_cipher_set_iv(&cipher_op, iv, iv_len);
if (status != PSA_SUCCESS) { if (status != PSA_SUCCESS) {
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
@ -1274,7 +1360,7 @@ int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx,
*olen += part_len; *olen += part_len;
return 0; return 0;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) { if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) {
return ret; return ret;
@ -1311,7 +1397,7 @@ static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen, unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len) unsigned char *tag, size_t tag_len)
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* As in the non-PSA case, we don't check that /* As in the non-PSA case, we don't check that
* a key has been set. If not, the key slot will * a key has been set. If not, the key slot will
@ -1342,10 +1428,10 @@ static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
*olen -= tag_len; *olen -= tag_len;
return 0; return 0;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
*olen = ilen; *olen = ilen;
return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
ilen, iv, iv_len, ad, ad_len, ilen, iv, iv_len, ad, ad_len,
@ -1353,7 +1439,7 @@ static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
} }
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C) #if defined(MBEDTLS_CCM_C)
if (MBEDTLS_MODE_CCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
*olen = ilen; *olen = ilen;
return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen, return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen,
iv, iv_len, ad, ad_len, input, output, iv, iv_len, ad, ad_len, input, output,
@ -1361,9 +1447,9 @@ static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx,
} }
#endif /* MBEDTLS_CCM_C */ #endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type) { if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
/* ChachaPoly has fixed length nonce and MAC (tag) */ /* ChachaPoly has fixed length nonce and MAC (tag) */
if ((iv_len != ctx->cipher_info->iv_size) || if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
(tag_len != 16U)) { (tag_len != 16U)) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
@ -1388,7 +1474,7 @@ static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen, unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len) const unsigned char *tag, size_t tag_len)
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
if (ctx->psa_enabled == 1) { if (ctx->psa_enabled == 1) {
/* As in the non-PSA case, we don't check that /* As in the non-PSA case, we don't check that
* a key has been set. If not, the key slot will * a key has been set. If not, the key slot will
@ -1420,10 +1506,10 @@ static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
return 0; return 0;
} }
#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_GCM_C) #if defined(MBEDTLS_GCM_C)
if (MBEDTLS_MODE_GCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen; *olen = ilen;
@ -1439,7 +1525,7 @@ static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
} }
#endif /* MBEDTLS_GCM_C */ #endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C) #if defined(MBEDTLS_CCM_C)
if (MBEDTLS_MODE_CCM == ctx->cipher_info->mode) { if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen; *olen = ilen;
@ -1455,11 +1541,11 @@ static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx,
} }
#endif /* MBEDTLS_CCM_C */ #endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C) #if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type) { if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* ChachaPoly has fixed length nonce and MAC (tag) */ /* ChachaPoly has fixed length nonce and MAC (tag) */
if ((iv_len != ctx->cipher_info->iv_size) || if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) ||
(tag_len != 16U)) { (tag_len != 16U)) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
@ -1493,13 +1579,14 @@ int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx,
{ {
#if defined(MBEDTLS_NIST_KW_C) #if defined(MBEDTLS_NIST_KW_C)
if ( if (
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
ctx->psa_enabled == 0 && ctx->psa_enabled == 0 &&
#endif #endif
(MBEDTLS_MODE_KW == ctx->cipher_info->mode || (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_KWP == ctx->cipher_info->mode)) { MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
mbedtls_nist_kw_mode_t mode = (MBEDTLS_MODE_KW == ctx->cipher_info->mode) ? mbedtls_nist_kw_mode_t mode =
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
/* There is no iv, tag or ad associated with KW and KWP, /* There is no iv, tag or ad associated with KW and KWP,
* so these length should be 0 as documented. */ * so these length should be 0 as documented. */
@ -1543,13 +1630,14 @@ int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx,
{ {
#if defined(MBEDTLS_NIST_KW_C) #if defined(MBEDTLS_NIST_KW_C)
if ( if (
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
ctx->psa_enabled == 0 && ctx->psa_enabled == 0 &&
#endif #endif
(MBEDTLS_MODE_KW == ctx->cipher_info->mode || (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) ||
MBEDTLS_MODE_KWP == ctx->cipher_info->mode)) { MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) {
mbedtls_nist_kw_mode_t mode = (MBEDTLS_MODE_KW == ctx->cipher_info->mode) ? mbedtls_nist_kw_mode_t mode =
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ?
MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
/* There is no iv, tag or ad associated with KW and KWP, /* There is no iv, tag or ad associated with KW and KWP,
* so these length should be 0 as documented. */ * so these length should be 0 as documented. */

File diff suppressed because it is too large Load diff

View file

@ -135,6 +135,8 @@ extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[]; extern int mbedtls_cipher_supported[];
extern const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[];
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -119,7 +119,7 @@ static int cmac_generate_subkeys(mbedtls_cipher_context_t *ctx,
mbedtls_platform_zeroize(L, sizeof(L)); mbedtls_platform_zeroize(L, sizeof(L));
block_size = ctx->cipher_info->block_size; block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
/* Calculate Ek(0) */ /* Calculate Ek(0) */
if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) { if ((ret = mbedtls_cipher_update(ctx, L, block_size, L, &olen)) != 0) {
@ -186,7 +186,7 @@ int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
return retval; return retval;
} }
type = ctx->cipher_info->type; type = mbedtls_cipher_info_get_type(ctx->cipher_info);
switch (type) { switch (type) {
case MBEDTLS_CIPHER_AES_128_ECB: case MBEDTLS_CIPHER_AES_128_ECB:
@ -226,7 +226,7 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
} }
cmac_ctx = ctx->cmac_ctx; cmac_ctx = ctx->cmac_ctx;
block_size = ctx->cipher_info->block_size; block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
state = ctx->cmac_ctx->state; state = ctx->cmac_ctx->state;
/* Is there data still to process from the last call, that's greater in /* Is there data still to process from the last call, that's greater in
@ -237,7 +237,7 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
input, input,
block_size - cmac_ctx->unprocessed_len); block_size - cmac_ctx->unprocessed_len);
mbedtls_xor(state, cmac_ctx->unprocessed_block, state, block_size); mbedtls_xor_no_simd(state, cmac_ctx->unprocessed_block, state, block_size);
if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
&olen)) != 0) { &olen)) != 0) {
@ -255,7 +255,7 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
/* Iterate across the input data in block sized chunks, excluding any /* Iterate across the input data in block sized chunks, excluding any
* final partial or complete block */ * final partial or complete block */
for (j = 1; j < n; j++) { for (j = 1; j < n; j++) {
mbedtls_xor(state, input, state, block_size); mbedtls_xor_no_simd(state, input, state, block_size);
if ((ret = mbedtls_cipher_update(ctx, state, block_size, state, if ((ret = mbedtls_cipher_update(ctx, state, block_size, state,
&olen)) != 0) { &olen)) != 0) {
@ -295,7 +295,7 @@ int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
} }
cmac_ctx = ctx->cmac_ctx; cmac_ctx = ctx->cmac_ctx;
block_size = ctx->cipher_info->block_size; block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
state = cmac_ctx->state; state = cmac_ctx->state;
mbedtls_platform_zeroize(K1, sizeof(K1)); mbedtls_platform_zeroize(K1, sizeof(K1));

View file

@ -114,6 +114,20 @@ extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const cha
*/ */
#define MBEDTLS_ALLOW_PRIVATE_ACCESS #define MBEDTLS_ALLOW_PRIVATE_ACCESS
/**
* \brief Securely zeroize a buffer then free it.
*
* Similar to making consecutive calls to
* \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has
* code size savings, and potential for optimisation in the future.
*
* Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0.
*
* \param buf Buffer to be zeroized then freed.
* \param len Length of the buffer in bytes
*/
void mbedtls_zeroize_and_free(void *buf, size_t len);
/** Return an offset into a buffer. /** Return an offset into a buffer.
* *
* This is just the addition of an offset to a pointer, except that this * This is just the addition of an offset to a pointer, except that this
@ -192,6 +206,45 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
} }
} }
/**
* Perform a fast block XOR operation, such that
* r[i] = a[i] ^ b[i] where 0 <= i < n
*
* In some situations, this can perform better than mbedtls_xor (e.g., it's about 5%
* better in AES-CBC).
*
* \param r Pointer to result (buffer of at least \p n bytes). \p r
* may be equal to either \p a or \p b, but behaviour when
* it overlaps in other ways is undefined.
* \param a Pointer to input (buffer of at least \p n bytes)
* \param b Pointer to input (buffer of at least \p n bytes)
* \param n Number of bytes to process.
*/
static inline void mbedtls_xor_no_simd(unsigned char *r,
const unsigned char *a,
const unsigned char *b,
size_t n)
{
size_t i = 0;
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
#if defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__)
/* This codepath probably only makes sense on architectures with 64-bit registers */
for (; (i + 8) <= n; i += 8) {
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
mbedtls_put_unaligned_uint64(r + i, x);
}
#else
for (; (i + 4) <= n; i += 4) {
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
mbedtls_put_unaligned_uint32(r + i, x);
}
#endif
#endif
for (; i < n; i++) {
r[i] = a[i] ^ b[i];
}
}
/* Fix MSVC C99 compatible issue /* Fix MSVC C99 compatible issue
* MSVC support __func__ from visual studio 2015( 1900 ) * MSVC support __func__ from visual studio 2015( 1900 )
* Use MSVC predefine macro to avoid name check fail. * Use MSVC predefine macro to avoid name check fail.
@ -203,8 +256,12 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
/* Define `asm` for compilers which don't define it. */ /* Define `asm` for compilers which don't define it. */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifndef asm #ifndef asm
#if defined(__IAR_SYSTEMS_ICC__)
#define asm __asm
#else
#define asm __asm__ #define asm __asm__
#endif #endif
#endif
/* *INDENT-ON* */ /* *INDENT-ON* */
/* /*
@ -252,8 +309,8 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
/* Define compiler branch hints */ /* Define compiler branch hints */
#if defined(__has_builtin) #if defined(__has_builtin)
#if __has_builtin(__builtin_expect) #if __has_builtin(__builtin_expect)
#define MBEDTLS_LIKELY(x) __builtin_expect((x), 1) #define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1)
#define MBEDTLS_UNLIKELY(x) __builtin_expect((x), 0) #define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0)
#endif #endif
#endif #endif
#if !defined(MBEDTLS_LIKELY) #if !defined(MBEDTLS_LIKELY)
@ -261,4 +318,20 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned
#define MBEDTLS_UNLIKELY(x) x #define MBEDTLS_UNLIKELY(x) x
#endif #endif
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/* Defined if the compiler really is gcc and not clang, etc */
#define MBEDTLS_COMPILER_IS_GCC
#endif
/* For gcc -Os, override with -O2 for a given function.
*
* This will not affect behaviour for other optimisation settings, e.g. -O0.
*/
#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__)
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2")))
#else
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
#endif
#endif /* MBEDTLS_LIBRARY_COMMON_H */ #endif /* MBEDTLS_LIBRARY_COMMON_H */

View file

@ -397,7 +397,8 @@ void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
} }
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_REMOVE_INFO */ #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_REMOVE_INFO */
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
defined(MBEDTLS_ECDH_C)
static void mbedtls_debug_printf_ecdh_internal(const mbedtls_ssl_context *ssl, static void mbedtls_debug_printf_ecdh_internal(const mbedtls_ssl_context *ssl,
int level, const char *file, int level, const char *file,
int line, int line,
@ -443,6 +444,7 @@ void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
} }
#endif #endif
} }
#endif /* MBEDTLS_ECDH_C */ #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#endif /* MBEDTLS_DEBUG_C */ #endif /* MBEDTLS_DEBUG_C */

View file

@ -617,8 +617,7 @@ static int load_file(const char *path, unsigned char **buf, size_t *n)
if (fread(*buf, 1, *n, f) != *n) { if (fread(*buf, 1, *n, f) != *n) {
fclose(f); fclose(f);
mbedtls_platform_zeroize(*buf, *n + 1); mbedtls_zeroize_and_free(*buf, *n + 1);
mbedtls_free(*buf);
return MBEDTLS_ERR_DHM_FILE_IO_ERROR; return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
} }
@ -649,8 +648,7 @@ int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
ret = mbedtls_dhm_parse_dhm(dhm, buf, n); ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
mbedtls_platform_zeroize(buf, n); mbedtls_zeroize_and_free(buf, n);
mbedtls_free(buf);
return ret; return ret;
} }

View file

@ -592,6 +592,11 @@ void mbedtls_ecp_group_free(mbedtls_ecp_group *grp)
mbedtls_mpi_free(&grp->A); mbedtls_mpi_free(&grp->A);
mbedtls_mpi_free(&grp->B); mbedtls_mpi_free(&grp->B);
mbedtls_ecp_point_free(&grp->G); mbedtls_ecp_point_free(&grp->G);
#if !defined(MBEDTLS_ECP_WITH_MPI_UINT)
mbedtls_mpi_free(&grp->N);
mbedtls_mpi_free(&grp->P);
#endif
} }
if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) { if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) {
@ -2930,9 +2935,9 @@ int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) } #define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) }
#define ECP_MPI_INIT_ARRAY(x) \ #define ECP_MPI_INIT_ARRAY(x) \
ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x) ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint))
/* /*
* Constants for the two points other than 0, 1, -1 (mod p) in * Constants for the two points other than 0, 1, -1 (mod p) in
* https://cr.yp.to/ecdh.html#validate * https://cr.yp.to/ecdh.html#validate
@ -3278,16 +3283,14 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
); );
} }
} }
#endif #endif
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&key->d, buf, buflen)); MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&key->d, buf, buflen));
MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(&key->grp, &key->d));
} }
#endif #endif
MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(&key->grp, &key->d));
cleanup: cleanup:
if (ret != 0) { if (ret != 0) {

File diff suppressed because it is too large Load diff

6055
library/ecp_curves_new.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -40,8 +40,21 @@ typedef enum {
MBEDTLS_ECP_MOD_SCALAR MBEDTLS_ECP_MOD_SCALAR
} mbedtls_ecp_modulus_type; } mbedtls_ecp_modulus_type;
typedef enum {
MBEDTLS_ECP_VARIANT_NONE = 0,
MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT,
MBEDTLS_ECP_VARIANT_WITH_MPI_UINT
} mbedtls_ecp_variant;
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT) #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT)
/** Queries the ecp variant.
*
* \return The id of the ecp variant.
*/
MBEDTLS_STATIC_TESTABLE
mbedtls_ecp_variant mbedtls_ecp_get_variant(void);
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/** Generate a private key on a Montgomery curve (Curve25519 or Curve448). /** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
* *

View file

@ -48,10 +48,8 @@
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#if !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h> #include <windows.h>
#if _WIN32_WINNT >= 0x0501 /* _WIN32_WINNT_WINXP */
#include <wincrypt.h> #include <wincrypt.h>
int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
@ -76,6 +74,9 @@ int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len,
return 0; return 0;
} }
#else /* !_WIN32_WINNT_WINXP */
#error Entropy not available before Windows XP, use MBEDTLS_NO_PLATFORM_ENTROPY
#endif /* !_WIN32_WINNT_WINXP */
#else /* _WIN32 && !EFIX64 && !EFI32 */ #else /* _WIN32 && !EFIX64 && !EFI32 */
/* /*

View file

@ -147,7 +147,7 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
return MBEDTLS_ERR_GCM_BAD_INPUT; return MBEDTLS_ERR_GCM_BAD_INPUT;
} }
if (cipher_info->block_size != 16) { if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
return MBEDTLS_ERR_GCM_BAD_INPUT; return MBEDTLS_ERR_GCM_BAD_INPUT;
} }
@ -174,7 +174,7 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
* last4[x] = x times P^128 * last4[x] = x times P^128
* where x and last4[x] are seen as elements of GF(2^128) as in [MGV] * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
*/ */
static const uint64_t last4[16] = static const uint16_t last4[16] =
{ {
0x0000, 0x1c20, 0x3840, 0x2460, 0x0000, 0x1c20, 0x3840, 0x2460,
0x7080, 0x6ca0, 0x48c0, 0x54e0, 0x7080, 0x6ca0, 0x48c0, 0x54e0,

View file

@ -41,7 +41,7 @@
#include "mbedtls/lms.h" #include "mbedtls/lms.h"
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#include "psa/crypto.h" #include "psa/crypto.h"
@ -438,8 +438,10 @@ int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
} }
ctx->params.type = ctx->params.type =
mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN, (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET); MBEDTLS_LMOTS_TYPE_LEN,
key +
MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) { if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;

View file

@ -39,7 +39,7 @@
#include "lmots.h" #include "lmots.h"
#include "psa/crypto.h" #include "psa/crypto.h"
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#include "mbedtls/lms.h" #include "mbedtls/lms.h"
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
@ -249,8 +249,10 @@ int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
mbedtls_lms_algorithm_type_t type; mbedtls_lms_algorithm_type_t type;
mbedtls_lmots_algorithm_type_t otstype; mbedtls_lmots_algorithm_type_t otstype;
type = mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMS_TYPE_LEN, type = (mbedtls_lms_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
key + PUBLIC_KEY_TYPE_OFFSET); MBEDTLS_LMS_TYPE_LEN,
key +
PUBLIC_KEY_TYPE_OFFSET);
if (type != MBEDTLS_LMS_SHA256_M32_H10) { if (type != MBEDTLS_LMS_SHA256_M32_H10) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
@ -260,8 +262,10 @@ int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
otstype = mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN, otstype = (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
key + PUBLIC_KEY_OTSTYPE_OFFSET); MBEDTLS_LMOTS_TYPE_LEN,
key +
PUBLIC_KEY_OTSTYPE_OFFSET);
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) { if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA; return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
} }
@ -537,9 +541,8 @@ static int get_merkle_path(mbedtls_lms_private_t *ctx,
ret = 0; ret = 0;
exit: exit:
mbedtls_platform_zeroize(tree, node_bytes * mbedtls_zeroize_and_free(tree, node_bytes *
MERKLE_TREE_NODE_AM(ctx->params.type)); MERKLE_TREE_NODE_AM(ctx->params.type));
mbedtls_free(tree);
return ret; return ret;
} }
@ -700,9 +703,8 @@ int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
ret = 0; ret = 0;
exit: exit:
mbedtls_platform_zeroize(tree, node_bytes * mbedtls_zeroize_and_free(tree, node_bytes *
MERKLE_TREE_NODE_AM(priv_ctx->params.type)); MERKLE_TREE_NODE_AM(priv_ctx->params.type));
mbedtls_free(tree);
return ret; return ret;
} }

View file

@ -56,7 +56,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h> #include <psa/crypto.h>
#include "md_psa.h" #include "md_psa.h"
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#endif #endif
#if defined(MBEDTLS_MD_SOME_PSA) #if defined(MBEDTLS_MD_SOME_PSA)
@ -76,102 +76,75 @@
#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE" #error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE"
#endif #endif
#if defined(MBEDTLS_MD_C)
#define MD_INFO(type, out_size, block_size) type, out_size, block_size,
#else
#define MD_INFO(type, out_size, block_size) type, out_size,
#endif
#if defined(MBEDTLS_MD_CAN_MD5) #if defined(MBEDTLS_MD_CAN_MD5)
const mbedtls_md_info_t mbedtls_md5_info = { static const mbedtls_md_info_t mbedtls_md5_info = {
"MD5", MD_INFO(MBEDTLS_MD_MD5, 16, 64)
MBEDTLS_MD_MD5,
16,
64,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160) #if defined(MBEDTLS_MD_CAN_RIPEMD160)
const mbedtls_md_info_t mbedtls_ripemd160_info = { static const mbedtls_md_info_t mbedtls_ripemd160_info = {
"RIPEMD160", MD_INFO(MBEDTLS_MD_RIPEMD160, 20, 64)
MBEDTLS_MD_RIPEMD160,
20,
64,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA1) #if defined(MBEDTLS_MD_CAN_SHA1)
const mbedtls_md_info_t mbedtls_sha1_info = { static const mbedtls_md_info_t mbedtls_sha1_info = {
"SHA1", MD_INFO(MBEDTLS_MD_SHA1, 20, 64)
MBEDTLS_MD_SHA1,
20,
64,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA224) #if defined(MBEDTLS_MD_CAN_SHA224)
const mbedtls_md_info_t mbedtls_sha224_info = { static const mbedtls_md_info_t mbedtls_sha224_info = {
"SHA224", MD_INFO(MBEDTLS_MD_SHA224, 28, 64)
MBEDTLS_MD_SHA224,
28,
64,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA256) #if defined(MBEDTLS_MD_CAN_SHA256)
const mbedtls_md_info_t mbedtls_sha256_info = { static const mbedtls_md_info_t mbedtls_sha256_info = {
"SHA256", MD_INFO(MBEDTLS_MD_SHA256, 32, 64)
MBEDTLS_MD_SHA256,
32,
64,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA384) #if defined(MBEDTLS_MD_CAN_SHA384)
const mbedtls_md_info_t mbedtls_sha384_info = { static const mbedtls_md_info_t mbedtls_sha384_info = {
"SHA384", MD_INFO(MBEDTLS_MD_SHA384, 48, 128)
MBEDTLS_MD_SHA384,
48,
128,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA512) #if defined(MBEDTLS_MD_CAN_SHA512)
const mbedtls_md_info_t mbedtls_sha512_info = { static const mbedtls_md_info_t mbedtls_sha512_info = {
"SHA512", MD_INFO(MBEDTLS_MD_SHA512, 64, 128)
MBEDTLS_MD_SHA512,
64,
128,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA3_224) #if defined(MBEDTLS_MD_CAN_SHA3_224)
const mbedtls_md_info_t mbedtls_sha3_224_info = { static const mbedtls_md_info_t mbedtls_sha3_224_info = {
"SHA3-224", MD_INFO(MBEDTLS_MD_SHA3_224, 28, 144)
MBEDTLS_MD_SHA3_224,
28,
144,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA3_256) #if defined(MBEDTLS_MD_CAN_SHA3_256)
const mbedtls_md_info_t mbedtls_sha3_256_info = { static const mbedtls_md_info_t mbedtls_sha3_256_info = {
"SHA3-256", MD_INFO(MBEDTLS_MD_SHA3_256, 32, 136)
MBEDTLS_MD_SHA3_256,
32,
136,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA3_384) #if defined(MBEDTLS_MD_CAN_SHA3_384)
const mbedtls_md_info_t mbedtls_sha3_384_info = { static const mbedtls_md_info_t mbedtls_sha3_384_info = {
"SHA3-384", MD_INFO(MBEDTLS_MD_SHA3_384, 48, 104)
MBEDTLS_MD_SHA3_384,
48,
104,
}; };
#endif #endif
#if defined(MBEDTLS_MD_CAN_SHA3_512) #if defined(MBEDTLS_MD_CAN_SHA3_512)
const mbedtls_md_info_t mbedtls_sha3_512_info = { static const mbedtls_md_info_t mbedtls_sha3_512_info = {
"SHA3-512", MD_INFO(MBEDTLS_MD_SHA3_512, 64, 72)
MBEDTLS_MD_SHA3_512,
64,
72,
}; };
#endif #endif
@ -346,9 +319,8 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx)
#if defined(MBEDTLS_MD_C) #if defined(MBEDTLS_MD_C)
if (ctx->hmac_ctx != NULL) { if (ctx->hmac_ctx != NULL) {
mbedtls_platform_zeroize(ctx->hmac_ctx, mbedtls_zeroize_and_free(ctx->hmac_ctx,
2 * ctx->md_info->block_size); 2 * ctx->md_info->block_size);
mbedtls_free(ctx->hmac_ctx);
} }
#endif #endif
@ -786,78 +758,6 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
} }
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
{
switch (md_type) {
#if defined(MBEDTLS_MD_CAN_MD5)
case MBEDTLS_MD_MD5:
return PSA_ALG_MD5;
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
case MBEDTLS_MD_RIPEMD160:
return PSA_ALG_RIPEMD160;
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
case MBEDTLS_MD_SHA1:
return PSA_ALG_SHA_1;
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
case MBEDTLS_MD_SHA224:
return PSA_ALG_SHA_224;
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
case MBEDTLS_MD_SHA256:
return PSA_ALG_SHA_256;
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
case MBEDTLS_MD_SHA384:
return PSA_ALG_SHA_384;
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
case MBEDTLS_MD_SHA512:
return PSA_ALG_SHA_512;
#endif
default:
return PSA_ALG_NONE;
}
}
mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
{
switch (psa_alg) {
#if defined(MBEDTLS_MD_CAN_MD5)
case PSA_ALG_MD5:
return MBEDTLS_MD_MD5;
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
case PSA_ALG_RIPEMD160:
return MBEDTLS_MD_RIPEMD160;
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
case PSA_ALG_SHA_1:
return MBEDTLS_MD_SHA1;
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
case PSA_ALG_SHA_224:
return MBEDTLS_MD_SHA224;
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
case PSA_ALG_SHA_256:
return MBEDTLS_MD_SHA256;
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
case PSA_ALG_SHA_384:
return MBEDTLS_MD_SHA384;
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
case PSA_ALG_SHA_512:
return MBEDTLS_MD_SHA512;
#endif
default:
return MBEDTLS_MD_NONE;
}
}
int mbedtls_md_error_from_psa(psa_status_t status) int mbedtls_md_error_from_psa(psa_status_t status)
{ {
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors, return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors,
@ -928,69 +828,77 @@ const int *mbedtls_md_list(void)
return supported_digests; return supported_digests;
} }
typedef struct {
const char *md_name;
mbedtls_md_type_t md_type;
} md_name_entry;
static const md_name_entry md_names[] = {
#if defined(MBEDTLS_MD_CAN_MD5)
{ "MD5", MBEDTLS_MD_MD5 },
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
{ "RIPEMD160", MBEDTLS_MD_RIPEMD160 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
{ "SHA1", MBEDTLS_MD_SHA1 },
{ "SHA", MBEDTLS_MD_SHA1 }, // compatibility fallback
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
{ "SHA224", MBEDTLS_MD_SHA224 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
{ "SHA256", MBEDTLS_MD_SHA256 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
{ "SHA384", MBEDTLS_MD_SHA384 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
{ "SHA512", MBEDTLS_MD_SHA512 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
{ "SHA3-224", MBEDTLS_MD_SHA3_224 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
{ "SHA3-256", MBEDTLS_MD_SHA3_256 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
{ "SHA3-384", MBEDTLS_MD_SHA3_384 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
{ "SHA3-512", MBEDTLS_MD_SHA3_512 },
#endif
{ NULL, MBEDTLS_MD_NONE },
};
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
{ {
if (NULL == md_name) { if (NULL == md_name) {
return NULL; return NULL;
} }
/* Get the appropriate digest information */ const md_name_entry *entry = md_names;
#if defined(MBEDTLS_MD_CAN_MD5) while (entry->md_name != NULL &&
if (!strcmp("MD5", md_name)) { strcmp(entry->md_name, md_name) != 0) {
return mbedtls_md_info_from_type(MBEDTLS_MD_MD5); ++entry;
} }
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160) return mbedtls_md_info_from_type(entry->md_type);
if (!strcmp("RIPEMD160", md_name)) { }
return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
{
if (md_info == NULL) {
return NULL;
} }
#endif
#if defined(MBEDTLS_MD_CAN_SHA1) const md_name_entry *entry = md_names;
if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) { while (entry->md_type != MBEDTLS_MD_NONE &&
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); entry->md_type != md_info->type) {
++entry;
} }
#endif
#if defined(MBEDTLS_MD_CAN_SHA224) return entry->md_name;
if (!strcmp("SHA224", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
if (!strcmp("SHA256", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
if (!strcmp("SHA384", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
if (!strcmp("SHA512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
if (!strcmp("SHA3-224", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_224);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
if (!strcmp("SHA3-256", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_256);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
if (!strcmp("SHA3-384", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_384);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
if (!strcmp("SHA3-512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_512);
}
#endif
return NULL;
} }
const mbedtls_md_info_t *mbedtls_md_info_from_ctx( const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
@ -1191,15 +1099,6 @@ cleanup:
return ret; return ret;
} }
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
{
if (md_info == NULL) {
return NULL;
}
return md_info->name;
}
#endif /* MBEDTLS_MD_C */ #endif /* MBEDTLS_MD_C */
#endif /* MBEDTLS_MD_LIGHT */ #endif /* MBEDTLS_MD_LIGHT */

View file

@ -31,12 +31,21 @@
* \brief This function returns the PSA algorithm identifier * \brief This function returns the PSA algorithm identifier
* associated with the given digest type. * associated with the given digest type.
* *
* \param md_type The type of digest to search for. * \param md_type The type of digest to search for. Must not be NONE.
* *
* \return The PSA algorithm identifier associated with \p md_type. * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will
* \return PSA_ALG_NONE if the algorithm is not supported. * not return \c PSA_ALG_NONE, but an invalid algorithm.
*
* \warning This function does not check if the algorithm is
* supported, it always returns the corresponding identifier.
*
* \return The PSA algorithm identifier associated with \p md_type,
* regardless of whether it is supported or not.
*/ */
psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
{
return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type;
}
/** /**
* \brief This function returns the given digest type * \brief This function returns the given digest type
@ -44,10 +53,16 @@ psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type);
* *
* \param psa_alg The PSA algorithm identifier to search for. * \param psa_alg The PSA algorithm identifier to search for.
* *
* \return The MD type associated with \p psa_alg. * \warning This function does not check if the algorithm is
* \return MBEDTLS_MD_NONE if the algorithm is not supported. * supported, it always returns the corresponding identifier.
*
* \return The MD type associated with \p psa_alg,
* regardless of whether it is supported or not.
*/ */
mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg); static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
/** Convert PSA status to MD error code. /** Convert PSA status to MD error code.
* *

View file

@ -39,47 +39,18 @@ extern "C" {
* Allows message digest functions to be called in a generic way. * Allows message digest functions to be called in a generic way.
*/ */
struct mbedtls_md_info_t { struct mbedtls_md_info_t {
/** Name of the message digest */
const char *name;
/** Digest identifier */ /** Digest identifier */
mbedtls_md_type_t type; mbedtls_md_type_t type;
/** Output length of the digest function in bytes */ /** Output length of the digest function in bytes */
unsigned char size; unsigned char size;
#if defined(MBEDTLS_MD_C)
/** Block length of the digest function in bytes */ /** Block length of the digest function in bytes */
unsigned char block_size; unsigned char block_size;
#endif
}; };
#if defined(MBEDTLS_MD5_C)
extern const mbedtls_md_info_t mbedtls_md5_info;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
extern const mbedtls_md_info_t mbedtls_ripemd160_info;
#endif
#if defined(MBEDTLS_SHA1_C)
extern const mbedtls_md_info_t mbedtls_sha1_info;
#endif
#if defined(MBEDTLS_SHA224_C)
extern const mbedtls_md_info_t mbedtls_sha224_info;
#endif
#if defined(MBEDTLS_SHA256_C)
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif
#if defined(MBEDTLS_SHA384_C)
extern const mbedtls_md_info_t mbedtls_sha384_info;
#endif
#if defined(MBEDTLS_SHA512_C)
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
#if defined(MBEDTLS_SHA3_C)
extern const mbedtls_md_info_t mbedtls_sha3_224_info;
extern const mbedtls_md_info_t mbedtls_sha3_256_info;
extern const mbedtls_md_info_t mbedtls_sha3_384_info;
extern const mbedtls_md_info_t mbedtls_sha3_512_info;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -49,11 +49,6 @@
#define IS_EINTR(ret) ((ret) == WSAEINTR) #define IS_EINTR(ret) ((ret) == WSAEINTR)
#if !defined(_WIN32_WINNT)
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
#endif
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <winsock2.h> #include <winsock2.h>
@ -90,6 +85,7 @@ static int wsa_init_done = 0;
#include <errno.h> #include <errno.h>
#define IS_EINTR(ret) ((ret) == EINTR) #define IS_EINTR(ret) ((ret) == EINTR)
#define SOCKET int
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
@ -494,13 +490,13 @@ int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout)
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
if (rw & MBEDTLS_NET_POLL_READ) { if (rw & MBEDTLS_NET_POLL_READ) {
rw &= ~MBEDTLS_NET_POLL_READ; rw &= ~MBEDTLS_NET_POLL_READ;
FD_SET(fd, &read_fds); FD_SET((SOCKET) fd, &read_fds);
} }
FD_ZERO(&write_fds); FD_ZERO(&write_fds);
if (rw & MBEDTLS_NET_POLL_WRITE) { if (rw & MBEDTLS_NET_POLL_WRITE) {
rw &= ~MBEDTLS_NET_POLL_WRITE; rw &= ~MBEDTLS_NET_POLL_WRITE;
FD_SET(fd, &write_fds); FD_SET((SOCKET) fd, &write_fds);
} }
if (rw != 0) { if (rw != 0) {
@ -608,7 +604,7 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf,
} }
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
FD_SET(fd, &read_fds); FD_SET((SOCKET) fd, &read_fds);
tv.tv_sec = timeout / 1000; tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000; tv.tv_usec = (timeout % 1000) * 1000;

View file

@ -75,7 +75,7 @@ int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx,
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }
if (cipher_info->block_size != 16) { if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
} }

View file

@ -406,16 +406,14 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
} }
if ((ret = mbedtls_base64_decode(buf, len, &len, s1, s2 - s1)) != 0) { if ((ret = mbedtls_base64_decode(buf, len, &len, s1, s2 - s1)) != 0) {
mbedtls_platform_zeroize(buf, len); mbedtls_zeroize_and_free(buf, len);
mbedtls_free(buf);
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret); return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret);
} }
if (enc != 0) { if (enc != 0) {
#if defined(PEM_RFC1421) #if defined(PEM_RFC1421)
if (pwd == NULL) { if (pwd == NULL) {
mbedtls_platform_zeroize(buf, len); mbedtls_zeroize_and_free(buf, len);
mbedtls_free(buf);
return MBEDTLS_ERR_PEM_PASSWORD_REQUIRED; return MBEDTLS_ERR_PEM_PASSWORD_REQUIRED;
} }
@ -451,13 +449,11 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
* Use that as a heuristic to try to detect password mismatches. * Use that as a heuristic to try to detect password mismatches.
*/ */
if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) { if (len <= 2 || buf[0] != 0x30 || buf[1] > 0x83) {
mbedtls_platform_zeroize(buf, len); mbedtls_zeroize_and_free(buf, len);
mbedtls_free(buf);
return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH; return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH;
} }
#else #else
mbedtls_platform_zeroize(buf, len); mbedtls_zeroize_and_free(buf, len);
mbedtls_free(buf);
return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE;
#endif /* PEM_RFC1421 */ #endif /* PEM_RFC1421 */
} }
@ -471,8 +467,7 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
void mbedtls_pem_free(mbedtls_pem_context *ctx) void mbedtls_pem_free(mbedtls_pem_context *ctx)
{ {
if (ctx->buf != NULL) { if (ctx->buf != NULL) {
mbedtls_platform_zeroize(ctx->buf, ctx->buflen); mbedtls_zeroize_and_free(ctx->buf, ctx->buflen);
mbedtls_free(ctx->buf);
} }
mbedtls_free(ctx->info); mbedtls_free(ctx->info);

View file

@ -39,7 +39,7 @@
#endif #endif
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#include "md_psa.h" #include "md_psa.h"
#endif #endif
@ -181,10 +181,13 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
type = psa_get_key_type(&attributes); type = psa_get_key_type(&attributes);
psa_reset_key_attributes(&attributes); psa_reset_key_attributes(&attributes);
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
info = &mbedtls_pk_ecdsa_opaque_info; info = &mbedtls_ecdsa_opaque_info;
} else if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { } else
info = &mbedtls_pk_rsa_opaque_info; #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
info = &mbedtls_rsa_opaque_info;
} else { } else {
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
} }

View file

@ -34,7 +34,7 @@
#endif #endif
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) #define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status)
#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ #define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
psa_to_pk_rsa_errors, \ psa_to_pk_rsa_errors, \

File diff suppressed because it is too large Load diff

View file

@ -134,8 +134,8 @@ extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
#endif #endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
extern const mbedtls_pk_info_t mbedtls_pk_ecdsa_opaque_info; extern const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info;
extern const mbedtls_pk_info_t mbedtls_pk_rsa_opaque_info; extern const mbedtls_pk_info_t mbedtls_rsa_opaque_info;
#if !defined(MBEDTLS_DEPRECATED_REMOVED) #if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) #if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
@ -150,9 +150,9 @@ int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_ecdsa(psa_status_t status);
int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa(psa_status_t status); int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa(psa_status_t status);
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ #if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_rsa(psa_status_t status); int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_rsa(psa_status_t status);
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY */ #endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#endif /* !MBEDTLS_DEPRECATED_REMOVED */ #endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_RSA_C) #if defined(MBEDTLS_RSA_C)

View file

@ -39,7 +39,7 @@
#include "mbedtls/des.h" #include "mbedtls/des.h"
#endif #endif
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
@ -151,11 +151,11 @@ int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE; return MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE;
} }
keylen = cipher_info->key_bitlen / 8; keylen = (int) mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen, if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen,
key, keylen, key, keylen,
iv, cipher_info->iv_size)) != 0) { iv, mbedtls_cipher_info_get_iv_size(cipher_info))) != 0) {
return ret; return ret;
} }
@ -171,7 +171,9 @@ int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
goto exit; goto exit;
} }
if ((ret = mbedtls_cipher_set_iv(&cipher_ctx, iv, cipher_info->iv_size)) != 0) { if ((ret =
mbedtls_cipher_set_iv(&cipher_ctx, iv,
mbedtls_cipher_info_get_iv_size(cipher_info))) != 0) {
goto exit; goto exit;
} }

View file

@ -44,7 +44,7 @@
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)
static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params,
@ -176,10 +176,10 @@ int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
* The value of keylen from pkcs5_parse_pbkdf2_params() is ignored * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
* since it is optional and we don't know if it was set or not * since it is optional and we don't know if it was set or not
*/ */
keylen = cipher_info->key_bitlen / 8; keylen = (int) mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
if (enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || if (enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
enc_scheme_params.len != cipher_info->iv_size) { enc_scheme_params.len != mbedtls_cipher_info_get_iv_size(cipher_info)) {
return MBEDTLS_ERR_PKCS5_INVALID_FORMAT; return MBEDTLS_ERR_PKCS5_INVALID_FORMAT;
} }

View file

@ -54,7 +54,7 @@
#endif #endif
#if defined(MBEDTLS_PSA_CRYPTO_C) #if defined(MBEDTLS_PSA_CRYPTO_C)
#include "mbedtls/psa_util.h" #include "psa_util_internal.h"
#endif #endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -107,8 +107,7 @@ int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n)
if (fread(*buf, 1, *n, f) != *n) { if (fread(*buf, 1, *n, f) != *n) {
fclose(f); fclose(f);
mbedtls_platform_zeroize(*buf, *n); mbedtls_zeroize_and_free(*buf, *n);
mbedtls_free(*buf);
return MBEDTLS_ERR_PK_FILE_IO_ERROR; return MBEDTLS_ERR_PK_FILE_IO_ERROR;
} }
@ -146,8 +145,7 @@ int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
(const unsigned char *) pwd, strlen(pwd), f_rng, p_rng); (const unsigned char *) pwd, strlen(pwd), f_rng, p_rng);
} }
mbedtls_platform_zeroize(buf, n); mbedtls_zeroize_and_free(buf, n);
mbedtls_free(buf);
return ret; return ret;
} }
@ -167,8 +165,7 @@ int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path)
ret = mbedtls_pk_parse_public_key(ctx, buf, n); ret = mbedtls_pk_parse_public_key(ctx, buf, n);
mbedtls_platform_zeroize(buf, n); mbedtls_zeroize_and_free(buf, n);
mbedtls_free(buf);
return ret; return ret;
} }
@ -654,7 +651,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk);
if ((ret = mbedtls_mpi_read_binary_le(&eck->d, key, len)) != 0) { if ((ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, len)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
} }
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
@ -666,14 +663,6 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk,
return ret; return ret;
} }
/* When MBEDTLS_PK_USE_PSA_EC_DATA the key is checked while importing it
* into PSA. */
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
return ret;
}
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0; return 0;
} }
#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ #endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */
@ -1217,15 +1206,11 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
} }
/* Keep a reference to the position fo the private key. It will be used
* later in this function. */
d = p; d = p;
d_len = len; d_len = len;
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_mpi_read_binary(&eck->d, p, len)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
#endif
p += len; p += len;
pubkey_done = 0; pubkey_done = 0;
@ -1245,6 +1230,13 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
} }
} }
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_read_key(eck->grp.id, eck, d, d_len)) != 0) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
}
#endif
if (p != end) { if (p != end) {
/* /*
* Is 'publickey' present? If not, or if we can't read it (eg because it * Is 'publickey' present? If not, or if we can't read it (eg because it
@ -1307,12 +1299,6 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk,
} }
} }
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) {
return ret;
}
#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
return 0; return 0;
} }
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
@ -1697,8 +1683,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
ret = pk_parse_key_pkcs8_encrypted_der(pk, key_copy, keylen, ret = pk_parse_key_pkcs8_encrypted_der(pk, key_copy, keylen,
pwd, pwdlen, f_rng, p_rng); pwd, pwdlen, f_rng, p_rng);
mbedtls_platform_zeroize(key_copy, keylen); mbedtls_zeroize_and_free(key_copy, keylen);
mbedtls_free(key_copy);
} }
if (ret == 0) { if (ret == 0) {

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