Merge remote-tracking branch 'origin/development' into update-restricted-2023-08-30

This commit is contained in:
Dave Rodgman 2023-08-30 11:22:00 +01:00
commit 730bbee226
315 changed files with 16246 additions and 9989 deletions

2
.gitignore vendored
View file

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

View file

@ -32,6 +32,10 @@ jobs:
packages:
- clang-10
- gnutls-bin
env:
# Platform tests have an allocation that returns null
- ASAN_OPTIONS="allocator_may_return_null=1"
- MSAN_OPTIONS="allocator_may_return_null=1"
script:
# Do a manual build+test sequence rather than using all.sh,
# because there's no all.sh component that does what we want,
@ -89,6 +93,10 @@ jobs:
apt:
packages:
- gcc
env:
# Platform tests have an allocation that returns null
- ASAN_OPTIONS="allocator_may_return_null=1"
- MSAN_OPTIONS="allocator_may_return_null=1"
script:
# Do a manual build+test sequence rather than using all.sh.
#
@ -115,6 +123,10 @@ jobs:
packages:
- clang
- gnutls-bin
env:
# Platform tests have an allocation that returns null
- ASAN_OPTIONS="allocator_may_return_null=1"
- MSAN_OPTIONS="allocator_may_return_null=1"
script:
# Do a manual build+test sequence rather than using all.sh.
#
@ -129,6 +141,30 @@ jobs:
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
- name: Arm64 accelerators tests on arm64 host
os: linux
dist: focal
arch: arm64
addons:
apt:
packages:
- gcc
script:
# Do a manual build+test sequence rather than using all.sh.
#
# This is arm64 host only test for no runtime detection case. Internal
# and Open CI do not include Arm64 host, and they check if components
# are be tested. As result, it will always fail on `pre-test-check` in
# them.
- scripts/config.py unset MBEDTLS_AESNI_C
- scripts/config.py unset MBEDTLS_PADLOCK_C
- scripts/config.py set MBEDTLS_AESCE_C
- scripts/config.py set MBEDTLS_AES_USE_HARDWARE_ONLY
- make generated_files
- make
- programs/test/selftest aes | grep "using AESCE"
- tests/context-info.sh
after_failure:
- tests/scripts/travis-log-failure.sh

View file

@ -199,10 +199,12 @@ static uint64_t u32_muladd64(uint32_t x, uint32_t y, uint32_t z, uint32_t t);
* Currently assembly optimisations are only supported with GCC/Clang for
* Arm's Cortex-A and Cortex-M lines of CPUs, which start with the v6-M and
* v7-M architectures. __ARM_ARCH_PROFILE is not defined for v6 and earlier.
* Thumb and 32-bit assembly is supported; aarch64 is not supported.
*/
#if defined(__GNUC__) &&\
defined(__ARM_ARCH) && __ARM_ARCH >= 6 && defined(__ARM_ARCH_PROFILE) && \
( __ARM_ARCH_PROFILE == 77 || __ARM_ARCH_PROFILE == 65 ) /* 'M' or 'A' */
( __ARM_ARCH_PROFILE == 77 || __ARM_ARCH_PROFILE == 65 ) /* 'M' or 'A' */ && \
!defined(__aarch64__)
/*
* This set of CPUs is conveniently partitioned as follows:

View file

@ -226,7 +226,9 @@ if(CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_COMPILER_IS_CLANG)
if(CMAKE_COMPILER_IS_IAR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts -Ohz")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts")
set(CMAKE_C_FLAGS_RELEASE "-Ohz")
set(CMAKE_C_FLAGS_DEBUG "--debug -On")
endif(CMAKE_COMPILER_IS_IAR)
if(CMAKE_COMPILER_IS_MSVC)
@ -372,7 +374,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
VERSION 3.4.0)
VERSION 3.4.1)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"

View file

@ -84,8 +84,14 @@ Mbed TLS is well documented, but if you think documentation is needed, speak out
License and Copyright
---------------------
All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible. For licensing details, please see the [License section of the README](README.md#License).
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See the [LICENSE](LICENSE) file for the full text of this license.
Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 or GPL-2.0-or-later licenses.
All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible.
The copyright on contributions is retained by the original authors of the code. Where possible for new files, this should be noted in a comment at the top of the file in the form: "Copyright The Mbed TLS Contributors".
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and be subject to the same Apache 2.0 license. This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and is submitted under both the Apache-2.0 AND GPL-2.0-or-later licenses.
This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.

View file

@ -1,5 +1,13 @@
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
Default behavior changes

View file

@ -21,6 +21,9 @@ We generally don't include changelog entries for:
* Performance improvements, unless they are particularly significant.
* Changes to parts of the code base that users don't interact with directly,
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.
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
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
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy. Here yyy can be: USE, IMPORT,
EXPORT, GENERATE, DERIVE. The goal is to have a finer detail about the
capabilities of the PSA side for either key.
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy. Here yyy can be: BASIC,
IMPORT, EXPORT, GENERATE, DERIVE. The goal is to have a finer detail about
the capabilities of the PSA side for either key.
Features
* 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
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
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,6 @@
Features
* New configuration option MBEDTLS_AES_USE_HARDWARE_ONLY introduced. When
using CPU-accelerated AES (e.g., Arm Crypto Extensions), this option
disables the plain C implementation and the run-time detection for the
CPU feature, which reduces code size and avoids the vulnerability of the
plain C implementation.

View file

@ -0,0 +1,2 @@
Features
* Add support for PBKDF2-CMAC through the PSA API.

View file

@ -0,0 +1,3 @@
Features
* Add a possibility to generate CSR's with RCF822 and directoryName subtype
of subjectAltName extension in x509 certificates.

View file

@ -5,3 +5,6 @@ Features
MBEDTLS_USE_PSA_CRYPTO. Restartable/interruptible ECDHE operations in
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.
* 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,3 @@
Bugfix
* Fix some cases where mbedtls_mpi_mod_exp, RSA key construction or ECDSA
signature can silently return an incorrect result in low memory conditions.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix a potential corruption of the passed-in IV when mbedtls_aes_crypt_cbc()
is called with zero length and padlock is not enabled.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix compile failure due to empty enum in cipher_wrap.c, when building
with a very minimal configuration. Fixes #7625.

View file

@ -0,0 +1,2 @@
Bugfix
* Fix IAR compiler warnings.

View file

@ -0,0 +1,3 @@
Features
* The documentation of mbedtls_ecp_group now describes the optimized
representation of A for some curves. Fixes #8045.

View file

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

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,3 @@
Bugfix
* Don't try to include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE when
MBEDTLS_PSA_CRYPTO_CONFIG is disabled.

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

@ -0,0 +1,4 @@
Changes
* Use heap memory to allocate DER encoded RSA private key.
This reduces stack usage significantly for RSA signature
operations when MBEDTLS_PSA_CRYPTO_C is defined.

View file

@ -0,0 +1,4 @@
Bugfix
* Fix x509 certificate generation to conform to RFC 5480 / RFC 5758 when
using ECC key. The certificate was rejected by some crypto frameworks.
Fixes #2924.

View file

@ -307,13 +307,14 @@ When using drivers, you will generally want to enable two compilation options (s
License
-------
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See the [LICENSE](LICENSE) file for the full text of this license. Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 OR GPL-2.0-or-later licenses.
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See the [LICENSE](LICENSE) file for the full text of this license, and [the 'License and Copyright' section in the contributing guidelines](CONTRIBUTING.md#License-and-Copyright) for more information.
### Third-party code included in Mbed TLS
This project contains code from other projects. This code is located within the `3rdparty/` directory. The original license text is included within project subdirectories, and in source files. The projects are listed below:
* `3rdparty/everest/`: Files stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is also used by the project under the Apache 2.0 license. We do not plan to regularly update these files, so they may not contain fixes and improvements present in the upstream project.
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is also used by Mbed TLS under the Apache 2.0 license. We do not plan to regularly update these files, so they may not contain fixes and improvements present in the upstream project.
Contributing
------------

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

@ -116,4 +116,23 @@
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 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 */

View file

@ -43,8 +43,11 @@ record() {
fi
}
# save current HEAD
HEAD=$(git branch --show-current)
# save current HEAD.
# 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
cleanup

View file

@ -0,0 +1,284 @@
Thread safety of the PSA subsystem
==================================
## Requirements
### Backward compatibility requirement
Code that is currently working must keep working. There can be an exception for code that uses features that are advertised as experimental; for example, it would be annoying but ok to add extra requirements for drivers.
(In this section, “currently” means Mbed TLS releases without proper concurrency management: 3.0.0, 3.1.0, and any other subsequent 3.x version.)
In particular, if you either protect all PSA calls with a mutex, or only ever call PSA functions from a single thread, your application currently works and must keep working. If your application currently builds and works with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C` enabled, it must keep building and working.
As a consequence, we must not add a new platform requirement beyond mutexes for the base case. It would be ok to add new platform requirements if they're only needed for PSA drivers, or if they're only performance improvements.
Tempting platform requirements that we cannot add to the default `MBEDTLS_THREADING_C` include:
* Releasing a mutex from a different thread than the one that acquired it. This isn't even guaranteed to work with pthreads.
* New primitives such as semaphores or condition variables.
### Correctness out of the box
If you build with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C`, the code must be functionally correct: no race conditions, deadlocks or livelocks.
The [PSA Crypto API specification](https://armmbed.github.io/mbed-crypto/html/overview/conventions.html#concurrent-calls) defines minimum expectations for concurrent calls. They must work as if they had been executed one at a time, except that the following cases have undefined behavior:
* Destroying a key while it's in use.
* Concurrent calls using the same operation object. (An operation object may not be used by more than one thread at a time. But it can move from one thread to another between calls.)
* Overlap of an output buffer with an input or output of a concurrent call.
* Modification of an input buffer during a call.
Note that while the specification does not define the behavior in such cases, Mbed TLS can be used as a crypto service. It's acceptable if an application can mess itself up, but it is not acceptable if an application can mess up the crypto service. As a consequence, destroying a key while it's in use may violate the security property that all key material is erased as soon as `psa_destroy_key` returns, but it may not cause data corruption or read-after-free inside the key store.
### No spinning
The code must not spin on a potentially non-blocking task. For example, this is proscribed:
```
lock(m);
while (!its_my_turn) {
unlock(m);
lock(m);
}
```
Rationale: this can cause battery drain, and can even be a livelock (spinning forever), e.g. if the thread that might unblock this one has a lower priority.
### Driver requirements
At the time of writing, the driver interface specification does not consider multithreaded environments.
We need to define clear policies so that driver implementers know what to expect. Here are two possible policies at two ends of the spectrum; what is desirable is probably somewhere in between.
* Driver entry points may be called concurrently from multiple threads, even if they're using the same key, and even including destroying a key while an operation is in progress on it.
* At most one driver entry point is active at any given time.
A more reasonable policy could be:
* By default, each driver only has at most one entry point active at any given time. In other words, each driver has its own exclusive lock.
* Drivers have an optional `"thread_safe"` boolean property. If true, it allows concurrent calls to this driver.
* Even with a thread-safe driver, the core never starts the destruction of a key while there are operations in progress on it, and never performs concurrent calls on the same multipart operation.
### Long-term performance requirements
In the short term, correctness is the important thing. We can start with a global lock.
In the medium to long term, performing a slow or blocking operation (for example, a driver call, or an RSA decryption) should not block other threads, even if they're calling the same driver or using the same key object.
We may want to go directly to a more sophisticated approach because when a system works with a global lock, it's typically hard to get rid of it to get more fine-grained concurrency.
### Key destruction long-term requirements
As noted above in [“Correctness out of the box”](#correctness-out-of-the-box), when a key is destroyed, it's ok if `psa_destroy_key` allows copies of the key to live until ongoing operations using the key return. In the long term, it would be good to guarantee that `psa_destroy_key` wipes all copies of the key material.
#### Summary of guarantees when `psa_destroy_key` returns
* The key identifier doesn't exist. Rationale: this is a functional requirement for persistent keys: the caller can immediately create a new key with the same identifier.
* The resources from the key have been freed. Rationale: in a low-resource condition, this may be necessary for the caller to re-create a similar key, which should be possible.
* The call must not block indefinitely, and in particular cannot wait for an event that is triggered by application code such as calling an abort function. Rationale: this may not strictly be a functional requirement, but it is an expectation `psa_destroy_key` does not block forever due to another thread, which could potentially be another process on a multi-process system.
* In the long term, no copy of the key material exists. Rationale: this is a security requirement. We do not have this requirement yet, but we need to document this as a security weakness, and we would like to become compliant.
## Resources to protect
Analysis of the behavior of the PSA key store as of Mbed TLS 9202ba37b19d3ea25c8451fd8597fce69eaa6867.
### Global variables
* `psa_crypto_slot_management::global_data.key_slots[i]`: see [“Key slots”](#key-slots).
* `psa_crypto_slot_management::global_data.key_slots_initialized`:
* `psa_initialize_key_slots`: modification.
* `psa_wipe_all_key_slots`: modification.
* `psa_get_empty_key_slot`: read.
* `psa_get_and_lock_key_slot`: read.
* `psa_crypto::global_data.rng`: depends on the RNG implementation. See [“Random generator”](#random-generator).
* `psa_generate_random`: query.
* `mbedtls_psa_crypto_configure_entropy_sources` (only if `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled): setup. Only called from `psa_crypto_init` via `mbedtls_psa_random_init`, or from test code.
* `mbedtls_psa_crypto_free`: deinit.
* `psa_crypto_init`: seed (via `mbedtls_psa_random_seed`); setup via `mbedtls_psa_crypto_configure_entropy_sources.
* `psa_crypto::global_data.{initialized,rng_state}`: these are bit-fields and cannot be modified independently so they must be protected by the same mutex. The following functions access these fields:
* `mbedtls_psa_crypto_configure_entropy_sources` [`rng_state`] (only if `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled): read. Only called from `psa_crypto_init` via `mbedtls_psa_random_init`, or from test code.
* `mbedtls_psa_crypto_free`: modification.
* `psa_crypto_init`: modification.
* Many functions via `GUARD_MODULE_INITIALIZED`: read.
### Key slots
#### Key slot array traversal
“Occupied key slot” is determined by `psa_is_key_slot_occupied` based on `slot->attr.type`.
The following functions traverse the key slot array:
* `psa_get_and_lock_key_slot_in_memory`: reads `slot->attr.id`.
* `psa_get_and_lock_key_slot_in_memory`: calls `psa_lock_key_slot` on one occupied slot.
* `psa_get_empty_key_slot`: calls `psa_is_key_slot_occupied`.
* `psa_get_empty_key_slot`: calls `psa_wipe_key_slot` and more modifications on one occupied slot with no active user.
* `psa_get_empty_key_slot`: calls `psa_lock_key_slot` and more modification on one unoccupied slot.
* `psa_wipe_all_key_slots`: writes to all slots.
* `mbedtls_psa_get_stats`: reads from all slots.
#### Key slot state
The following functions modify a slot's usage state:
* `psa_lock_key_slot`: writes to `slot->lock_count`.
* `psa_unlock_key_slot`: writes to `slot->lock_count`.
* `psa_wipe_key_slot`: writes to `slot->lock_count`.
* `psa_destroy_key`: reads `slot->lock_count`, calls `psa_lock_key_slot`.
* `psa_wipe_all_key_slots`: writes to all slots.
* `psa_get_empty_key_slot`: writes to `slot->lock_count` and calls `psa_wipe_key_slot` and `psa_lock_key_slot` on one occupied slot with no active user; calls `psa_lock_key_slot` on one unoccupied slot.
* `psa_close_key`: reads `slot->lock_count`; calls `psa_get_and_lock_key_slot_in_memory`, `psa_wipe_key_slot` and `psa_unlock_key_slot`.
* `psa_purge_key`: reads `slot->lock_count`; calls `psa_get_and_lock_key_slot_in_memory`, `psa_wipe_key_slot` and `psa_unlock_key_slot`.
**slot->attr access:**
`psa_crypto_core.h`:
* `psa_key_slot_set_flags` - writes to attr.flags
* `psa_key_slot_set_bits_in_flags` - writes to attr.flags
* `psa_key_slot_clear_bits` - writes to attr.flags
* `psa_is_key_slot_occupied` - reads attr.type (but see “[Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied)”)
* `psa_key_slot_get_flags` - reads attr.flags
`psa_crypto_slot_management.c`:
* `psa_get_and_lock_key_slot_in_memory` - reads attr.id
* `psa_get_empty_key_slot` - reads attr.lifetime
* `psa_load_persistent_key_into_slot` - passes attr pointer to psa_load_persistent_key
* `psa_load_persistent_key` - reads attr.id and passes pointer to psa_parse_key_data_from_storage
* `psa_parse_key_data_from_storage` - writes to many attributes
* `psa_get_and_lock_key_slot` - writes to attr.id, attr.lifetime, and attr.policy.usage
* `psa_purge_key` - reads attr.lifetime, calls psa_wipe_key_slot
* `mbedtls_psa_get_stats` - reads attr.lifetime, attr.id
`psa_crypto.c`:
* `psa_get_and_lock_key_slot_with_policy` - reads attr.type, attr.policy.
* `psa_get_and_lock_transparent_key_slot_with_policy` - reads attr.lifetime
* `psa_destroy_key` - reads attr.lifetime, attr.id
* `psa_get_key_attributes` - copies all publicly available attributes of a key
* `psa_export_key` - copies attributes
* `psa_export_public_key` - reads attr.type, copies attributes
* `psa_start_key_creation` - writes to the whole attr structure
* `psa_validate_optional_attributes` - reads attr.type, attr.bits
* `psa_import_key` - reads attr.bits
* `psa_copy_key` - reads attr.bits, attr.type, attr.lifetime, attr.policy
* `psa_mac_setup` - copies whole attr structure
* `psa_mac_compute_internal` - copies whole attr structure
* `psa_verify_internal` - copies whole attr structure
* `psa_sign_internal` - copies whole attr structure, reads attr.type
* `psa_assymmetric_encrypt` - reads attr.type
* `psa_assymetric_decrypt` - reads attr.type
* `psa_cipher_setup` - copies whole attr structure, reads attr.type
* `psa_cipher_encrypt` - copies whole attr structure, reads attr.type
* `psa_cipher_decrypt` - copies whole attr structure, reads attr.type
* `psa_aead_encrypt` - copies whole attr structure
* `psa_aead_decrypt` - copies whole attr structure
* `psa_aead_setup` - copies whole attr structure
* `psa_generate_derived_key_internal` - reads attr.type, writes to and reads from attr.bits, copies whole attr structure
* `psa_key_derivation_input_key` - reads attr.type
* `psa_key_agreement_raw_internal` - reads attr.type and attr.bits
#### Determining whether a key slot is occupied
`psa_is_key_slot_occupied` currently uses the `attr.type` field to determine whether a key slot is occupied. This works because we maintain the invariant that an occupied slot contains key material. With concurrency, it is desirable to allow a key slot to be reserved, but not yet contain key material or even metadata. When creating a key, determining the key type can be costly, for example when loading a persistent key from storage or (not yet implemented) when importing or unwrapping a key using an interface that determines the key type from the data that it parses. So we should not need to hold the global key store lock while the key type is undetermined.
Instead, `psa_is_key_slot_occupied` should use the key identifier to decide whether a slot is occupied. The key identifier is always readily available: when allocating a slot for a persistent key, it's an input of the function that allocates the key slot; when allocating a slot for a volatile key, the identifier is calculated from the choice of slot.
#### Key slot content
Other than what is used to determine the [“key slot state”](#key-slot-state), the contents of a key slot are only accessed as follows:
* Modification during key creation (between `psa_start_key_creation` and `psa_finish_key_creation` or `psa_fail_key_creation`).
* Destruction in `psa_wipe_key_slot`.
* Read in many functions, between calls to `psa_lock_key_slot` and `psa_unlock_key_slot`.
**slot->key access:**
* `psa_allocate_buffer_to_slot` - allocates key.data, sets key.bytes;
* `psa_copy_key_material_into_slot` - writes to key.data
* `psa_remove_key_data_from_memory` - writes and reads to/from key data
* `psa_get_key_attributes` - reads from key data
* `psa_export_key` - passes key data to psa_driver_wrapper_export_key
* `psa_export_public_key` - passes key data to psa_driver_wrapper_export_public_key
* `psa_finish_key_creation` - passes key data to psa_save_persistent_key
* `psa_validate_optional_attributes` - passes key data and bytes to mbedtls_psa_rsa_load_representation
* `psa_import_key` - passes key data to psa_driver_wrapper_import_key
* `psa_copy_key` - passes key data to psa_driver_wrapper_copy_key, psa_copy_key_material_into_slot
* `psa_mac_setup` - passes key data to psa_driver_wrapper_mac_sign_setup, psa_driver_wrapper_mac_verify_setup
* `psa_mac_compute_internal` - passes key data to psa_driver_wrapper_mac_compute
* `psa_sign_internal` - passes key data to psa_driver_wrapper_sign_message, psa_driver_wrapper_sign_hash
* `psa_verify_internal` - passes key data to psa_driver_wrapper_verify_message, psa_driver_wrapper_verify_hash
* `psa_asymmetric_encrypt` - passes key data to mbedtls_psa_rsa_load_representation
* `psa_asymmetric_decrypt` - passes key data to mbedtls_psa_rsa_load_representation
* `psa_cipher_setup ` - passes key data to psa_driver_wrapper_cipher_encrypt_setup and psa_driver_wrapper_cipher_decrypt_setup
* `psa_cipher_encrypt` - passes key data to psa_driver_wrapper_cipher_encrypt
* `psa_cipher_decrypt` - passes key data to psa_driver_wrapper_cipher_decrypt
* `psa_aead_encrypt` - passes key data to psa_driver_wrapper_aead_encrypt
* `psa_aead_decrypt` - passes key data to psa_driver_wrapper_aead_decrypt
* `psa_aead_setup` - passes key data to psa_driver_wrapper_aead_encrypt_setup and psa_driver_wrapper_aead_decrypt_setup
* `psa_generate_derived_key_internal` - passes key data to psa_driver_wrapper_import_key
* `psa_key_derivation_input_key` - passes key data to psa_key_derivation_input_internal
* `psa_key_agreement_raw_internal` - passes key data to mbedtls_psa_ecp_load_representation
* `psa_generate_key` - passes key data to psa_driver_wrapper_generate_key
### Random generator
The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`.
With the built-in RNG implementations using `mbedtls_ctr_drbg_context` or `mbedtls_hmac_drbg_context`, querying the RNG with `mbedtls_xxx_drbg_random()` is thread-safe (protected by a mutex inside the RNG implementation), but other operations (init, free, seed) are not.
When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, thread safety depends on the implementation.
### Driver resources
Depends on the driver. The PSA driver interface specification does not discuss whether drivers must support concurrent calls.
## Simple global lock strategy
Have a single mutex protecting all accesses to the key store and other global variables. In practice, this means every PSA API function needs to take the lock on entry and release on exit, except for:
* Hash function.
* Accessors for key attributes and other local structures.
Note that operation functions do need to take the lock, since they need to prevent the destruction of the key.
Note that this does not protect access to the RNG via `mbedtls_psa_get_random`, which is guaranteed to be thread-safe when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled.
This approach is conceptually simple, but requires extra instrumentation to every function and has bad performance in a multithreaded environment since a slow operation in one thread blocks unrelated operations on other threads.
## Global lock excluding slot content
Have a single mutex protecting all accesses to the key store and other global variables, except that it's ok to access the content of a key slot without taking the lock if one of the following conditions holds:
* The key slot is in a state that guarantees that the thread has exclusive access.
* The key slot is in a state that guarantees that no other thread can modify the slot content, and the accessing thread is only reading the slot.
Note that a thread must hold the global mutex when it reads or changes a slot's state.
### Slot states
For concurrency purposes, a slot can be in one of three states:
* UNUSED: no thread is currently accessing the slot. It may be occupied by a volatile key or a cached key.
* WRITING: a thread has exclusive access to the slot. This can only happen in specific circumstances as detailed below.
* READING: any thread may read from the slot.
A high-level view of state transitions:
* `psa_get_empty_key_slot`: UNUSED → WRITING.
* `psa_get_and_lock_key_slot_in_memory`: UNUSED or READING → READING. This function only accepts slots in the UNUSED or READING state. A slot with the correct id but in the WRITING state is considered free.
* `psa_unlock_key_slot`: READING → UNUSED or READING.
* `psa_finish_key_creation`: WRITING → READING.
* `psa_fail_key_creation`: WRITING → UNUSED.
* `psa_wipe_key_slot`: any → UNUSED. If the slot is READING or WRITING on entry, this function must wait until the writer or all readers have finished. (By the way, the WRITING state is possible if `mbedtls_psa_crypto_free` is called while a key creation is in progress.) See [“Destruction of a key in use”](#destruction of a key in use).
The current `state->lock_count` corresponds to the difference between UNUSED and READING: a slot is in use iff its lock count is nonzero, so `lock_count == 0` corresponds to UNUSED and `lock_count != 0` corresponds to READING.
There is currently no indication of when a slot is in the WRITING state. This only happens between a call to `psa_start_key_creation` and a call to one of `psa_finish_key_creation` or `psa_fail_key_creation`. This new state can be conveyed by a new boolean flag, or by setting `lock_count` to `~0`.
### Destruction of a key in use
Problem: a key slot is destroyed (by `psa_wipe_key_slot`) while it's in use (READING or WRITING).
TODO: how do we ensure that? This needs something more sophisticated than mutexes (concurrency number >2)! Even a per-slot mutex isn't enough (we'd need a reader-writer lock).
Solution: after some team discussion, we've decided to rely on a new threading abstraction which mimics C11 (i.e. `mbedtls_fff` where `fff` is the C11 function name, having the same parameters and return type, with default implementations for C11, pthreads and Windows). We'll likely use condition variables in addition to mutexes.

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

@ -2,6 +2,7 @@ PSA Cryptoprocessor driver developer's guide
============================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
This document describes how to write drivers of cryptoprocessors such as accelerators and secure elements for the PSA cryptography subsystem of Mbed TLS.

View file

@ -2,6 +2,7 @@ Building Mbed TLS with PSA cryptoprocessor drivers
==================================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
This document describes how to build Mbed TLS with additional cryptoprocessor drivers that follow the PSA cryptoprocessor driver interface.

View file

@ -5,6 +5,8 @@ This document describes an interface for cryptoprocessor drivers in the PSA cryp
This specification is work in progress and should be considered to be in a beta stage. There is ongoing work to implement this interface in Mbed TLS, which is the reference implementation of the PSA Cryptography API. At this stage, Arm does not expect major changes, but minor changes are expected based on experience from the first implementation and on external feedback.
For a practical guide, with a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
## Introduction
### Purpose of the driver interface

View file

@ -1,11 +1,11 @@
Migrating to an auto generated psa_crypto_driver_wrappers.c file
================================================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.c file.
It is meant to give the library user migration guidelines while the Mbed TLS project tides over multiple minor revs of version 1.0, after which this will be merged into psa-driver-interface.md.
For a practical guide with a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
## Introduction
The design of the Driver Wrappers code generation is based on the design proposal https://github.com/Mbed-TLS/mbedtls/pull/5067

View file

@ -29,8 +29,8 @@ Auto-generation of the driver wrapper is supported for the operation entry point
| Transparent Driver | Opaque Driver |
|---------------------|---------------------|
| `import_key` | `import_key` |
| `export_key` | `export_key` |
| `export_public_key` | `export_public_key` |
| | `export_key` |
| | `copy_key` |
| | `get_builtin_key` |

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
* 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/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES
@ -51,4 +51,5 @@ PREDEFINED = "MBEDTLS_CHECK_RETURN_CRITICAL=" \
"MBEDTLS_CHECK_RETURN_TYPICAL=" \
"MBEDTLS_CHECK_RETURN_OPTIONAL=" \
"MBEDTLS_PRINTF_ATTRIBUTE(a,b)=" \
"__DOXYGEN__" \

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
* 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
* for both encryption and decryption operations. Therefore, you
* 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.
* \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
* 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
* SEQUENCE, after masking with \p tag_must_mask.
* 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
* 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
* 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
* SEQUENCE, after masking with \p tag_may_mask.
* Mismatching tags will be silently ignored.

View file

@ -544,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 buf The input buffer. This must be a readable buffer of length
* \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 #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@ -559,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 buf The input buffer. This must be a readable buffer of length
* \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 #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@ -999,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_BAD_INPUT_DATA if \p N is less than
* or equal to one.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
* with respect to \p N.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p A has no modular
* inverse with respect to \p N.
*/
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *N);

View file

@ -38,16 +38,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 4
#define MBEDTLS_VERSION_PATCH 0
#define MBEDTLS_VERSION_PATCH 1
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x03040000
#define MBEDTLS_VERSION_STRING "3.4.0"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.0"
#define MBEDTLS_VERSION_NUMBER 0x03040100
#define MBEDTLS_VERSION_STRING "3.4.1"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.1"
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
@ -59,6 +59,7 @@
#define inline __inline
#endif
/* X.509, TLS and non-PSA crypto configuration */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/mbedtls_config.h"
#else
@ -80,6 +81,18 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
/* PSA crypto configuration */
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
#else
#include "psa/crypto_config.h"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
#endif
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if
* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined
* to ensure a 128-bit key size in CTR_DRBG.
@ -161,6 +174,37 @@
#define MBEDTLS_PK_PARSE_EC_COMPRESSED
#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
* is defined as well to include all PSA code.
*/
@ -177,6 +221,14 @@
#define MBEDTLS_PK_PARSE_C
#endif
/* Helper symbol to state that the PK module has support for EC keys. This
* can either be provided through the legacy ECP solution or through the
* PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA (see pk.h for its description). */
#if defined(MBEDTLS_ECP_C) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
#define MBEDTLS_PK_HAVE_ECC_KEYS
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
/* The following blocks make it easier to disable all of TLS,
* or of TLS 1.2 or 1.3 or DTLS, without having to manually disable all
* key exchanges, options and extensions related to them. */
@ -222,16 +274,6 @@
#undef MBEDTLS_SSL_EARLY_DATA
#endif
#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
#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
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
(defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED))

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
* key for both encryption and decryption. In particular, calls
* 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.
*
* \warning You must never reuse a nonce value with the same key. Doing so

View file

@ -35,7 +35,7 @@
#include <stdint.h>
#if defined(_WIN32)
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
@ -51,7 +51,7 @@
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif
#endif /* _WIN32 */
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
#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"
@ -275,19 +275,6 @@
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#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(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#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 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
@ -299,17 +286,6 @@
#endif
#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(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#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 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ECC_SECP_R1_256)
@ -322,14 +298,14 @@
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#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) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@ -339,7 +315,7 @@
#endif
#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"
#endif
@ -350,14 +326,14 @@
#endif
#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) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
@ -436,10 +412,6 @@
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
@ -449,7 +421,7 @@
#endif
#if defined(MBEDTLS_PK_C) && \
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_LIGHT)
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
@ -814,8 +786,9 @@
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
( defined(MBEDTLS_PK_HAVE_ECDSA) || defined(MBEDTLS_PKCS1_V21) ) )
#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
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"
#endif
#endif
@ -1009,15 +982,15 @@
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
#if defined(MBEDTLS_X509_USE_C) && \
(!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) || \
( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
#if defined(MBEDTLS_X509_CREATE_C) && \
(!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_PARSE_C) || \
( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
@ -1122,16 +1095,14 @@
#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \
( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLS_PK_PARSE_C) ) || \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) ||\
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || ( !defined(MBEDTLS_BIGNUM_C) ) || \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || \
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || \
( !defined(MBEDTLS_MD_C) ) )
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
#endif
/* Undefine helper symbols */
#undef MBEDTLS_PK_HAVE_ECDSA
#undef MBEDTLS_PK_HAVE_JPAKE
#undef MBEDTLS_PK_HAVE_ECDH
#undef MBEDTLS_MD_HAVE_SHA256
#undef MBEDTLS_MD_HAVE_SHA384
#undef MBEDTLS_MD_HAVE_SHA512

View file

@ -505,7 +505,7 @@ static inline size_t mbedtls_cipher_info_get_key_bitlen(
*
* \return The cipher name, which is a human readable string,
* 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(
const mbedtls_cipher_info_t *info)
@ -596,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.
*/
@ -790,7 +790,7 @@ static inline const char *mbedtls_cipher_get_name(
* \param ctx The context of the cipher. This must be initialized.
*
* \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.
*/
static inline int mbedtls_cipher_get_key_bitlen(
@ -990,7 +990,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \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.
* This may not be \c NULL.
*

View file

@ -30,24 +30,8 @@
#ifndef MBEDTLS_CONFIG_PSA_H
#define MBEDTLS_CONFIG_PSA_H
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
#else
#include "psa/crypto_config.h"
#endif
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
#endif
#include "psa/crypto_legacy.h"
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************/
@ -273,6 +257,7 @@ extern "C" {
#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1
#define PSA_HAVE_SOFT_PBKDF2_HMAC
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
@ -438,13 +423,21 @@ extern "C" {
#define PSA_HAVE_SOFT_BLOCK_AEAD 1
#endif
#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128)
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 1
#define PSA_HAVE_SOFT_PBKDF2_CMAC
#endif /* !MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128 */
#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */
#if defined(PSA_WANT_KEY_TYPE_AES)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
#define PSA_HAVE_SOFT_KEY_TYPE_AES 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
defined(PSA_HAVE_SOFT_BLOCK_MODE) || \
defined(PSA_HAVE_SOFT_BLOCK_AEAD)
defined(PSA_HAVE_SOFT_BLOCK_AEAD) || \
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
#define MBEDTLS_AES_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
@ -515,12 +508,18 @@ extern "C" {
#if defined(PSA_WANT_ALG_CMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
defined(PSA_HAVE_SOFT_BLOCK_CIPHER) || \
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
#define MBEDTLS_CMAC_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */
#endif /* PSA_WANT_ALG_CMAC */
#if defined(PSA_HAVE_SOFT_PBKDF2_HMAC) || \
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
#define PSA_HAVE_SOFT_PBKDF2 1
#endif /* PSA_HAVE_SOFT_PBKDF2_HMAC || PSA_HAVE_SOFT_PBKDF2_CMAC */
#if defined(PSA_WANT_ALG_CTR)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
@ -834,14 +833,16 @@ extern "C" {
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define PSA_WANT_ALG_RSA_PSS 1
#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_IMPORT 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_IMPORT 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 PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
#endif /* MBEDTLS_RSA_C */
@ -1027,36 +1028,28 @@ extern "C" {
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#endif
/* Temporary internal migration helpers */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY
/* See description above */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#endif
/* Temporary internal migration helpers */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY
/* See description above */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#endif
/* Temporary internal migration helpers */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY
/* See description above */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#endif
/* Temporary internal migration helpers */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY
/* See description above */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#endif
/* These features are always enabled. */
@ -1065,8 +1058,4 @@ extern "C" {
#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CONFIG_PSA_H */

View file

@ -23,20 +23,22 @@
#include <stddef.h>
/** Constant-time buffer comparison without branches.
*
* This is equivalent to the standard memcmp function, but is likely to be
* compiled to code using bitwise operation rather than a branch.
* compiled to code using bitwise operations rather than a branch, such that
* the time taken is constant w.r.t. the data pointed to by \p a and \p b,
* and w.r.t. whether \p a and \p b are equal or not. It is not constant-time
* w.r.t. \p n .
*
* This function can be used to write constant-time code by replacing branches
* with bit operations using masks.
*
* \param a Pointer to the first buffer.
* \param b Pointer to the second buffer.
* \param n The number of bytes to compare in the buffer.
* \param a Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
* \param b Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
* \param n The number of bytes to compare.
*
* \return Zero if the content of the two buffer is the same,
* \return Zero if the contents of the two buffers are the same,
* otherwise non-zero.
*/
int mbedtls_ct_memcmp(const void *a,

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);
#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 {
MBEDTLS_DEBUG_ECDH_Q,
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 mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr);
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_C */
#ifdef __cplusplus
}

View file

@ -325,7 +325,7 @@ size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx);
* initialized.
*
* \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.
*/
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 f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This
* may be \c NULL if \p f_rng_blind doesn't need a context
* parameter.
*
* \return \c 0 on success.
* \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 f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be
* \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
* to disable restarting. If it is not \c NULL, it
* 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().
* \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
* buffer of length \p blen Bytes.
* buffer of length \p hlen 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
* 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().
* \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
* buffer of length \p blen Bytes.
* buffer of length \p hlen 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
* 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
* and have a group and public key bound to it.
* \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 sig The signature to read and verify. This must be a readable
* 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
* and have a group and public key bound to it.
* \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 sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.

View file

@ -197,6 +197,27 @@ mbedtls_ecp_point;
* odd prime as mbedtls_ecp_mul() requires an odd number, and
* mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
*
* The default implementation only initializes \p A without setting it to the
* authentic value for curves with <code>A = -3</code>(SECP256R1, etc), in which
* case you need to load \p A by yourself when using domain parameters directly,
* for example:
* \code
* mbedtls_mpi_init(&A);
* mbedtls_ecp_group_init(&grp);
* CHECK_RETURN(mbedtls_ecp_group_load(&grp, grp_id));
* if (mbedtls_ecp_group_a_is_minus_3(&grp)) {
* CHECK_RETURN(mbedtls_mpi_sub_int(&A, &grp.P, 3));
* } else {
* CHECK_RETURN(mbedtls_mpi_copy(&A, &grp.A));
* }
*
* do_something_with_a(&A);
*
* cleanup:
* mbedtls_mpi_free(&A);
* mbedtls_ecp_group_free(&grp);
* \endcode
*
* For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
* which is the quantity used in the formulas. Additionally, \p nbits is
* not the size of \p N but the required size for private keys.
@ -223,8 +244,11 @@ mbedtls_ecp_point;
typedef struct mbedtls_ecp_group {
mbedtls_ecp_group_id id; /*!< An internal group identifier. */
mbedtls_mpi P; /*!< The prime modulus of the base field. */
mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For
Montgomery curves: <code>(A + 2) / 4</code>. */
mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. Note that
\p A is not set to the authentic value in some cases.
Refer to detailed description of ::mbedtls_ecp_group if
using domain parameters in the structure.
For Montgomery curves: <code>(A + 2) / 4</code>. */
mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation.
For Montgomery curves: unused. */
mbedtls_ecp_point G; /*!< The generator of the subgroup used. */
@ -991,6 +1015,26 @@ int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_restart_ctx *rs_ctx);
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
* \brief This function checks if domain parameter A of the curve is
* \c -3.
*
* \note This function is only defined for short Weierstrass curves.
* It may not be included in builds without any short
* Weierstrass curve.
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
*
* \return \c 1 if <code>A = -3</code>.
* \return \c 0 Otherwise.
*/
static inline int mbedtls_ecp_group_a_is_minus_3(const mbedtls_ecp_group *grp)
{
return grp->A.MBEDTLS_PRIVATE(p) == NULL;
}
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@ -1083,7 +1127,7 @@ int mbedtls_ecp_muladd_restartable(
*
* It only checks that the point is non-zero, has
* 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
* by standards, and should not be necessary if the group
* used has a small cofactor. In particular, it is useless for
@ -1108,7 +1152,7 @@ int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp,
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.
*
* \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.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
* where \p entropy_len is the entropy length
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len * 3 / 2
* where \c entropy_len is the entropy length
* described above.
*
* \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.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
* where \p entropy_len is the entropy length
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* (see mbedtls_hmac_drbg_set_entropy_len()).
*
* \return \c 0 if successful.

View file

@ -172,15 +172,47 @@
* This allows different allocators (self-implemented or provided) to be
* provided to the platform abstraction layer.
*
* Enabling MBEDTLS_PLATFORM_MEMORY without the
* Enabling #MBEDTLS_PLATFORM_MEMORY without the
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
* free() function pointer at runtime.
*
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
* Enabling #MBEDTLS_PLATFORM_MEMORY and specifying
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
* alternate function at compile time.
*
* An overview of how the value of mbedtls_calloc is determined:
*
* - if !MBEDTLS_PLATFORM_MEMORY
* - mbedtls_calloc = calloc
* - if MBEDTLS_PLATFORM_MEMORY
* - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
* - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO
* - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
* - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC.
* - How is MBEDTLS_PLATFORM_STD_CALLOC handled?
* - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
* - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything;
* - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present;
* - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
* - if MBEDTLS_PLATFORM_STD_CALLOC is present:
* - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected;
* - if !MBEDTLS_PLATFORM_STD_CALLOC:
* - MBEDTLS_PLATFORM_STD_CALLOC = calloc
*
* - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked.
* - if !MBEDTLS_PLATFORM_STD_CALLOC
* - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc
*
* - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC.
*
* Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible.
* MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time.
* #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used,
* dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases.
* An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
* An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
*
* Requires: MBEDTLS_PLATFORM_C
*
* Enable this layer to allow use of alternative memory allocators.
@ -1283,8 +1315,8 @@
* );
* ```
* 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
* of random data and set \c *output_length to \p output_size.
* The function must fill the \c output buffer with \c output_size bytes
* of random data and set \c *output_length to \c output_size.
*
* Requires: MBEDTLS_PSA_CRYPTO_C
*
@ -1998,8 +2030,15 @@
* If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
* an alternative header to include instead of include/psa/crypto_config.h.
*
* This feature is still experimental and is not ready for production since
* it is not completed.
* \warning This option is experimental, in that the set of `PSA_WANT_XXX`
* symbols is not completely finalized yet, and the configuration
* tooling is not ideally adapted to having two separate configuration
* files.
* Future minor releases of Mbed TLS may make minor changes to those
* symbols, but we will endeavor to provide a transition path.
* Nonetheless, this option is considered mature enough to use in
* production, as long as you accept that you may need to make
* minor changes to psa/crypto_config.h when upgrading Mbed TLS.
*/
//#define MBEDTLS_PSA_CRYPTO_CONFIG
@ -3701,8 +3740,29 @@
/* Platform options */
//#define MBEDTLS_PLATFORM_STD_MEM_HDR <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */
//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */
/** \def MBEDTLS_PLATFORM_STD_CALLOC
*
* Default allocator to use, can be undefined.
* It must initialize the allocated buffer memory to zeroes.
* The size of the buffer is the product of the two parameters.
* The calloc function returns either a null pointer or a pointer to the allocated space.
* If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function.
* An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
* See the description of #MBEDTLS_PLATFORM_MEMORY for more details.
* The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE.
*/
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc
/** \def MBEDTLS_PLATFORM_STD_FREE
*
* Default free to use, can be undefined.
* NULL is a valid parameter, and the function must do nothing.
* A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed.
* An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
* See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply).
*/
//#define MBEDTLS_PLATFORM_STD_FREE free
//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */
//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */
//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
@ -3716,10 +3776,10 @@
//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */
/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */
/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */
//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */
//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
@ -3781,6 +3841,9 @@
*/
//#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 */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
@ -3997,4 +4060,27 @@
*/
//#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
/*
* Disable plain C implementation for AES.
*
* When the plain C implementation is enabled, and an implementation using a
* special CPU feature (such as MBEDTLS_AESCE_C) is also enabled, runtime
* detection will be used to select between them.
*
* If only one implementation is present, runtime detection will not be used.
* This configuration will crash at runtime if running on a CPU without the
* necessary features. It will not build unless at least one of MBEDTLS_AESCE_C
* and/or MBEDTLS_AESNI_C is enabled & present in the build.
*/
//#define MBEDTLS_AES_USE_HARDWARE_ONLY
/** \} name SECTION: Module configuration options */

View file

@ -146,19 +146,22 @@ extern "C" {
* 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 {
MBEDTLS_MD_NONE=0, /**< None. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_SHA3_224, /**< The SHA3-224 message digest. */
MBEDTLS_MD_SHA3_256, /**< The SHA3-256 message digest. */
MBEDTLS_MD_SHA3_384, /**< The SHA3-384 message digest. */
MBEDTLS_MD_SHA3_512, /**< The SHA3-512 message digest. */
MBEDTLS_MD_MD5=0x03, /**< The MD5 message digest. */
MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */
MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */
MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */
MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */
MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */
} mbedtls_md_type_t;
/* 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);
/**
* \brief This function extracts the message-digest name from the
* message-digest information structure.
* \brief This function returns the name of the message digest for
* the message-digest information structure given.
*
* \param md_info The information structure of the message-digest algorithm
* to use.

View file

@ -286,6 +286,10 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len,
* \brief Closes down the connection and free associated data
*
* \param ctx The context to close
*
* \note This function frees and clears data associated with the
* context but does not free the memory pointed to by \p ctx.
* This memory is the responsibility of the caller.
*/
void mbedtls_net_close(mbedtls_net_context *ctx);
@ -293,6 +297,10 @@ void mbedtls_net_close(mbedtls_net_context *ctx);
* \brief Gracefully shutdown the connection and free associated data
*
* \param ctx The context to free
*
* \note This function frees and clears data associated with the
* context but does not free the memory pointed to by \p ctx.
* This memory is the responsibility of the caller.
*/
void mbedtls_net_free(mbedtls_net_context *ctx);

View file

@ -171,40 +171,9 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#endif
#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(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#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
* 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 affects how data is stored, not
* which functions are used for various operations. The overall picture looks
* like this:
* - if USE_PSA is not defined and ECP_C is then use ecp_keypair data structure
@ -231,6 +200,28 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#define MBEDTLS_PK_HAVE_ECC_KEYS
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
/* 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)
* format. It should be noted that this only affect how data is stored, not
* which functions are used for various operations. The overall picture looks
* like this:
* - if USE_PSA is not defined and ECP_C is then use ecp_keypair data structure
* and legacy functions
* - if USE_PSA is defined and
* - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
* format and use PSA functions
* - if !ECP_C then use new raw data and PSA functions directly.
*
* The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
* as ECP_C is defined mbedtls_pk_ec() gives the user read/write access to the
* ecp_keypair structure inside the pk_context so they can modify it using
* ECP functions which are not under the PK module's control.
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_USE_PSA_EC_DATA
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_ECP_C */
/**
* \brief Types for interfacing with the debug module
*/
@ -552,7 +543,7 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
*
* \return 0 on success (signature is 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.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
@ -606,7 +597,7 @@ int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
* used for this type of signatures,
* #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.
*
* \note If hash_len is 0, then the length associated with md_alg

View file

@ -130,11 +130,22 @@ extern "C" {
#endif
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
/* Enable certain documented defines only when generating doxygen to avoid
* an "unrecognized define" error. */
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC)
#define MBEDTLS_PLATFORM_STD_CALLOC
#endif
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE)
#define MBEDTLS_PLATFORM_STD_FREE
#endif
/** \} name SECTION: Module settings */
/*
* The function pointers for calloc and free.
* Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE
* in mbedtls_config.h for more information about behaviour and requirements.
*/
#if defined(MBEDTLS_PLATFORM_MEMORY)
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \

View file

@ -85,6 +85,12 @@ extern "C" {
// 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.
*/
@ -282,15 +288,15 @@ int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx,
* \brief This function completes an RSA context from
* 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.
*
* To setup an RSA private key, sufficient information must
* be present for the other parameters to be derivable.
*
* The default implementation supports the following:
* <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li>
* <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul>
* <ul><li>Derive \c P, \c Q from \c N, \c D, \c E.</li>
* <li>Derive \c N, \c D from \c P, \c Q, \c E.</li></ul>
* Alternative implementations need not support these.
*
* 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 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 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.
*
* \note For PKCS#1 v2.1 encoding, see comments on
* mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
* \p hash_id.
* mbedtls_rsa_rsassa_pss_verify() about \c md_alg and
* \c hash_id.
*
* \param ctx The initialized RSA public key context to use.
* \param md_alg The message-digest algorithm used to hash the original data.

View file

@ -42,7 +42,7 @@
#include "mbedtls/md.h"
#if defined(MBEDTLS_ECDH_C)
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED)
#include "mbedtls/ecdh.h"
#endif
@ -619,6 +619,7 @@
/* Dummy type used only for its size */
union mbedtls_ssl_premaster_secret {
unsigned char dummy; /* Make the union non-empty even with SSL disabled */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */
#endif
@ -2170,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
* the peer to use when sending encrypted messages to us.
* 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.
* \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.
*
* \note The value of \p own_cid_len must match the value of the
@ -3124,8 +3125,8 @@ int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
*
* \param session The session structure to be saved.
* \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
* NULL if \p len is \c 0.
* writeable buffer of at least \p buf_len bytes, or may be \c
* NULL if \p buf_len is \c 0.
* \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
* been written. It must point to a valid \c size_t.
@ -3266,7 +3267,7 @@ void mbedtls_ssl_conf_tls13_key_exchange_modes(mbedtls_ssl_config *conf,
* record headers.
*
* \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.
*/
int mbedtls_ssl_conf_cid(mbedtls_ssl_config *conf, size_t len,
@ -3810,8 +3811,8 @@ static inline const char *mbedtls_ssl_get_hostname(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/**
* \brief Retrieve SNI extension value for the current handshake.
* Available in \p f_cert_cb of \c mbedtls_ssl_conf_cert_cb(),
* this is the same value passed to \p f_sni callback of
* Available in \c f_cert_cb of \c mbedtls_ssl_conf_cert_cb(),
* 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().
*
@ -3820,10 +3821,10 @@ static inline const char *mbedtls_ssl_get_hostname(mbedtls_ssl_context *ssl)
* 0 if SNI extension is not present or not yet processed.
*
* \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().
* - 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.
*/
const unsigned char *mbedtls_ssl_get_hs_sni(mbedtls_ssl_context *ssl,
@ -4116,7 +4117,7 @@ void MBEDTLS_DEPRECATED mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, i
* negotiated.
*
* \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)
*/
static inline void mbedtls_ssl_conf_max_tls_version(mbedtls_ssl_config *conf,
@ -4173,7 +4174,7 @@ void MBEDTLS_DEPRECATED mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, i
* negotiated.
*
* \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)
*/
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 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.
*
* \return \c 0 on success. This indicates the cache entry for

View file

@ -346,11 +346,6 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
#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 */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
@ -364,6 +359,62 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED
#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;
#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */

View file

@ -429,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
* alternative name.
* \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:
* "rfc822Name", "dnsName", "directoryName",
@ -439,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
* subject alternative name. For example, after successful
* 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.
*
* \warning The target structure contains pointers to the raw data of the
@ -503,7 +503,8 @@ int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first);
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size);
unsigned char *sig, size_t size,
mbedtls_pk_type_t pk_alg);
int mbedtls_x509_get_ns_cert_type(unsigned char **p,
const unsigned char *end,
unsigned char *ns_cert_type);
@ -525,6 +526,9 @@ int mbedtls_x509_info_cert_type(char **buf, size_t *size,
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
unsigned int key_usage);
int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions,
const mbedtls_x509_san_list *san_list);
/**
* \brief This function parses a CN string as an IP address.
*

View file

@ -4407,9 +4407,9 @@ psa_status_t psa_sign_hash_start(
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p signature buffer is too small. You can
* 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
* respectively of \p key.
* respectively of \c key.
*
* \retval #PSA_ERROR_BAD_STATE
* An operation was not previously started on this context via

View file

@ -105,7 +105,7 @@ typedef struct psa_tls12_prf_key_derivation_s {
} psa_tls12_prf_key_derivation_t;
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#if defined(PSA_HAVE_SOFT_PBKDF2)
typedef enum {
PSA_PBKDF2_STATE_INIT, /* no input provided */
PSA_PBKDF2_STATE_INPUT_COST_SET, /* input cost has been set */
@ -125,6 +125,6 @@ typedef struct {
uint8_t MBEDTLS_PRIVATE(bytes_used);
uint32_t MBEDTLS_PRIVATE(block_number);
} psa_pbkdf2_key_derivation_t;
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
#endif /* PSA_CRYPTO_BUILTIN_KEY_DERIVATION_H */

View file

@ -94,7 +94,8 @@ typedef struct {
defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_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
#endif

View file

@ -76,6 +76,7 @@
#define PSA_WANT_ALG_MD5 1
#define PSA_WANT_ALG_OFB 1
#define PSA_WANT_ALG_PBKDF2_HMAC 1
#define PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 1
#define PSA_WANT_ALG_RIPEMD160 1
#define PSA_WANT_ALG_RSA_OAEP 1
#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
@ -91,7 +92,8 @@
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1
/* Note: when adding support, also adjust include/mbedtls/config_psa.h */
/* XTS is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_XTS 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1

View file

@ -55,7 +55,7 @@ typedef union {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
psa_tls12_ecjpake_to_pms_t MBEDTLS_PRIVATE(tls12_ecjpake_to_pms);
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#if defined(PSA_HAVE_SOFT_PBKDF2)
psa_pbkdf2_key_derivation_t MBEDTLS_PRIVATE(pbkdf2);
#endif
} psa_driver_key_derivation_context_t;

View file

@ -1036,12 +1036,12 @@ typedef uint32_t psa_pake_primitive_t;
* (value of type ::psa_pake_primitive_type_t).
* \param pake_family The family of the primitive
* (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
* constants).
* \param pake_bits The bit-size of the primitive
* (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
* ::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
* Success.
* \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.
* \retval #PSA_ERROR_NOT_SUPPORTED
* 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
* information.
* \param output_size Size of the \p output buffer in bytes. This must
* be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \p
* primitive, \p step) where \p alg and
* be at least #PSA_PAKE_OUTPUT_SIZE(\c alg, \c
* primitive, \p output_step) where \c alg and
* \p primitive are the PAKE algorithm and primitive
* in the operation's cipher suite, and \p step is
* the output step.
@ -1693,9 +1693,9 @@ psa_status_t psa_pake_output(psa_pake_operation_t *operation,
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p is not compatible with the \p operations algorithm, or the
* \p input is not valid for the \p operation's algorithm, cipher suite
* or \p step.
* \p input_length is not compatible with the \p operations algorithm,
* or the \p input is not valid for the \p operation's algorithm,
* cipher suite or \p step.
* \retval #PSA_ERROR_NOT_SUPPORTED
* \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
@ -1744,7 +1744,7 @@ psa_status_t psa_pake_input(psa_pake_operation_t *operation,
*
* When this function returns successfully, \p operation becomes inactive.
* 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.
*
* \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
* 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
@ -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
* 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

View file

@ -4,8 +4,8 @@
* \brief Add temporary suppport for deprecated symbols before they are
* removed from the library.
*
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_LEGACY and
* MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_LEGACY symbols are deprecated.
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR
* symbols are deprecated.
* 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).
* 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. */
#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.
*
* 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
* is the maximum size of a signature in bytes.
*/
#define PSA_SIGNATURE_MAX_SIZE \
(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) : \
PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE)
#define PSA_SIGNATURE_MAX_SIZE 1
#if (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
(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().
*
@ -948,10 +968,29 @@
*
* See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
*/
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
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), \
PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS))
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE 1
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
(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.
*
@ -962,11 +1001,29 @@
*
* See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
*/
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
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))
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 1
#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().
*
@ -1002,11 +1059,18 @@
*
* See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits).
*/
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \
(PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) ? \
PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \
PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS))
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE 1
#if defined(PSA_WANT_ALG_ECDH) && \
(PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_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_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.
*

View file

@ -2115,6 +2115,10 @@
*/
#define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t) 0x08800200)
#define PSA_ALG_IS_PBKDF2(kdf_alg) \
(PSA_ALG_IS_PBKDF2_HMAC(kdf_alg) || \
((kdf_alg) == PSA_ALG_PBKDF2_AES_CMAC_PRF_128))
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t) 0xfe00ffff)
#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t) 0xffff0000)

3
library/.gitignore vendored
View file

@ -2,8 +2,9 @@ libmbed*
*.sln
*.vcxproj
# Automatically generated files
###START_GENERATED_FILES###
/error.c
/version_features.c
/ssl_debug_helpers_generated.c
/psa_crypto_driver_wrappers.c
###END_GENERATED_FILES###

View file

@ -37,8 +37,8 @@ set(src_crypto
ecdsa.c
ecjpake.c
ecp.c
ecp_new.c
ecp_curves.c
ecp_curves_new.c
entropy.c
entropy_poll.c
error.c
@ -99,6 +99,7 @@ set(src_x509
x509_crl.c
x509_crt.c
x509_csr.c
x509write.c
x509write_crt.c
x509write_csr.c
)
@ -290,7 +291,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
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})
if(TARGET everest)
@ -302,11 +303,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
endif()
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})
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})
endif(USE_SHARED_MBEDTLS_LIBRARY)

View file

@ -102,8 +102,8 @@ OBJS_CRYPTO= \
ecdsa.o \
ecjpake.o \
ecp.o \
ecp_new.o \
ecp_curves.o \
ecp_curves_new.o \
entropy.o \
entropy_poll.o \
error.o \
@ -167,6 +167,7 @@ OBJS_X509= \
x509_crl.o \
x509_crt.o \
x509_csr.o \
x509write.o \
x509write_crt.o \
x509write_csr.o \
pkcs7.o \

View file

@ -19,7 +19,7 @@
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
*
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
* https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
@ -33,6 +33,36 @@
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#if defined(__aarch64__)
#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
#endif
#endif
#if defined(__amd64__) || defined(__x86_64__) || \
((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
#endif
#endif
#if defined(__i386__) || defined(_M_IX86)
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C)
#if !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
"MBEDTLS_PADLOCK_C is set"
#endif
#endif
#endif
#if defined(MBEDTLS_PADLOCK_C)
#include "padlock.h"
#endif
@ -47,7 +77,7 @@
#if !defined(MBEDTLS_AES_ALT)
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
static int aes_padlock_ace = -1;
#endif
@ -542,7 +572,7 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
* Note that the offset is in units of elements of buf, i.e. 32-bit words,
* i.e. an offset of 1 means 4 bytes and so on.
*/
#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
(defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
#define MAY_NEED_TO_ALIGN
#endif
@ -554,7 +584,7 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
#if defined(MAY_NEED_TO_ALIGN)
int align_16_bytes = 0;
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
if (aes_padlock_ace == -1) {
aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
}
@ -595,7 +625,6 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits)
{
unsigned int i;
uint32_t *RK;
switch (keybits) {
@ -624,19 +653,20 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
}
#endif
for (i = 0; i < (keybits >> 5); i++) {
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
for (unsigned int i = 0; i < (keybits >> 5); i++) {
RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
}
switch (ctx->nr) {
case 10:
for (i = 0; i < 10; i++, RK += 4) {
for (unsigned int i = 0; i < 10; i++, RK += 4) {
RK[4] = RK[0] ^ RCON[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
@ -652,7 +682,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
case 12:
for (i = 0; i < 8; i++, RK += 6) {
for (unsigned int i = 0; i < 8; i++, RK += 6) {
RK[6] = RK[0] ^ RCON[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
@ -669,7 +699,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
case 14:
for (i = 0; i < 7; i++, RK += 8) {
for (unsigned int i = 0; i < 7; i++, RK += 8) {
RK[8] = RK[0] ^ RCON[i] ^
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
@ -695,6 +725,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
}
return 0;
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
}
#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
@ -705,10 +736,13 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits)
{
int i, j, ret;
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
uint32_t *SK;
#endif
int ret;
mbedtls_aes_context cty;
uint32_t *RK;
uint32_t *SK;
mbedtls_aes_init(&cty);
@ -731,7 +765,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
mbedtls_aesce_inverse_key(
(unsigned char *) RK,
(const unsigned char *) (cty.buf + cty.rk_offset),
@ -740,15 +774,16 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
}
#endif
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
SK = cty.buf + cty.rk_offset + cty.nr * 4;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
for (j = 0; j < 4; j++, SK++) {
SK -= 8;
for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
for (int j = 0; j < 4; j++, SK++) {
*RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
@ -760,7 +795,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
exit:
mbedtls_aes_free(&cty);
@ -1057,22 +1092,25 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
}
#endif
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
if (aes_padlock_ace > 0) {
return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
}
#endif
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
if (mode == MBEDTLS_AES_ENCRYPT) {
return mbedtls_internal_aes_encrypt(ctx, input, output);
} else {
return mbedtls_internal_aes_decrypt(ctx, input, output);
}
#endif
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@ -1094,11 +1132,16 @@ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
/* Nothing to do if length is zero. */
if (length == 0) {
return 0;
}
if (length % 16) {
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
}
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
if (aes_padlock_ace > 0) {
if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
return 0;
@ -1850,29 +1893,33 @@ int mbedtls_aes_self_test(int verbose)
#if defined(MBEDTLS_AES_ALT)
mbedtls_printf(" AES note: alternative implementation.\n");
#else /* MBEDTLS_AES_ALT */
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
mbedtls_printf(" AES note: using VIA Padlock.\n");
} else
#endif
#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
#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
#endif
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
mbedtls_printf(" AES note: using AESNI.\n");
} else
#endif
#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
mbedtls_printf(" AES note: using VIA Padlock.\n");
} else
#endif
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
if (mbedtls_aesce_has_support()) {
if (MBEDTLS_AESCE_HAS_SUPPORT()) {
mbedtls_printf(" AES note: using AESCE.\n");
} else
#endif
mbedtls_printf(" AES note: built-in implementation.\n");
{
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
mbedtls_printf(" AES note: built-in implementation.\n");
#endif
}
#endif /* MBEDTLS_AES_ALT */
}

View file

@ -94,25 +94,39 @@
#endif /* !(__ARM_FEATURE_CRYPTO || __ARM_FEATURE_AES) ||
MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG */
#if defined(__linux__)
#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif
signed char mbedtls_aesce_has_support_result = -1;
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
/*
* AES instruction support detection routine
*/
int mbedtls_aesce_has_support(void)
int mbedtls_aesce_has_support_impl(void)
{
#if defined(__linux__)
unsigned long auxval = getauxval(AT_HWCAP);
return (auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
(HWCAP_ASIMD | HWCAP_AES);
#else
/* Assume AES instructions are supported. */
return 1;
#endif
/* To avoid many calls to getauxval, cache the result. This is
* thread-safe, because we store the result in a char so cannot
* be vulnerable to non-atomic updates.
* It is possible that we could end up setting result more than
* once, but that is harmless.
*/
if (mbedtls_aesce_has_support_result == -1) {
unsigned long auxval = getauxval(AT_HWCAP);
if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
(HWCAP_ASIMD | HWCAP_AES)) {
mbedtls_aesce_has_support_result = 1;
} else {
mbedtls_aesce_has_support_result = 0;
}
}
return mbedtls_aesce_has_support_result;
}
#endif
#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
/* Single round of AESCE encryption */
#define AESCE_ENCRYPT_ROUND \

View file

@ -42,12 +42,29 @@
extern "C" {
#endif
#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
extern signed char mbedtls_aesce_has_support_result;
/**
* \brief Internal function to detect the crypto extension in CPUs.
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int mbedtls_aesce_has_support(void);
int mbedtls_aesce_has_support_impl(void);
#define MBEDTLS_AESCE_HAS_SUPPORT() (mbedtls_aesce_has_support_result == -1 ? \
mbedtls_aesce_has_support_impl() : \
mbedtls_aesce_has_support_result)
#else /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
/* If we are not on Linux, we can't detect support so assume that it's supported.
* Similarly, assume support if MBEDTLS_AES_USE_HARDWARE_ONLY is set.
*/
#define MBEDTLS_AESCE_HAS_SUPPORT() 1
#endif /* defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) */
/**
* \brief Internal AES-ECB block encryption and decryption

View file

@ -35,10 +35,13 @@
#if MBEDTLS_AESNI_HAVE_CODE == 2
#if !defined(_WIN32)
#include <cpuid.h>
#else
#include <intrin.h>
#endif
#include <immintrin.h>
#endif
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
/*
* AES-NI support detection routine
*/
@ -68,6 +71,7 @@ int mbedtls_aesni_has_support(unsigned int what)
return (c & what) != 0;
}
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
#if MBEDTLS_AESNI_HAVE_CODE == 2

View file

@ -35,13 +35,20 @@
/* Can we do AESNI with inline assembly?
* (Only implemented with gas syntax, only for 64-bit.)
*/
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
(defined(__amd64__) || defined(__x86_64__)) && \
!defined(MBEDTLS_HAVE_X86_64)
#if !defined(MBEDTLS_HAVE_X86_64) && \
(defined(__amd64__) || defined(__x86_64__) || \
defined(_M_X64) || defined(_M_AMD64)) && \
!defined(_M_ARM64EC)
#define MBEDTLS_HAVE_X86_64
#endif
#if defined(MBEDTLS_AESNI_C)
#if !defined(MBEDTLS_HAVE_X86) && \
(defined(__i386__) || defined(_M_IX86))
#define MBEDTLS_HAVE_X86
#endif
#if defined(MBEDTLS_AESNI_C) && \
(defined(MBEDTLS_HAVE_X86_64) || defined(MBEDTLS_HAVE_X86))
/* Can we do AESNI with intrinsics?
* (Only implemented with certain compilers, only for certain targets.)
@ -67,8 +74,13 @@
* In the long run, we will likely remove the assembly implementation. */
#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
#elif defined(MBEDTLS_HAVE_X86_64)
#elif defined(MBEDTLS_HAVE_ASM) && \
defined(__GNUC__) && defined(MBEDTLS_HAVE_X86_64)
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
#elif defined(__GNUC__)
# error "Must use `-mpclmul -msse2 -maes` for MBEDTLS_AESNI_C"
#else
#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available"
#endif
#if defined(MBEDTLS_AESNI_HAVE_CODE)
@ -88,7 +100,11 @@ extern "C" {
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
int mbedtls_aesni_has_support(unsigned int what);
#else
#define mbedtls_aesni_has_support(what) 1
#endif
/**
* \brief Internal AES-NI AES-ECB block encryption and decryption

View file

@ -24,6 +24,7 @@
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#include "base64_internal.h"
#include "constant_time_internal.h"
#include <stdint.h>
@ -33,6 +34,39 @@
#include "mbedtls/platform.h"
#endif /* MBEDTLS_SELF_TEST */
MBEDTLS_STATIC_TESTABLE
unsigned char mbedtls_ct_base64_enc_char(unsigned char value)
{
unsigned char digit = 0;
/* For each range of values, if value is in that range, mask digit with
* the corresponding value. Since value can only be in a single range,
* only at most one masking will change digit. */
digit |= mbedtls_ct_uchar_in_range_if(0, 25, value, 'A' + value);
digit |= mbedtls_ct_uchar_in_range_if(26, 51, value, 'a' + value - 26);
digit |= mbedtls_ct_uchar_in_range_if(52, 61, value, '0' + value - 52);
digit |= mbedtls_ct_uchar_in_range_if(62, 62, value, '+');
digit |= mbedtls_ct_uchar_in_range_if(63, 63, value, '/');
return digit;
}
MBEDTLS_STATIC_TESTABLE
signed char mbedtls_ct_base64_dec_value(unsigned char c)
{
unsigned char val = 0;
/* For each range of digits, if c is in that range, mask val with
* the corresponding value. Since c can only be in a single range,
* only at most one masking will change val. Set val to one plus
* the desired value so that it stays 0 if c is in none of the ranges. */
val |= mbedtls_ct_uchar_in_range_if('A', 'Z', c, c - 'A' + 0 + 1);
val |= mbedtls_ct_uchar_in_range_if('a', 'z', c, c - 'a' + 26 + 1);
val |= mbedtls_ct_uchar_in_range_if('0', '9', c, c - '0' + 52 + 1);
val |= mbedtls_ct_uchar_in_range_if('+', '+', c, c - '+' + 62 + 1);
val |= mbedtls_ct_uchar_in_range_if('/', '/', c, c - '/' + 63 + 1);
/* At this point, val is 0 if c is an invalid digit and v+1 if c is
* a digit with the value v. */
return val - 1;
}
/*
* Encode a buffer into base64 format
*/

57
library/base64_internal.h Normal file
View file

@ -0,0 +1,57 @@
/**
* \file base64_internal.h
*
* \brief RFC 1521 base64 encoding/decoding: interfaces for invasive testing
*/
/*
* 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 MBEDTLS_BASE64_INTERNAL
#define MBEDTLS_BASE64_INTERNAL
#include "common.h"
#if defined(MBEDTLS_TEST_HOOKS)
/** Given a value in the range 0..63, return the corresponding Base64 digit.
*
* The implementation assumes that letters are consecutive (e.g. ASCII
* but not EBCDIC).
*
* \param value A value in the range 0..63.
*
* \return A base64 digit converted from \p value.
*/
unsigned char mbedtls_ct_base64_enc_char(unsigned char value);
/** Given a Base64 digit, return its value.
*
* If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
* return -1.
*
* The implementation assumes that letters are consecutive (e.g. ASCII
* but not EBCDIC).
*
* \param c A base64 digit.
*
* \return The value of the base64 digit \p c.
*/
signed char mbedtls_ct_base64_dec_value(unsigned char c);
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* MBEDTLS_BASE64_INTERNAL */

View file

@ -54,12 +54,135 @@
#define MPI_VALIDATE(cond) \
MBEDTLS_INTERNAL_VALIDATE(cond)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_mpi_zeroize(mbedtls_mpi_uint *v, size_t n)
/*
* Compare signed values in constant time
*/
int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
const mbedtls_mpi *Y,
unsigned *ret)
{
mbedtls_platform_zeroize(v, ciL * n);
mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MPI_VALIDATE_RET(ret != NULL);
if (X->n != Y->n) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
/*
* Set sign_N to 1 if N >= 0, 0 if N < 0.
* We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
*/
X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1);
Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1);
/*
* If the signs are different, then the positive operand is the bigger.
* That is if X is negative (X_is_negative == 1), then X < Y is true and it
* is false if X is positive (X_is_negative == 0).
*/
different_sign = mbedtls_ct_bool_xor(X_is_negative, Y_is_negative); // non-zero if different sign
result = mbedtls_ct_bool_and(different_sign, X_is_negative);
/*
* Assuming signs are the same, compare X and Y. We switch the comparison
* order if they are negative so that we get the right result, regardles of
* sign.
*/
/* This array is used to conditionally swap the pointers in const time */
void * const p[2] = { X->p, Y->p };
size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1);
mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n);
/*
* Store in result iff the signs are the same (i.e., iff different_sign == false). If
* the signs differ, result has already been set, so we don't change it.
*/
result = mbedtls_ct_bool_or(result,
mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt));
*ret = mbedtls_ct_uint_if_else_0(result, 1);
return 0;
}
/*
* Conditionally assign X = Y, without leaking information
* about whether the assignment was made or not.
* (Leaking information about the respective sizes of X and Y is ok however.)
*/
#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
/*
* MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
* https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
*/
__declspec(noinline)
#endif
int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
const mbedtls_mpi *Y,
unsigned char assign)
{
int ret = 0;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s);
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign);
for (size_t i = Y->n; i < X->n; i++) {
X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]);
}
cleanup:
return ret;
}
/*
* Conditionally swap X and Y, without leaking information
* about whether the swap was made or not.
* Here it is not ok to simply swap the pointers, which would lead to
* different memory access patterns when X and Y are used afterwards.
*/
int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
mbedtls_mpi *Y,
unsigned char swap)
{
int ret = 0;
int s;
MPI_VALIDATE_RET(X != NULL);
MPI_VALIDATE_RET(Y != NULL);
if (X == Y) {
return 0;
}
mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap);
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
s = X->s;
X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s);
Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s);
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
cleanup:
return ret;
}
/* Implementation that should never be optimized out by the compiler */
#define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
/*
* Initialize one MPI
*/
@ -82,8 +205,7 @@ void mbedtls_mpi_free(mbedtls_mpi *X)
}
if (X->p != NULL) {
mbedtls_mpi_zeroize(X->p, X->n);
mbedtls_free(X->p);
mbedtls_mpi_zeroize_and_free(X->p, X->n);
}
X->s = 1;
@ -110,8 +232,7 @@ int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
if (X->p != NULL) {
memcpy(p, X->p, X->n * ciL);
mbedtls_mpi_zeroize(X->p, X->n);
mbedtls_free(X->p);
mbedtls_mpi_zeroize_and_free(X->p, X->n);
}
/* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
@ -160,8 +281,7 @@ int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
if (X->p != NULL) {
memcpy(p, X->p, i * ciL);
mbedtls_mpi_zeroize(X->p, X->n);
mbedtls_free(X->p);
mbedtls_mpi_zeroize_and_free(X->p, X->n);
}
/* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
@ -264,6 +384,10 @@ static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z;
}
/* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative.
* This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */
#define TO_SIGN(x) ((((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1)
/*
* Set value from integer
*/
@ -276,7 +400,7 @@ int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
memset(X->p, 0, X->n * ciL);
X->p[0] = mpi_sint_abs(z);
X->s = (z < 0) ? -1 : 1;
X->s = TO_SIGN(z);
cleanup:
@ -332,16 +456,35 @@ cleanup:
*/
size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
{
size_t i, j, count = 0;
size_t i;
MBEDTLS_INTERNAL_VALIDATE_RET(X != NULL, 0);
#if defined(__has_builtin)
#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
#define mbedtls_mpi_uint_ctz __builtin_ctz
#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)
#define mbedtls_mpi_uint_ctz __builtin_ctzl
#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)
#define mbedtls_mpi_uint_ctz __builtin_ctzll
#endif
#endif
#if defined(mbedtls_mpi_uint_ctz)
for (i = 0; i < X->n; i++) {
for (j = 0; j < biL; j++, count++) {
if (X->p[i] != 0) {
return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);
}
}
#else
size_t count = 0;
for (i = 0; i < X->n; i++) {
for (size_t j = 0; j < biL; j++, count++) {
if (((X->p[i] >> j) & 1) != 0) {
return count;
}
}
}
#endif
return 0;
}
@ -802,9 +945,8 @@ int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
}
}
if (i == 0 && j == 0) {
return 0;
}
/* If i == j == 0, i.e. abs(X) == abs(Y),
* we end up returning 0 at the end of the function. */
if (i > j) {
return 1;
@ -886,7 +1028,7 @@ int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
MPI_VALIDATE_RET(X != NULL);
*p = mpi_sint_abs(z);
Y.s = (z < 0) ? -1 : 1;
Y.s = TO_SIGN(z);
Y.n = 1;
Y.p = p;
@ -1074,7 +1216,7 @@ int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = (b < 0) ? -1 : 1;
B.s = TO_SIGN(b);
B.n = 1;
B.p = p;
@ -1092,7 +1234,7 @@ int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = (b < 0) ? -1 : 1;
B.s = TO_SIGN(b);
B.n = 1;
B.p = p;
@ -1442,7 +1584,7 @@ int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
MPI_VALIDATE_RET(A != NULL);
p[0] = mpi_sint_abs(b);
B.s = (b < 0) ? -1 : 1;
B.s = TO_SIGN(b);
B.n = 1;
B.p = p;
@ -1608,10 +1750,8 @@ static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_
for (size_t i = 0; i < T_size; i++) {
MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
(unsigned char) mbedtls_ct_size_bool_eq(i,
idx)));
(unsigned char) mbedtls_ct_uint_eq(i, idx)));
}
cleanup:
return ret;
}
@ -1686,8 +1826,9 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
* and squarings. Firstly, when multiplying by an element of the window
* W[i], we do a constant-trace table lookup to obfuscate i. This leaves
* squarings as having a different memory access patterns from other
* multiplications. So secondly, we put the accumulator X in the table as
* well, and also do a constant-trace table lookup to multiply by X.
* multiplications. So secondly, we put the accumulator in the table as
* well, and also do a constant-trace table lookup to multiply by the
* accumulator which is W[x_index].
*
* This way, all multiplications take the form of a lookup-and-multiply.
* The number of lookup-and-multiply operations inside each iteration of
@ -1700,19 +1841,16 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
* observe both memory accesses and branches. However, branch prediction
* exploitation typically requires many traces of execution over the same
* data, which is defeated by randomized blinding.
*
* To achieve this, we make a copy of X and we use the table entry in each
* calculation from this point on.
*/
const size_t x_index = 0;
mbedtls_mpi_init(&W[x_index]);
mbedtls_mpi_copy(&W[x_index], X);
j = N->n + 1;
/* All W[i] and X must have at least N->n limbs for the mpi_montmul()
* and mpi_montred() calls later. Here we ensure that W[1] and X are
* large enough, and later we'll grow other W[i] to the same length.
* They must not be shrunk midway through this function!
/* All W[i] including the accumulator must have at least N->n limbs for
* the mpi_montmul() and mpi_montred() calls later. Here we ensure that
* W[1] and the accumulator W[x_index] are large enough. later we'll grow
* other W[i] to the same length. They must not be shrunk midway through
* this function!
*/
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
@ -1893,7 +2031,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
/*
* Load the result in the output variable.
*/
mbedtls_mpi_copy(X, &W[x_index]);
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
cleanup:
@ -2171,29 +2309,30 @@ cleanup:
#if defined(MBEDTLS_GENPRIME)
static const int small_prime[] =
{
3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137,
139, 149, 151, 157, 163, 167, 173, 179,
181, 191, 193, 197, 199, 211, 223, 227,
229, 233, 239, 241, 251, 257, 263, 269,
271, 277, 281, 283, 293, 307, 311, 313,
317, 331, 337, 347, 349, 353, 359, 367,
373, 379, 383, 389, 397, 401, 409, 419,
421, 431, 433, 439, 443, 449, 457, 461,
463, 467, 479, 487, 491, 499, 503, 509,
521, 523, 541, 547, 557, 563, 569, 571,
577, 587, 593, 599, 601, 607, 613, 617,
619, 631, 641, 643, 647, 653, 659, 661,
673, 677, 683, 691, 701, 709, 719, 727,
733, 739, 743, 751, 757, 761, 769, 773,
787, 797, 809, 811, 821, 823, 827, 829,
839, 853, 857, 859, 863, 877, 881, 883,
887, 907, 911, 919, 929, 937, 941, 947,
953, 967, 971, 977, 983, 991, 997, -103
/* Gaps between primes, starting at 3. https://oeis.org/A001223 */
static const unsigned char small_prime_gaps[] = {
2, 2, 4, 2, 4, 2, 4, 6,
2, 6, 4, 2, 4, 6, 6, 2,
6, 4, 2, 6, 4, 6, 8, 4,
2, 4, 2, 4, 14, 4, 6, 2,
10, 2, 6, 6, 4, 6, 6, 2,
10, 2, 4, 2, 12, 12, 4, 2,
4, 6, 2, 10, 6, 6, 6, 2,
6, 4, 2, 10, 14, 4, 2, 4,
14, 6, 10, 2, 4, 6, 8, 6,
6, 4, 6, 8, 4, 8, 10, 2,
10, 2, 6, 4, 6, 8, 4, 2,
4, 12, 8, 4, 8, 4, 6, 12,
2, 18, 6, 10, 6, 6, 2, 6,
10, 6, 6, 2, 6, 6, 4, 2,
12, 10, 2, 4, 6, 6, 2, 12,
4, 6, 8, 10, 8, 10, 8, 6,
6, 4, 8, 6, 4, 8, 4, 14,
10, 12, 2, 10, 2, 4, 2, 10,
14, 4, 2, 4, 14, 4, 2, 4,
20, 4, 8, 10, 8, 4, 6, 6,
14, 4, 6, 6, 8, 6, /*reaches 997*/
0 /* the last entry is effectively unused */
};
/*
@ -2210,20 +2349,20 @@ static int mpi_check_small_factors(const mbedtls_mpi *X)
int ret = 0;
size_t i;
mbedtls_mpi_uint r;
unsigned p = 3; /* The first odd prime */
if ((X->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
for (i = 0; small_prime[i] > 0; i++) {
if (mbedtls_mpi_cmp_int(X, small_prime[i]) <= 0) {
return 1;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, small_prime[i]));
for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));
if (r == 0) {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
if (mbedtls_mpi_cmp_int(X, p) == 0) {
return 1;
} else {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
}
}

View file

@ -144,54 +144,92 @@ void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A,
/* Whether min <= A, in constant time.
* A_limbs must be at least 1. */
unsigned mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
const mbedtls_mpi_uint *A,
size_t A_limbs)
mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
const mbedtls_mpi_uint *A,
size_t A_limbs)
{
/* min <= least significant limb? */
unsigned min_le_lsl = 1 ^ mbedtls_ct_mpi_uint_lt(A[0], min);
mbedtls_ct_condition_t min_le_lsl = mbedtls_ct_uint_ge(A[0], min);
/* limbs other than the least significant one are all zero? */
mbedtls_mpi_uint msll_mask = 0;
mbedtls_ct_condition_t msll_mask = MBEDTLS_CT_FALSE;
for (size_t i = 1; i < A_limbs; i++) {
msll_mask |= A[i];
msll_mask = mbedtls_ct_bool_or(msll_mask, mbedtls_ct_bool(A[i]));
}
/* The most significant limbs of A are not all zero iff msll_mask != 0. */
unsigned msll_nonzero = mbedtls_ct_mpi_uint_mask(msll_mask) & 1;
/* min <= A iff the lowest limb of A is >= min or the other limbs
* are not all zero. */
return min_le_lsl | msll_nonzero;
return mbedtls_ct_bool_or(msll_mask, min_le_lsl);
}
mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
size_t limbs)
{
mbedtls_ct_condition_t ret = MBEDTLS_CT_FALSE, cond = MBEDTLS_CT_FALSE, done = MBEDTLS_CT_FALSE;
for (size_t i = limbs; i > 0; i--) {
/*
* If B[i - 1] < A[i - 1] then A < B is false and the result must
* remain 0.
*
* Again even if we can make a decision, we just mark the result and
* the fact that we are done and continue looping.
*/
cond = mbedtls_ct_uint_lt(B[i - 1], A[i - 1]);
done = mbedtls_ct_bool_or(done, cond);
/*
* If A[i - 1] < B[i - 1] then A < B is true.
*
* Again even if we can make a decision, we just mark the result and
* the fact that we are done and continue looping.
*/
cond = mbedtls_ct_uint_lt(A[i - 1], B[i - 1]);
ret = mbedtls_ct_bool_or(ret, mbedtls_ct_bool_and(cond, mbedtls_ct_bool_not(done)));
done = mbedtls_ct_bool_or(done, cond);
}
/*
* If all the limbs were equal, then the numbers are equal, A < B is false
* and leaving the result 0 is correct.
*/
return ret;
}
void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
size_t limbs,
unsigned char assign)
mbedtls_ct_condition_t assign)
{
if (X == A) {
return;
}
mbedtls_ct_mpi_uint_cond_assign(limbs, X, A, assign);
/* This function is very performance-sensitive for RSA. For this reason
* we have the loop below, instead of calling mbedtls_ct_memcpy_if
* (this is more optimal since here we don't have to handle the case where
* we copy awkwardly sized data).
*/
for (size_t i = 0; i < limbs; i++) {
X[i] = mbedtls_ct_mpi_uint_if(assign, A[i], X[i]);
}
}
void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X,
mbedtls_mpi_uint *Y,
size_t limbs,
unsigned char swap)
mbedtls_ct_condition_t swap)
{
if (X == Y) {
return;
}
/* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
mbedtls_mpi_uint limb_mask = mbedtls_ct_mpi_uint_mask(swap);
for (size_t i = 0; i < limbs; i++) {
mbedtls_mpi_uint tmp = X[i];
X[i] = (X[i] & ~limb_mask) | (Y[i] & limb_mask);
Y[i] = (Y[i] & ~limb_mask) | (tmp & limb_mask);
X[i] = mbedtls_ct_mpi_uint_if(swap, Y[i], X[i]);
Y[i] = mbedtls_ct_mpi_uint_if(swap, tmp, Y[i]);
}
}
@ -422,11 +460,10 @@ mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X,
{
mbedtls_mpi_uint c = 0;
/* all-bits 0 if cond is 0, all-bits 1 if cond is non-0 */
const mbedtls_mpi_uint mask = mbedtls_ct_mpi_uint_mask(cond);
mbedtls_ct_condition_t do_add = mbedtls_ct_bool(cond);
for (size_t i = 0; i < limbs; i++) {
mbedtls_mpi_uint add = mask & A[i];
mbedtls_mpi_uint add = mbedtls_ct_mpi_uint_if_else_0(do_add, A[i]);
mbedtls_mpi_uint t = c + X[i];
c = (t < X[i]);
t += add;
@ -568,7 +605,11 @@ void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X,
* So the correct return value is already in X if (carry ^ borrow) = 0,
* but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1.
*/
mbedtls_ct_mpi_uint_cond_assign(AN_limbs, X, T, (unsigned char) (carry ^ borrow));
mbedtls_ct_memcpy_if(mbedtls_ct_bool(carry ^ borrow),
(unsigned char *) X,
(unsigned char *) T,
NULL,
AN_limbs * sizeof(mbedtls_mpi_uint));
}
int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X,
@ -593,7 +634,7 @@ void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest,
size_t index)
{
for (size_t i = 0; i < count; i++, table += limbs) {
unsigned char assign = mbedtls_ct_size_bool_eq(i, index);
mbedtls_ct_condition_t assign = mbedtls_ct_uint_eq(i, index);
mbedtls_mpi_core_cond_assign(dest, table, limbs, assign);
}
}
@ -633,7 +674,7 @@ int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
unsigned ge_lower = 1, lt_upper = 0;
mbedtls_ct_condition_t ge_lower = MBEDTLS_CT_TRUE, lt_upper = MBEDTLS_CT_FALSE;
size_t n_bits = mbedtls_mpi_core_bitlen(N, limbs);
size_t n_bytes = (n_bits + 7) / 8;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
@ -678,7 +719,7 @@ int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
ge_lower = mbedtls_mpi_core_uint_le_mpi(min, X, limbs);
lt_upper = mbedtls_mpi_core_lt_ct(X, N, limbs);
} while (ge_lower == 0 || lt_upper == 0);
} while (mbedtls_ct_bool_and(ge_lower, lt_upper) == MBEDTLS_CT_FALSE);
cleanup:
return ret;
@ -686,16 +727,16 @@ cleanup:
static size_t exp_mod_get_window_size(size_t Ebits)
{
size_t wsize = (Ebits > 671) ? 6 : (Ebits > 239) ? 5 :
(Ebits > 79) ? 4 : 1;
#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
if (wsize > MBEDTLS_MPI_WINDOW_SIZE) {
wsize = MBEDTLS_MPI_WINDOW_SIZE;
}
#if MBEDTLS_MPI_WINDOW_SIZE >= 6
return (Ebits > 671) ? 6 : (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;
#elif MBEDTLS_MPI_WINDOW_SIZE == 5
return (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;
#elif MBEDTLS_MPI_WINDOW_SIZE > 1
return (Ebits > 79) ? MBEDTLS_MPI_WINDOW_SIZE : 1;
#else
(void) Ebits;
return 1;
#endif
return wsize;
}
size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs)

View file

@ -86,6 +86,8 @@
#include "mbedtls/bignum.h"
#endif
#include "constant_time_internal.h"
#define ciL (sizeof(mbedtls_mpi_uint)) /** chars in limb */
#define biL (ciL << 3) /** bits in limb */
#define biH (ciL << 2) /** half limb size */
@ -142,11 +144,29 @@ void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A,
* \param A_limbs The number of limbs of \p A.
* This must be at least 1.
*
* \return 1 if \p min is less than or equal to \p A, otherwise 0.
* \return MBEDTLS_CT_TRUE if \p min is less than or equal to \p A, otherwise MBEDTLS_CT_FALSE.
*/
unsigned mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
const mbedtls_mpi_uint *A,
size_t A_limbs);
mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
const mbedtls_mpi_uint *A,
size_t A_limbs);
/**
* \brief Check if one unsigned MPI is less than another in constant
* time.
*
* \param A The left-hand MPI. This must point to an array of limbs
* with the same allocated length as \p B.
* \param B The right-hand MPI. This must point to an array of limbs
* with the same allocated length as \p A.
* \param limbs The number of limbs in \p A and \p B.
* This must not be 0.
*
* \return MBEDTLS_CT_TRUE if \p A is less than \p B.
* MBEDTLS_CT_FALSE if \p A is greater than or equal to \p B.
*/
mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
size_t limbs);
/**
* \brief Perform a safe conditional copy of an MPI which doesn't reveal
@ -158,21 +178,17 @@ unsigned mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
* \param[in] A The address of the source MPI. This must be initialized.
* \param limbs The number of limbs of \p A.
* \param assign The condition deciding whether to perform the
* assignment or not. Must be either 0 or 1:
* * \c 1: Perform the assignment `X = A`.
* * \c 0: Keep the original value of \p X.
* assignment or not. Callers will need to use
* the constant time interface (e.g. `mbedtls_ct_bool()`)
* to construct this argument.
*
* \note This function avoids leaking any information about whether
* the assignment was done or not.
*
* \warning If \p assign is neither 0 nor 1, the result of this function
* is indeterminate, and the resulting value in \p X might be
* neither its original value nor the value in \p A.
*/
void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
size_t limbs,
unsigned char assign);
mbedtls_ct_condition_t assign);
/**
* \brief Perform a safe conditional swap of two MPIs which doesn't reveal
@ -184,21 +200,15 @@ void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,
* This must be initialized.
* \param limbs The number of limbs of \p X and \p Y.
* \param swap The condition deciding whether to perform
* the swap or not. Must be either 0 or 1:
* * \c 1: Swap the values of \p X and \p Y.
* * \c 0: Keep the original values of \p X and \p Y.
* the swap or not.
*
* \note This function avoids leaking any information about whether
* the swap was done or not.
*
* \warning If \p swap is neither 0 nor 1, the result of this function
* is indeterminate, and both \p X and \p Y might end up with
* values different to either of the original ones.
*/
void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X,
mbedtls_mpi_uint *Y,
size_t limbs,
unsigned char swap);
mbedtls_ct_condition_t swap);
/** Import X from unsigned binary data, little-endian.
*

View file

@ -19,7 +19,7 @@
#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
#include <string.h>
@ -80,9 +80,8 @@ void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
switch (N->int_rep) {
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
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));
mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
N->rep.mont.rr = NULL;
}
N->rep.mont.mm = 0;
@ -295,9 +294,8 @@ int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
break;
}
mbedtls_platform_zeroize(working_memory,
mbedtls_zeroize_and_free(working_memory,
working_limbs * sizeof(mbedtls_mpi_uint));
mbedtls_free(working_memory);
return ret;
}
@ -399,11 +397,10 @@ cleanup:
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
working_memory != NULL) {
mbedtls_platform_zeroize(working_memory, working_memory_len);
mbedtls_free(working_memory);
mbedtls_zeroize_and_free(working_memory, working_memory_len);
}
return ret;
}
#endif /* MBEDTLS_BIGNUM_C */
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */

View file

@ -19,7 +19,7 @@
#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
#include <string.h>
@ -40,7 +40,7 @@ void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N,
unsigned char assign)
{
mbedtls_mpi_core_cond_assign(X, A, N->limbs, assign);
mbedtls_mpi_core_cond_assign(X, A, N->limbs, mbedtls_ct_bool(assign));
}
void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X,
@ -48,7 +48,7 @@ void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N,
unsigned char swap)
{
mbedtls_mpi_core_cond_swap(X, Y, N->limbs, swap);
mbedtls_mpi_core_cond_swap(X, Y, N->limbs, mbedtls_ct_bool(swap));
}
int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
@ -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,
N->rep.mont.mm, N->rep.mont.rr, T);
mbedtls_platform_zeroize(T, t_limbs * ciL);
mbedtls_free(T);
mbedtls_zeroize_and_free(T, t_limbs * ciL);
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_platform_zeroize(T, t_limbs * ciL);
mbedtls_free(T);
mbedtls_zeroize_and_free(T, t_limbs * ciL);
return 0;
}
@ -287,4 +285,4 @@ void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
}
#endif /* MBEDTLS_BIGNUM_C */
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */

View file

@ -60,25 +60,25 @@
#endif
#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))
#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
#endif
#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))
#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
#endif
#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))
#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
#endif
#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))
#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
#endif

View file

@ -231,8 +231,7 @@ void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
(void) psa_destroy_key(cipher_psa->slot);
}
mbedtls_platform_zeroize(cipher_psa, sizeof(*cipher_psa));
mbedtls_free(cipher_psa);
mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa));
}
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t));
@ -242,9 +241,8 @@ void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
#if defined(MBEDTLS_CMAC_C)
if (ctx->cmac_ctx) {
mbedtls_platform_zeroize(ctx->cmac_ctx,
mbedtls_zeroize_and_free(ctx->cmac_ctx,
sizeof(mbedtls_cmac_context_t));
mbedtls_free(ctx->cmac_ctx);
}
#endif

View file

@ -120,8 +120,10 @@ enum mbedtls_cipher_base_index {
MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE,
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS) && defined(MBEDTLS_AES_C)
MBEDTLS_CIPHER_BASE_INDEX_XTS_AES
MBEDTLS_CIPHER_BASE_INDEX_XTS_AES,
#endif
/* Prevent compile failure due to empty enum */
MBEDTLS_CIPHER_BASE_PREVENT_EMPTY_ENUM
};
#if defined(MBEDTLS_GCM_C)

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
/**
* \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.
*
* This is just the addition of an offset to a pointer, except that this
@ -274,7 +288,7 @@ static inline void mbedtls_xor_no_simd(unsigned char *r,
/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */
#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r"
#else
#error Unrecognised pointer size for aarch64
#error "Unrecognised pointer size for aarch64"
#endif
#endif
@ -295,8 +309,8 @@ static inline void mbedtls_xor_no_simd(unsigned char *r,
/* Define compiler branch hints */
#if defined(__has_builtin)
#if __has_builtin(__builtin_expect)
#define MBEDTLS_LIKELY(x) __builtin_expect((x), 1)
#define MBEDTLS_UNLIKELY(x) __builtin_expect((x), 0)
#define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1)
#define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0)
#endif
#endif
#if !defined(MBEDTLS_LIKELY)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,437 @@
/**
* Constant-time functions
*
* For readability, the static inline definitions are here, and
* constant_time_internal.h has only the declarations.
*
* This results in duplicate declarations of the form:
* static inline void f() { ... }
* static inline void f();
* when constant_time_internal.h is included. This appears to behave
* exactly as if the declaration-without-definition was not present.
*
* 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 MBEDTLS_CONSTANT_TIME_IMPL_H
#define MBEDTLS_CONSTANT_TIME_IMPL_H
#include <stddef.h>
#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
/* constant_time_impl.h contains all the static inline implementations,
* so that constant_time_internal.h is more readable.
*
* gcc generates warnings about duplicate declarations, so disable this
* warning.
*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
/* Disable asm under Memsan because it confuses Memsan and generates false errors.
*
* We also disable under Valgrind by default, because it's more useful
* for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names
* may be set to permit building asm under Valgrind.
*/
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \
(defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names
#define MBEDTLS_CT_NO_ASM
#elif defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_CT_NO_ASM
#endif
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \
__ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM)
#define MBEDTLS_CT_ASM
#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__))
#define MBEDTLS_CT_ARM_ASM
#elif defined(__aarch64__)
#define MBEDTLS_CT_AARCH64_ASM
#endif
#endif
#define MBEDTLS_CT_SIZE (sizeof(mbedtls_ct_uint_t) * 8)
/* ============================================================================
* Core const-time primitives
*/
/* Ensure that the compiler cannot know the value of x (i.e., cannot optimise
* based on its value) after this function is called.
*
* If we are not using assembly, this will be fairly inefficient, so its use
* should be minimised.
*/
#if !defined(MBEDTLS_CT_ASM)
extern volatile mbedtls_ct_uint_t mbedtls_ct_zero;
#endif
/**
* \brief Ensure that a value cannot be known at compile time.
*
* \param x The value to hide from the compiler.
* \return The same value that was passed in, such that the compiler
* cannot prove its value (even for calls of the form
* x = mbedtls_ct_compiler_opaque(1), x will be unknown).
*
* \note This is mainly used in constructing mbedtls_ct_condition_t
* values and performing operations over them, to ensure that
* there is no way for the compiler to ever know anything about
* the value of an mbedtls_ct_condition_t.
*/
static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x)
{
#if defined(MBEDTLS_CT_ASM)
asm volatile ("" : [x] "+r" (x) :);
return x;
#else
return x ^ mbedtls_ct_zero;
#endif
}
/*
* Selecting unified syntax is needed for gcc, and harmless on clang.
*
* This is needed because on Thumb 1, condition flags are always set, so
* e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist).
*
* Under Thumb 1 unified syntax, only the "negs" form is accepted, and
* under divided syntax, only the "neg" form is accepted. clang only
* supports unified syntax.
*
* On Thumb 2 and Arm, both compilers are happy with the "s" suffix,
* although we don't actually care about setting the flags.
*
* For gcc, restore divided syntax afterwards - otherwise old versions of gcc
* seem to apply unified syntax globally, which breaks other asm code.
*/
#if !defined(__clang__)
#define RESTORE_ASM_SYNTAX ".syntax divided \n\t"
#else
#define RESTORE_ASM_SYNTAX
#endif
/* Convert a number into a condition in constant time. */
static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x)
{
/*
* Define mask-generation code that, as far as possible, will not use branches or conditional instructions.
*
* For some platforms / type sizes, we define assembly to assure this.
*
* Otherwise, we define a plain C fallback which (in May 2023) does not get optimised into
* conditional instructions or branches by trunk clang, gcc, or MSVC v19.
*/
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
mbedtls_ct_uint_t s;
asm volatile ("neg %x[s], %x[x] \n\t"
"orr %x[x], %x[s], %x[x] \n\t"
"asr %x[x], %x[x], 63"
:
[s] "=&r" (s),
[x] "+&r" (x)
:
:
);
return (mbedtls_ct_condition_t) x;
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
uint32_t s;
asm volatile (".syntax unified \n\t"
"negs %[s], %[x] \n\t"
"orrs %[x], %[x], %[s] \n\t"
"asrs %[x], %[x], #31 \n\t"
RESTORE_ASM_SYNTAX
:
[s] "=&l" (s),
[x] "+&l" (x)
:
:
"cc" /* clobbers flag bits */
);
return (mbedtls_ct_condition_t) x;
#else
const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x);
#if defined(_MSC_VER)
/* MSVC has a warning about unary minus on unsigned, but this is
* well-defined and precisely what we want to do here */
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
// y is negative (i.e., top bit set) iff x is non-zero
mbedtls_ct_int_t y = (-xo) | -(xo >> 1);
// extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero)
y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1));
// -y has all bits set (if x is non-zero), or all bits clear (if x is zero)
return (mbedtls_ct_condition_t) (-y);
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
#endif
}
static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition,
mbedtls_ct_uint_t if1,
mbedtls_ct_uint_t if0)
{
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t"
"mvn %x[condition], %x[condition] \n\t"
"and %x[condition], %x[condition], %x[if0] \n\t"
"orr %x[condition], %x[if1], %x[condition]"
:
[condition] "+&r" (condition),
[if1] "+&r" (if1)
:
[if0] "r" (if0)
:
);
return (mbedtls_ct_uint_t) condition;
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
asm volatile (".syntax unified \n\t"
"ands %[if1], %[if1], %[condition] \n\t"
"mvns %[condition], %[condition] \n\t"
"ands %[condition], %[condition], %[if0] \n\t"
"orrs %[condition], %[if1], %[condition] \n\t"
RESTORE_ASM_SYNTAX
:
[condition] "+&l" (condition),
[if1] "+&l" (if1)
:
[if0] "l" (if0)
:
"cc"
);
return (mbedtls_ct_uint_t) condition;
#else
mbedtls_ct_condition_t not_cond =
(mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition));
return (mbedtls_ct_uint_t) ((condition & if1) | (not_cond & if0));
#endif
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
{
#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64))
uint64_t s1;
asm volatile ("eor %x[s1], %x[y], %x[x] \n\t"
"sub %x[x], %x[x], %x[y] \n\t"
"bic %x[x], %x[x], %x[s1] \n\t"
"and %x[s1], %x[s1], %x[y] \n\t"
"orr %x[s1], %x[x], %x[s1] \n\t"
"asr %x[x], %x[s1], 63"
: [s1] "=&r" (s1), [x] "+&r" (x)
: [y] "r" (y)
:
);
return (mbedtls_ct_condition_t) x;
#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32)
uint32_t s1;
asm volatile (
".syntax unified \n\t"
#if defined(__thumb__) && !defined(__thumb2__)
"movs %[s1], %[x] \n\t"
"eors %[s1], %[s1], %[y] \n\t"
#else
"eors %[s1], %[x], %[y] \n\t"
#endif
"subs %[x], %[x], %[y] \n\t"
"bics %[x], %[x], %[s1] \n\t"
"ands %[y], %[s1], %[y] \n\t"
"orrs %[x], %[x], %[y] \n\t"
"asrs %[x], %[x], #31 \n\t"
RESTORE_ASM_SYNTAX
: [s1] "=&l" (s1), [x] "+&l" (x), [y] "+&l" (y)
:
:
"cc"
);
return (mbedtls_ct_condition_t) x;
#else
/* Ensure that the compiler cannot optimise the following operations over x and y,
* even if it knows the value of x and y.
*/
const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x);
const mbedtls_ct_uint_t yo = mbedtls_ct_compiler_opaque(y);
/*
* Check if the most significant bits (MSB) of the operands are different.
* cond is true iff the MSBs differ.
*/
mbedtls_ct_condition_t cond = mbedtls_ct_bool((xo ^ yo) >> (MBEDTLS_CT_SIZE - 1));
/*
* If the MSB are the same then the difference x-y will be negative (and
* have its MSB set to 1 during conversion to unsigned) if and only if x<y.
*
* If the MSB are different, then the operand with the MSB of 1 is the
* bigger. (That is if y has MSB of 1, then x<y is true and it is false if
* the MSB of y is 0.)
*/
// Select either y, or x - y
mbedtls_ct_uint_t ret = mbedtls_ct_if(cond, yo, (mbedtls_ct_uint_t) (xo - yo));
// Extract only the MSB of ret
ret = ret >> (MBEDTLS_CT_SIZE - 1);
// Convert to a condition (i.e., all bits set iff non-zero)
return mbedtls_ct_bool(ret);
#endif
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
{
/* diff = 0 if x == y, non-zero otherwise */
const mbedtls_ct_uint_t diff = mbedtls_ct_compiler_opaque(x) ^ mbedtls_ct_compiler_opaque(y);
/* all ones if x != y, 0 otherwise */
return mbedtls_ct_bool(diff);
}
static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
unsigned char high,
unsigned char c,
unsigned char t)
{
const unsigned char co = (unsigned char) mbedtls_ct_compiler_opaque(c);
const unsigned char to = (unsigned char) mbedtls_ct_compiler_opaque(t);
/* low_mask is: 0 if low <= c, 0x...ff if low > c */
unsigned low_mask = ((unsigned) co - low) >> 8;
/* high_mask is: 0 if c <= high, 0x...ff if c > high */
unsigned high_mask = ((unsigned) high - co) >> 8;
return (unsigned char) (~(low_mask | high_mask)) & to;
}
/* ============================================================================
* Everything below here is trivial wrapper functions
*/
static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
size_t if1,
size_t if0)
{
return (size_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0);
}
static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
unsigned if1,
unsigned if0)
{
return (unsigned) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0);
}
#if defined(MBEDTLS_BIGNUM_C)
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition,
mbedtls_mpi_uint if1,
mbedtls_mpi_uint if0)
{
return (mbedtls_mpi_uint) mbedtls_ct_if(condition,
(mbedtls_ct_uint_t) if1,
(mbedtls_ct_uint_t) if0);
}
#endif
static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1)
{
return (size_t) (condition & if1);
}
static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1)
{
return (unsigned) (condition & if1);
}
#if defined(MBEDTLS_BIGNUM_C)
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
mbedtls_mpi_uint if1)
{
return (mbedtls_mpi_uint) (condition & if1);
}
#endif /* MBEDTLS_BIGNUM_C */
static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y)
{
return ~mbedtls_ct_uint_ne(x, y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y)
{
return mbedtls_ct_uint_lt(y, x);
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y)
{
return ~mbedtls_ct_uint_lt(x, y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y)
{
return ~mbedtls_ct_uint_gt(x, y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y)
{
return (mbedtls_ct_condition_t) (x ^ y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y)
{
return (mbedtls_ct_condition_t) (x & y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y)
{
return (mbedtls_ct_condition_t) (x | y);
}
static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x)
{
return (mbedtls_ct_condition_t) (~x);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif /* MBEDTLS_CONSTANT_TIME_IMPL_H */

View file

@ -20,224 +20,444 @@
#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
#include <stdint.h>
#include <stddef.h>
#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
#if defined(MBEDTLS_SSL_TLS_C)
#include "ssl_misc.h"
/* The constant-time interface provides various operations that are likely
* to result in constant-time code that does not branch or use conditional
* instructions for secret data (for secret pointers, this also applies to
* the data pointed to).
*
* It has three main parts:
*
* - boolean operations
* These are all named mbedtls_ct_<type>_<operation>.
* They operate over <type> and return mbedtls_ct_condition_t.
* All arguments are considered secret.
* example: bool x = y | z => x = mbedtls_ct_bool_or(y, z)
* example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z)
*
* - conditional data selection
* These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
* All arguments are considered secret.
* example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)
* example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint__if_else_0(x, b)
*
* - block memory operations
* Only some arguments are considered secret, as documented for each
* function.
* example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)
*
* mbedtls_ct_condition_t must be treated as opaque and only created and
* manipulated via the functions in this header. The compiler should never
* be able to prove anything about its value at compile-time.
*
* mbedtls_ct_uint_t is an unsigned integer type over which constant time
* operations may be performed via the functions in this header. It is as big
* as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
* to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
* not-larger integer types).
*
* For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
* are used to ensure that the generated code is constant time. For other
* architectures, it uses a plain C fallback designed to yield constant-time code
* (this has been observed to be constant-time on latest gcc, clang and MSVC
* as of May 2023).
*
* For readability, the static inline definitions are separated out into
* constant_time_impl.h.
*/
#if (SIZE_MAX > 0xffffffffffffffffULL)
/* Pointer size > 64-bit */
typedef size_t mbedtls_ct_condition_t;
typedef size_t mbedtls_ct_uint_t;
typedef ptrdiff_t mbedtls_ct_int_t;
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
typedef uint64_t mbedtls_ct_condition_t;
typedef uint64_t mbedtls_ct_uint_t;
typedef int64_t mbedtls_ct_int_t;
#define MBEDTLS_CT_SIZE_64
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
#else
/* Pointer size <= 32-bit, and no 64-bit MPIs */
typedef uint32_t mbedtls_ct_condition_t;
typedef uint32_t mbedtls_ct_uint_t;
typedef int32_t mbedtls_ct_int_t;
#define MBEDTLS_CT_SIZE_32
#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
#endif
#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
#include <stddef.h>
/** Turn a value into a mask:
* - if \p value == 0, return the all-bits 0 mask, aka 0
* - otherwise, return the all-bits 1 mask, aka (unsigned) -1
*
* This function can be used to write constant-time code by replacing branches
* with bit operations using masks.
*
* \param value The value to analyze.
*
* \return Zero if \p value is zero, otherwise all-bits-one.
/* ============================================================================
* Boolean operations
*/
unsigned mbedtls_ct_uint_mask(unsigned value);
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
/** Turn a value into a mask:
* - if \p value == 0, return the all-bits 0 mask, aka 0
* - otherwise, return the all-bits 1 mask, aka (size_t) -1
/** Convert a number into a mbedtls_ct_condition_t.
*
* This function can be used to write constant-time code by replacing branches
* with bit operations using masks.
* \param x Number to convert.
*
* \param value The value to analyze.
* \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
*
* \return Zero if \p value is zero, otherwise all-bits-one.
*/
size_t mbedtls_ct_size_mask(size_t value);
static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
#if defined(MBEDTLS_BIGNUM_C)
/** Turn a value into a mask:
* - if \p value == 0, return the all-bits 0 mask, aka 0
* - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
/** Boolean "not equal" operation.
*
* This function can be used to write constant-time code by replacing branches
* with bit operations using masks.
* Functionally equivalent to:
*
* \param value The value to analyze.
*
* \return Zero if \p value is zero, otherwise all-bits-one.
*/
mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value);
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
/** Constant-flow mask generation for "greater or equal" comparison:
* - if \p x >= \p y, return all-bits 1, that is (size_t) -1
* - otherwise, return all bits 0, that is 0
*
* This function can be used to write constant-time code by replacing branches
* with bit operations using masks.
* \p x != \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return All-bits-one if \p x is greater or equal than \p y,
* otherwise zero.
* \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
*/
size_t mbedtls_ct_size_mask_ge(size_t x,
size_t y);
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
/** Constant-flow boolean "equal" comparison:
* return x == y
/** Boolean "equals" operation.
*
* This is equivalent to \p x == \p y, but is likely to be compiled
* to code using bitwise operation rather than a branch.
* Functionally equivalent to:
*
* \p x == \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return 1 if \p x equals to \p y, otherwise 0.
* \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
*/
unsigned mbedtls_ct_size_bool_eq(size_t x,
size_t y);
static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y);
#if defined(MBEDTLS_BIGNUM_C)
/** Decide if an integer is less than the other, without branches.
/** Boolean "less than" operation.
*
* This is equivalent to \p x < \p y, but is likely to be compiled
* to code using bitwise operation rather than a branch.
* Functionally equivalent to:
*
* \p x < \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return 1 if \p x is less than \p y, otherwise 0.
* \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
*/
unsigned mbedtls_ct_mpi_uint_lt(const mbedtls_mpi_uint x,
const mbedtls_mpi_uint y);
static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
/**
* \brief Check if one unsigned MPI is less than another in constant
* time.
/** Boolean "greater than" operation.
*
* \param A The left-hand MPI. This must point to an array of limbs
* with the same allocated length as \p B.
* \param B The right-hand MPI. This must point to an array of limbs
* with the same allocated length as \p A.
* \param limbs The number of limbs in \p A and \p B.
* This must not be 0.
* Functionally equivalent to:
*
* \return The result of the comparison:
* \c 1 if \p A is less than \p B.
* \c 0 if \p A is greater than or equal to \p B.
* \p x > \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
*/
unsigned mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *B,
size_t limbs);
#endif /* MBEDTLS_BIGNUM_C */
static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y);
/** Choose between two integer values without branches.
/** Boolean "greater or equal" operation.
*
* This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
* to code using bitwise operation rather than a branch.
* Functionally equivalent to:
*
* \p x >= \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return MBEDTLS_CT_TRUE if \p x >= \p y,
* otherwise MBEDTLS_CT_FALSE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y);
/** Boolean "less than or equal" operation.
*
* Functionally equivalent to:
*
* \p x <= \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return MBEDTLS_CT_TRUE if \p x <= \p y,
* otherwise MBEDTLS_CT_FALSE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
mbedtls_ct_uint_t y);
/** Boolean "xor" operation.
*
* Functionally equivalent to:
*
* \p x ^ \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \note This is more efficient than mbedtls_ct_uint_ne if both arguments are
* mbedtls_ct_condition_t.
*
* \return MBEDTLS_CT_TRUE if \p x ^ \p y,
* otherwise MBEDTLS_CT_FALSE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y);
/** Boolean "and" operation.
*
* Functionally equivalent to:
*
* \p x && \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return MBEDTLS_CT_TRUE if \p x && \p y,
* otherwise MBEDTLS_CT_FALSE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y);
/** Boolean "or" operation.
*
* Functionally equivalent to:
*
* \p x || \p y
*
* \param x The first value to analyze.
* \param y The second value to analyze.
*
* \return MBEDTLS_CT_TRUE if \p x || \p y,
* otherwise MBEDTLS_CT_FALSE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
mbedtls_ct_condition_t y);
/** Boolean "not" operation.
*
* Functionally equivalent to:
*
* ! \p x
*
* \param x The value to invert
*
* \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
*/
static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
/* ============================================================================
* Data selection operations
*/
/** Choose between two size_t values.
*
* Functionally equivalent to:
*
* condition ? if1 : if0.
*
* \param condition Condition to test.
* \param if1 Value to use if \p condition is nonzero.
* \param if0 Value to use if \p condition is zero.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
*
* \return \c if1 if \p condition is nonzero, otherwise \c if0.
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
*/
unsigned mbedtls_ct_uint_if(unsigned condition,
unsigned if1,
unsigned if0);
static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
size_t if1,
size_t if0);
/** Choose between two unsigned values.
*
* Functionally equivalent to:
*
* condition ? if1 : if0.
*
* \param condition Condition to test.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
*
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
*/
static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
unsigned if1,
unsigned if0);
#if defined(MBEDTLS_BIGNUM_C)
/** Conditionally assign a value without branches.
/** Choose between two mbedtls_mpi_uint values.
*
* This is equivalent to `if ( condition ) dest = src`, but is likely
* to be compiled to code using bitwise operation rather than a branch.
* Functionally equivalent to:
*
* \param n \p dest and \p src must be arrays of limbs of size n.
* \param dest The MPI to conditionally assign to. This must point
* to an initialized MPI.
* \param src The MPI to be assigned from. This must point to an
* initialized MPI.
* \param condition Condition to test, must be 0 or 1.
* condition ? if1 : if0.
*
* \param condition Condition to test.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
* \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
*
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
*/
void mbedtls_ct_mpi_uint_cond_assign(size_t n,
mbedtls_mpi_uint *dest,
const mbedtls_mpi_uint *src,
unsigned char condition);
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
mbedtls_mpi_uint if1, \
mbedtls_mpi_uint if0);
#endif /* MBEDTLS_BIGNUM_C */
#endif
#if defined(MBEDTLS_BASE64_C)
/** Given a value in the range 0..63, return the corresponding Base64 digit.
/** Choose between an unsigned value and 0.
*
* The implementation assumes that letters are consecutive (e.g. ASCII
* but not EBCDIC).
* Functionally equivalent to:
*
* \param value A value in the range 0..63.
* condition ? if1 : 0.
*
* \return A base64 digit converted from \p value.
* Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
* results in smaller code size.
*
* \param condition Condition to test.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
*
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
*/
unsigned char mbedtls_ct_base64_enc_char(unsigned char value);
static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
/** Given a Base64 digit, return its value.
/** Choose between a size_t value and 0.
*
* If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
* return -1.
* Functionally equivalent to:
*
* The implementation assumes that letters are consecutive (e.g. ASCII
* but not EBCDIC).
* condition ? if1 : 0.
*
* \param c A base64 digit.
* Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
* results in smaller code size.
*
* \return The value of the base64 digit \p c.
* \param condition Condition to test.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
*
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
*/
signed char mbedtls_ct_base64_dec_value(unsigned char c);
static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
/** Conditional memcpy without branches.
/** Choose between an mbedtls_mpi_uint value and 0.
*
* This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
* to be compiled to code using bitwise operation rather than a branch.
* Functionally equivalent to:
*
* \param dest The pointer to conditionally copy to.
* \param src The pointer to copy from. Shouldn't overlap with \p dest.
* \param len The number of bytes to copy.
* \param c1 The first value to analyze in the condition.
* \param c2 The second value to analyze in the condition.
* condition ? if1 : 0.
*
* Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
* results in smaller code size.
*
* \param condition Condition to test.
* \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
*
* \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
*/
void mbedtls_ct_memcpy_if_eq(unsigned char *dest,
const unsigned char *src,
size_t len,
size_t c1, size_t c2);
static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
mbedtls_mpi_uint if1);
/** Copy data from a secret position with constant flow.
#endif
/** Constant-flow char selection
*
* This function copies \p len bytes from \p src_base + \p offset_secret to \p
* dst, with a code flow and memory access pattern that does not depend on \p
* offset_secret, but only on \p offset_min, \p offset_max and \p len.
* Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
* \param low Secret. Bottom of range
* \param high Secret. Top of range
* \param c Secret. Value to compare to range
* \param t Secret. Value to return, if in range
*
* \return \p t if \p low <= \p c <= \p high, 0 otherwise.
*/
static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
unsigned char high,
unsigned char c,
unsigned char t);
/* ============================================================================
* Block memory operations
*/
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
/** Conditionally set a block of memory to zero.
*
* Regardless of the condition, every byte will be read once and written to
* once.
*
* \param condition Secret. Condition to test.
* \param buf Secret. Pointer to the start of the buffer.
* \param len Number of bytes to set to zero.
*
* \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
* about not being optimised away if the memory is never read again.
*/
void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
/** Shift some data towards the left inside a buffer.
*
* Functionally equivalent to:
*
* memmove(start, start + offset, total - offset);
* memset(start + (total - offset), 0, offset);
*
* Timing independence comes at the expense of performance.
*
* \param start Secret. Pointer to the start of the buffer.
* \param total Total size of the buffer.
* \param offset Secret. Offset from which to copy \p total - \p offset bytes.
*/
void mbedtls_ct_memmove_left(void *start,
size_t total,
size_t offset);
#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
/** Conditional memcpy.
*
* Functionally equivalent to:
*
* if (condition) {
* memcpy(dest, src1, len);
* } else {
* if (src2 != NULL)
* memcpy(dest, src2, len);
* }
*
* It will always read len bytes from src1.
* If src2 != NULL, it will always read len bytes from src2.
* If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
*
* \param condition The condition
* \param dest Secret. Destination pointer.
* \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
* This may be equal to \p dest, but may not overlap in other ways.
* \param src2 Secret (contents only - may branch to determine if this parameter is NULL).
* Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
* This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
* \param len Number of bytes to copy.
*/
void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
unsigned char *dest,
const unsigned char *src1,
const unsigned char *src2,
size_t len
);
/** Copy data from a secret position.
*
* Functionally equivalent to:
*
* memcpy(dst, src + offset, len)
*
* This function copies \p len bytes from \p src_base + \p offset to \p
* dst, with a code flow and memory access pattern that does not depend on
* \p offset, but only on \p offset_min, \p offset_max and \p len.
*
* \note This function reads from \p dest, but the value that
* is read does not influence the result and this
@ -246,12 +466,12 @@ void mbedtls_ct_memcpy_if_eq(unsigned char *dest,
* positives from static or dynamic analyzers, especially
* if \p dest is not initialized.
*
* \param dest The destination buffer. This must point to a writable
* \param dest Secret. The destination buffer. This must point to a writable
* buffer of at least \p len bytes.
* \param src The base of the source buffer. This must point to a
* \param src Secret. The base of the source buffer. This must point to a
* readable buffer of at least \p offset_max + \p len
* bytes. Shouldn't overlap with \p dest.
* \param offset The offset in the source buffer from which to copy.
* bytes. Shouldn't overlap with \p dest
* \param offset Secret. The offset in the source buffer from which to copy.
* This must be no less than \p offset_min and no greater
* than \p offset_max.
* \param offset_min The minimal value of \p offset.
@ -265,99 +485,14 @@ void mbedtls_ct_memcpy_offset(unsigned char *dest,
size_t offset_max,
size_t len);
/** Compute the HMAC of variable-length data with constant flow.
*
* This function computes the HMAC of the concatenation of \p add_data and \p
* data, and does with a code flow and memory access pattern that does not
* depend on \p data_len_secret, but only on \p min_data_len and \p
* max_data_len. In particular, this function always reads exactly \p
* max_data_len bytes from \p data.
*
* \param ctx The HMAC context. It must have keys configured
* with mbedtls_md_hmac_starts() and use one of the
* following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
* It is reset using mbedtls_md_hmac_reset() after
* the computation is complete to prepare for the
* next computation.
* \param add_data The first part of the message whose HMAC is being
* calculated. This must point to a readable buffer
* of \p add_data_len bytes.
* \param add_data_len The length of \p add_data in bytes.
* \param data The buffer containing the second part of the
* message. This must point to a readable buffer
* of \p max_data_len bytes.
* \param data_len_secret The length of the data to process in \p data.
* This must be no less than \p min_data_len and no
* greater than \p max_data_len.
* \param min_data_len The minimal length of the second part of the
* message, read from \p data.
* \param max_data_len The maximal length of the second part of the
* message, read from \p data.
* \param output The HMAC will be written here. This must point to
* a writable buffer of sufficient size to hold the
* HMAC value.
*
* \retval 0 on success.
* \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
* The hardware accelerator failed.
/* Documented in include/mbedtls/constant_time.h. a and b are secret.
int mbedtls_ct_memcmp(const void *a,
const void *b,
size_t n);
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output);
#else
int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
* operation (EME-PKCS1-v1_5 decoding).
*
* \note The return value from this function is a sensitive value
* (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
* in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
* is often a situation that an attacker can provoke and leaking which
* one is the result is precisely the information the attacker wants.
*
* \param input The input buffer which is the payload inside PKCS#1v1.5
* encryption padding, called the "encoded message EM"
* by the terminology.
* \param ilen The length of the payload in the \p input buffer.
* \param output The buffer for the payload, called "message M" by the
* PKCS#1 terminology. This must be a writable buffer of
* length \p output_max_len bytes.
* \param olen The address at which to store the length of
* the payload. This must not be \c NULL.
* \param output_max_len The length in bytes of the output buffer \p output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
* The output buffer is too small for the unpadded payload.
* \return #MBEDTLS_ERR_RSA_INVALID_PADDING
* The input doesn't contain properly formatted padding.
*/
int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
size_t *olen);
#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
/* Include the implementation of static inline functions above. */
#include "constant_time_impl.h"
#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */

View file

@ -1,51 +0,0 @@
/**
* \file constant_time_invasive.h
*
* \brief Constant-time module: interfaces for invasive testing only.
*
* The interfaces in this file are intended for testing purposes only.
* They SHOULD NOT be made available in library integrations except when
* building the library for testing.
*/
/*
* 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 MBEDTLS_CONSTANT_TIME_INVASIVE_H
#define MBEDTLS_CONSTANT_TIME_INVASIVE_H
#include "common.h"
#if defined(MBEDTLS_TEST_HOOKS)
/** Turn a value into a mask:
* - if \p low <= \p c <= \p high,
* return the all-bits 1 mask, aka (unsigned) -1
* - otherwise, return the all-bits 0 mask, aka 0
*
* \param low The value to analyze.
* \param high The value to analyze.
* \param c The value to analyze.
*
* \return All-bits-one if \p low <= \p c <= \p high, otherwise zero.
*/
unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low,
unsigned char high,
unsigned char c);
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* MBEDTLS_CONSTANT_TIME_INVASIVE_H */

View file

@ -19,7 +19,7 @@
/*
* The NIST SP 800-90 DRBGs are described in the following publication.
*
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf
*/
#include "common.h"

View file

@ -144,7 +144,6 @@ void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
debug_send_line(ssl, level, file, line, str);
idx = 0;
memset(txt, 0, sizeof(txt));
for (i = 0; i < len; i++) {
if (i >= 4096) {
@ -202,17 +201,54 @@ void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
}
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_BIGNUM_C)
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
static void mbedtls_debug_print_ec_coord(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len)
{
char str[DEBUG_BUF_SIZE];
size_t i, idx = 0;
mbedtls_snprintf(str + idx, sizeof(str) - idx, "value of '%s' (%u bits) is:\n",
text, (unsigned int) len * 8);
debug_send_line(ssl, level, file, line, str);
for (i = 0; i < len; i++) {
if (i >= 4096) {
break;
}
if (i % 16 == 0) {
if (i > 0) {
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
debug_send_line(ssl, level, file, line, str);
idx = 0;
}
}
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
(unsigned int) buf[i]);
}
if (len > 0) {
for (/* i = i */; i % 16 != 0; i++) {
idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " ");
}
mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
debug_send_line(ssl, level, file, line, str);
}
}
void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_pk_context *pk)
{
char str[DEBUG_BUF_SIZE];
mbedtls_mpi mpi;
const uint8_t *mpi_start;
size_t mpi_len;
int ret;
const uint8_t *coord_start;
size_t coord_len;
if (NULL == ssl ||
NULL == ssl->conf ||
@ -223,32 +259,21 @@ void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
/* For the description of pk->pk_raw content please refer to the description
* psa_export_public_key() function. */
mpi_len = (pk->pub_raw_len - 1)/2;
coord_len = (pk->pub_raw_len - 1)/2;
/* X coordinate */
mbedtls_mpi_init(&mpi);
mpi_start = pk->pub_raw + 1;
ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
if (ret != 0) {
return;
}
coord_start = pk->pub_raw + 1;
mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
mbedtls_mpi_free(&mpi);
mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len);
/* Y coordinate */
mbedtls_mpi_init(&mpi);
mpi_start = mpi_start + mpi_len;
ret = mbedtls_mpi_read_binary(&mpi, mpi_start, mpi_len);
if (ret != 0) {
return;
}
coord_start = coord_start + coord_len;
mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
mbedtls_debug_print_mpi(ssl, level, file, line, str, &mpi);
mbedtls_mpi_free(&mpi);
mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len);
}
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
#if defined(MBEDTLS_BIGNUM_C)
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X)
@ -324,19 +349,21 @@ static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
mbedtls_snprintf(name, sizeof(name), "%s%s", text, items[i].name);
name[sizeof(name) - 1] = '\0';
#if defined(MBEDTLS_RSA_C)
if (items[i].type == MBEDTLS_PK_DEBUG_MPI) {
mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value);
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_LIGHT)
if (items[i].type == MBEDTLS_PK_DEBUG_ECP) {
mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
} else
#endif
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
} else
#endif
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
{ debug_send_line(ssl, level, file, line,
"should not happen\n"); }
}
@ -397,7 +424,8 @@ void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
}
#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,
int level, const char *file,
int line,
@ -443,6 +471,7 @@ void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
}
#endif
}
#endif /* MBEDTLS_ECDH_C */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
MBEDTLS_ECDH_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) {
fclose(f);
mbedtls_platform_zeroize(*buf, *n + 1);
mbedtls_free(*buf);
mbedtls_zeroize_and_free(*buf, *n + 1);
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);
mbedtls_platform_zeroize(buf, n);
mbedtls_free(buf);
mbedtls_zeroize_and_free(buf, n);
return ret;
}

View file

@ -373,7 +373,7 @@ modn:
#if defined(MBEDTLS_ECP_RESTARTABLE)
if (rs_ctx != NULL && rs_ctx->sig != NULL) {
mbedtls_mpi_copy(r, pr);
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr));
}
#endif
@ -447,7 +447,7 @@ int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len));
MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len));
mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len);
MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len));
#if defined(MBEDTLS_ECP_RESTARTABLE)
if (rs_ctx != NULL && rs_ctx->det != NULL) {

View file

@ -43,8 +43,6 @@
#include "common.h"
#if !defined(MBEDTLS_ECP_WITH_MPI_UINT)
/**
* \brief Function level alternative implementation.
*
@ -594,6 +592,11 @@ void mbedtls_ecp_group_free(mbedtls_ecp_group *grp)
mbedtls_mpi_free(&grp->A);
mbedtls_mpi_free(&grp->B);
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) {
@ -1252,7 +1255,7 @@ static int ecp_sw_rhs(const mbedtls_ecp_group *grp,
MPI_ECP_SQR(rhs, X);
/* Special case for A = -3 */
if (grp->A.p == NULL) {
if (mbedtls_ecp_group_a_is_minus_3(grp)) {
MPI_ECP_SUB_INT(rhs, rhs, 3);
} else {
MPI_ECP_ADD(rhs, rhs, &grp->A);
@ -1523,7 +1526,7 @@ static int ecp_double_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Special case for A = -3 */
if (grp->A.p == NULL) {
if (mbedtls_ecp_group_a_is_minus_3(grp)) {
/* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */
MPI_ECP_SQR(&tmp[1], &P->Z);
MPI_ECP_ADD(&tmp[2], &P->X, &tmp[1]);
@ -3636,18 +3639,6 @@ cleanup:
#endif /* MBEDTLS_SELF_TEST */
#if defined(MBEDTLS_TEST_HOOKS)
MBEDTLS_STATIC_TESTABLE
mbedtls_ecp_variant mbedtls_ecp_get_variant()
{
return MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT;
}
#endif /* MBEDTLS_TEST_HOOKS */
#endif /* !MBEDTLS_ECP_ALT */
#endif /* MBEDTLS_ECP_LIGHT */
#endif /* !MBEDTLS_ECP_WITH_MPI_UINT */

File diff suppressed because it is too large Load diff

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