Merge remote-tracking branch 'development' into psa_crypto_config-in-full

Conflicts:
* tests/scripts/all.sh: component_test_crypto_full_no_cipher was removed
  in the development branch.
This commit is contained in:
Gilles Peskine 2023-08-17 19:46:34 +02:00
commit 73936868b8
208 changed files with 12718 additions and 8403 deletions

View file

@ -372,7 +372,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

@ -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,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 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,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,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

@ -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

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
@ -161,6 +161,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 +208,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 +261,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

@ -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
@ -449,7 +425,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 +790,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 +986,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 +1099,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

@ -273,6 +273,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 +439,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 +524,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 +849,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 +1044,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. */

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

@ -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

View file

@ -1998,8 +1998,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
@ -3781,6 +3788,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 +4007,13 @@
*/
//#define MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
/**
* Uncomment to enable using new bignum code in the ECC modules.
*
* \warning This is currently experimental, incomplete and therefore should not
* be used in production.
*/
//#define MBEDTLS_ECP_WITH_MPI_UINT
/** \} name SECTION: Module configuration options */

View file

@ -467,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

@ -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
*/

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.
*/

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

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

@ -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

@ -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

@ -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

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

@ -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 4096u
/* 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
*/
@ -1094,6 +1094,11 @@ 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;
}

View file

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

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;
}

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

@ -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,8 +397,7 @@ 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;

View file

@ -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;
}

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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,306 @@
/**
* 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 */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
#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
}
/* 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.
*/
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
return (mbedtls_ct_condition_t) (((mbedtls_ct_int_t) ((-xo) | -(xo >> 1))) >>
(MBEDTLS_CT_SIZE - 1));
#if defined(_MSC_VER)
#pragma warning( pop )
#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)
{
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));
}
static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y)
{
/* 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);
}
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 = (const unsigned char) mbedtls_ct_compiler_opaque(c);
const unsigned char to = (const 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,442 @@
#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_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_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 +464,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 +483,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

@ -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

6055
library/ecp_curves_new.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -40,11 +40,6 @@ typedef enum {
MBEDTLS_ECP_MOD_SCALAR
} mbedtls_ecp_modulus_type;
/* Provide a commented-out definition so that `check_names.py` knows that
* it's not a typo.
*/
//#define MBEDTLS_ECP_WITH_MPI_UINT
typedef enum {
MBEDTLS_ECP_VARIANT_NONE = 0,
MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT,

File diff suppressed because it is too large Load diff

View file

@ -438,8 +438,10 @@ int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
}
ctx->params.type =
mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN,
key + MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
(mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
MBEDTLS_LMOTS_TYPE_LEN,
key +
MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;

View file

@ -249,8 +249,10 @@ int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
mbedtls_lms_algorithm_type_t type;
mbedtls_lmots_algorithm_type_t otstype;
type = mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMS_TYPE_LEN,
key + PUBLIC_KEY_TYPE_OFFSET);
type = (mbedtls_lms_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
MBEDTLS_LMS_TYPE_LEN,
key +
PUBLIC_KEY_TYPE_OFFSET);
if (type != MBEDTLS_LMS_SHA256_M32_H10) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
@ -260,8 +262,10 @@ int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
otstype = mbedtls_lms_network_bytes_to_unsigned_int(MBEDTLS_LMOTS_TYPE_LEN,
key + PUBLIC_KEY_OTSTYPE_OFFSET);
otstype = (mbedtls_lmots_algorithm_type_t) mbedtls_lms_network_bytes_to_unsigned_int(
MBEDTLS_LMOTS_TYPE_LEN,
key +
PUBLIC_KEY_OTSTYPE_OFFSET);
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
}
@ -537,9 +541,8 @@ static int get_merkle_path(mbedtls_lms_private_t *ctx,
ret = 0;
exit:
mbedtls_platform_zeroize(tree, node_bytes *
mbedtls_zeroize_and_free(tree, node_bytes *
MERKLE_TREE_NODE_AM(ctx->params.type));
mbedtls_free(tree);
return ret;
}
@ -700,9 +703,8 @@ int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
ret = 0;
exit:
mbedtls_platform_zeroize(tree, node_bytes *
mbedtls_zeroize_and_free(tree, node_bytes *
MERKLE_TREE_NODE_AM(priv_ctx->params.type));
mbedtls_free(tree);
return ret;
}

View file

@ -76,102 +76,75 @@
#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE"
#endif
#if defined(MBEDTLS_MD_C)
#define MD_INFO(type, out_size, block_size) type, out_size, block_size,
#else
#define MD_INFO(type, out_size, block_size) type, out_size,
#endif
#if defined(MBEDTLS_MD_CAN_MD5)
const mbedtls_md_info_t mbedtls_md5_info = {
"MD5",
MBEDTLS_MD_MD5,
16,
64,
static const mbedtls_md_info_t mbedtls_md5_info = {
MD_INFO(MBEDTLS_MD_MD5, 16, 64)
};
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
const mbedtls_md_info_t mbedtls_ripemd160_info = {
"RIPEMD160",
MBEDTLS_MD_RIPEMD160,
20,
64,
static const mbedtls_md_info_t mbedtls_ripemd160_info = {
MD_INFO(MBEDTLS_MD_RIPEMD160, 20, 64)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
const mbedtls_md_info_t mbedtls_sha1_info = {
"SHA1",
MBEDTLS_MD_SHA1,
20,
64,
static const mbedtls_md_info_t mbedtls_sha1_info = {
MD_INFO(MBEDTLS_MD_SHA1, 20, 64)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
const mbedtls_md_info_t mbedtls_sha224_info = {
"SHA224",
MBEDTLS_MD_SHA224,
28,
64,
static const mbedtls_md_info_t mbedtls_sha224_info = {
MD_INFO(MBEDTLS_MD_SHA224, 28, 64)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
const mbedtls_md_info_t mbedtls_sha256_info = {
"SHA256",
MBEDTLS_MD_SHA256,
32,
64,
static const mbedtls_md_info_t mbedtls_sha256_info = {
MD_INFO(MBEDTLS_MD_SHA256, 32, 64)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
const mbedtls_md_info_t mbedtls_sha384_info = {
"SHA384",
MBEDTLS_MD_SHA384,
48,
128,
static const mbedtls_md_info_t mbedtls_sha384_info = {
MD_INFO(MBEDTLS_MD_SHA384, 48, 128)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
const mbedtls_md_info_t mbedtls_sha512_info = {
"SHA512",
MBEDTLS_MD_SHA512,
64,
128,
static const mbedtls_md_info_t mbedtls_sha512_info = {
MD_INFO(MBEDTLS_MD_SHA512, 64, 128)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
const mbedtls_md_info_t mbedtls_sha3_224_info = {
"SHA3-224",
MBEDTLS_MD_SHA3_224,
28,
144,
static const mbedtls_md_info_t mbedtls_sha3_224_info = {
MD_INFO(MBEDTLS_MD_SHA3_224, 28, 144)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
const mbedtls_md_info_t mbedtls_sha3_256_info = {
"SHA3-256",
MBEDTLS_MD_SHA3_256,
32,
136,
static const mbedtls_md_info_t mbedtls_sha3_256_info = {
MD_INFO(MBEDTLS_MD_SHA3_256, 32, 136)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
const mbedtls_md_info_t mbedtls_sha3_384_info = {
"SHA3-384",
MBEDTLS_MD_SHA3_384,
48,
104,
static const mbedtls_md_info_t mbedtls_sha3_384_info = {
MD_INFO(MBEDTLS_MD_SHA3_384, 48, 104)
};
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
const mbedtls_md_info_t mbedtls_sha3_512_info = {
"SHA3-512",
MBEDTLS_MD_SHA3_512,
64,
72,
static const mbedtls_md_info_t mbedtls_sha3_512_info = {
MD_INFO(MBEDTLS_MD_SHA3_512, 64, 72)
};
#endif
@ -346,9 +319,8 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx)
#if defined(MBEDTLS_MD_C)
if (ctx->hmac_ctx != NULL) {
mbedtls_platform_zeroize(ctx->hmac_ctx,
mbedtls_zeroize_and_free(ctx->hmac_ctx,
2 * ctx->md_info->block_size);
mbedtls_free(ctx->hmac_ctx);
}
#endif
@ -856,69 +828,77 @@ const int *mbedtls_md_list(void)
return supported_digests;
}
typedef struct {
const char *md_name;
mbedtls_md_type_t md_type;
} md_name_entry;
static const md_name_entry md_names[] = {
#if defined(MBEDTLS_MD_CAN_MD5)
{ "MD5", MBEDTLS_MD_MD5 },
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
{ "RIPEMD160", MBEDTLS_MD_RIPEMD160 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
{ "SHA1", MBEDTLS_MD_SHA1 },
{ "SHA", MBEDTLS_MD_SHA1 }, // compatibility fallback
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
{ "SHA224", MBEDTLS_MD_SHA224 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
{ "SHA256", MBEDTLS_MD_SHA256 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
{ "SHA384", MBEDTLS_MD_SHA384 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
{ "SHA512", MBEDTLS_MD_SHA512 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
{ "SHA3-224", MBEDTLS_MD_SHA3_224 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
{ "SHA3-256", MBEDTLS_MD_SHA3_256 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
{ "SHA3-384", MBEDTLS_MD_SHA3_384 },
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
{ "SHA3-512", MBEDTLS_MD_SHA3_512 },
#endif
{ NULL, MBEDTLS_MD_NONE },
};
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
{
if (NULL == md_name) {
return NULL;
}
/* Get the appropriate digest information */
#if defined(MBEDTLS_MD_CAN_MD5)
if (!strcmp("MD5", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
const md_name_entry *entry = md_names;
while (entry->md_name != NULL &&
strcmp(entry->md_name, md_name) != 0) {
++entry;
}
#endif
#if defined(MBEDTLS_MD_CAN_RIPEMD160)
if (!strcmp("RIPEMD160", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
return mbedtls_md_info_from_type(entry->md_type);
}
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
{
if (md_info == NULL) {
return NULL;
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA1)
if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
const md_name_entry *entry = md_names;
while (entry->md_type != MBEDTLS_MD_NONE &&
entry->md_type != md_info->type) {
++entry;
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA224)
if (!strcmp("SHA224", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA256)
if (!strcmp("SHA256", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA384)
if (!strcmp("SHA384", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
if (!strcmp("SHA512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_224)
if (!strcmp("SHA3-224", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_224);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_256)
if (!strcmp("SHA3-256", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_256);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_384)
if (!strcmp("SHA3-384", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_384);
}
#endif
#if defined(MBEDTLS_MD_CAN_SHA3_512)
if (!strcmp("SHA3-512", md_name)) {
return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_512);
}
#endif
return NULL;
return entry->md_name;
}
const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
@ -1119,15 +1099,6 @@ cleanup:
return ret;
}
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
{
if (md_info == NULL) {
return NULL;
}
return md_info->name;
}
#endif /* MBEDTLS_MD_C */
#endif /* MBEDTLS_MD_LIGHT */

View file

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

View file

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

View file

@ -97,7 +97,7 @@ int mbedtls_pk_error_from_psa(psa_status_t status)
}
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
int mbedtls_pk_error_from_psa_rsa(psa_status_t status)
{
switch (status) {
@ -134,7 +134,7 @@ int mbedtls_pk_error_from_psa_rsa(psa_status_t status)
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
}
}
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY */
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#endif /* MBEDTLS_PSA_CRYPTO_C */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -302,11 +302,16 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
psa_status_t status;
mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
unsigned char *buf = NULL;
buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
if (buf == NULL) {
return MBEDTLS_ERR_PK_ALLOC_FAILED;
}
mbedtls_pk_info_t pk_info = mbedtls_rsa_info;
*sig_len = mbedtls_rsa_get_len(rsa_ctx);
if (sig_size < *sig_len) {
mbedtls_free(buf);
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
}
@ -314,8 +319,9 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
* re-construct one to make it happy */
key.pk_info = &pk_info;
key.pk_ctx = rsa_ctx;
key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
if (key_len <= 0) {
mbedtls_free(buf);
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
@ -323,7 +329,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
status = psa_import_key(&attributes,
buf + sizeof(buf) - key_len, key_len,
buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES - key_len, key_len,
&key_id);
if (status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
@ -339,6 +345,7 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg,
ret = 0;
cleanup:
mbedtls_free(buf);
status = psa_destroy_key(key_id);
if (ret == 0 && status != PSA_SUCCESS) {
ret = PSA_PK_TO_MBEDTLS_ERR(status);
@ -1637,8 +1644,7 @@ static void *rsa_alt_alloc_wrap(void)
static void rsa_alt_free_wrap(void *ctx)
{
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_rsa_alt_context));
mbedtls_free(ctx);
mbedtls_zeroize_and_free(ctx, sizeof(mbedtls_rsa_alt_context));
}
const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
@ -1725,7 +1731,7 @@ static int rsa_opaque_can_do(mbedtls_pk_type_t type)
type == MBEDTLS_PK_RSASSA_PSS;
}
#if defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
static int rsa_opaque_decrypt(mbedtls_pk_context *pk,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
@ -1747,7 +1753,7 @@ static int rsa_opaque_decrypt(mbedtls_pk_context *pk,
return 0;
}
#endif /* MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
static int rsa_opaque_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@ -1817,11 +1823,11 @@ const mbedtls_pk_info_t mbedtls_rsa_opaque_info = {
.rs_alloc_func = NULL,
.rs_free_func = NULL,
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#if defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
.decrypt_func = rsa_opaque_decrypt,
#else /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
#else /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
.decrypt_func = NULL,
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
.encrypt_func = NULL,
.check_pair_func = NULL,
.ctx_alloc_func = NULL,

View file

@ -150,9 +150,9 @@ int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_ecdsa(psa_status_t status);
int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa(psa_status_t status);
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_rsa(psa_status_t status);
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY */
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_RSA_C)

View file

@ -34,9 +34,6 @@
#include "mbedtls/rsa.h"
#endif
#include "mbedtls/ecp.h"
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
#include "pkwrite.h"
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#include "pk_internal.h"
#endif
@ -107,8 +104,7 @@ int mbedtls_pk_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);
mbedtls_free(*buf);
mbedtls_zeroize_and_free(*buf, *n);
return MBEDTLS_ERR_PK_FILE_IO_ERROR;
}
@ -146,8 +142,7 @@ int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
(const unsigned char *) pwd, strlen(pwd), f_rng, p_rng);
}
mbedtls_platform_zeroize(buf, n);
mbedtls_free(buf);
mbedtls_zeroize_and_free(buf, n);
return ret;
}
@ -167,8 +162,7 @@ int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path)
ret = mbedtls_pk_parse_public_key(ctx, buf, n);
mbedtls_platform_zeroize(buf, n);
mbedtls_free(buf);
mbedtls_zeroize_and_free(buf, n);
return ret;
}
@ -1686,8 +1680,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk,
ret = pk_parse_key_pkcs8_encrypted_der(pk, key_copy, keylen,
pwd, pwdlen, f_rng, p_rng);
mbedtls_platform_zeroize(key_copy, keylen);
mbedtls_free(key_copy);
mbedtls_zeroize_and_free(key_copy, keylen);
}
if (ret == 0) {

View file

@ -165,7 +165,7 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *pk)
{
size_t len = 0;
uint8_t buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {

View file

@ -27,6 +27,10 @@
#include "mbedtls/pk.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
* Max sizes of key per types. Shown as tag + len (+ content).
*/
@ -74,6 +78,19 @@
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/* Find the maximum number of bytes necessary to store an EC point. When USE_PSA
* is defined this means looking for the maximum between PSA and built-in
* supported curves. */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#define MBEDTLS_PK_MAX_ECC_BYTES (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
MBEDTLS_ECP_MAX_BYTES ? \
PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) : \
MBEDTLS_ECP_MAX_BYTES)
#else /* MBEDTLS_USE_PSA_CRYPTO */
#define MBEDTLS_PK_MAX_ECC_BYTES MBEDTLS_ECP_MAX_BYTES
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
* EC public keys:
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
@ -85,7 +102,7 @@
* + 2 * ECP_MAX (coords) [1]
* }
*/
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_PK_MAX_ECC_BYTES)
/*
* EC private keys:
@ -96,7 +113,7 @@
* publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
* }
*/
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_ECP_MAX_BYTES)
#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_PK_MAX_ECC_BYTES)
#else /* MBEDTLS_PK_HAVE_ECC_KEYS */

View file

@ -130,6 +130,15 @@ void mbedtls_platform_zeroize(void *buf, size_t len)
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
void mbedtls_zeroize_and_free(void *buf, size_t len)
{
if (buf != NULL) {
mbedtls_platform_zeroize(buf, len);
}
mbedtls_free(buf);
}
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
#include <time.h>
#if !defined(_WIN32) && (defined(unix) || \

View file

@ -72,7 +72,6 @@
#include "mbedtls/gcm.h"
#include "mbedtls/md5.h"
#include "mbedtls/md.h"
#include "md_wrap.h"
#include "mbedtls/pk.h"
#include "pk_wrap.h"
#include "mbedtls/platform_util.h"
@ -127,9 +126,9 @@ int psa_can_do_hash(psa_algorithm_t hash_alg)
(void) hash_alg;
return global_data.drivers_initialized;
}
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
static int psa_is_dh_key_size_valid(size_t bits)
{
if (bits != 2048 && bits != 3072 && bits != 4096 &&
@ -139,9 +138,9 @@ static int psa_is_dh_key_size_valid(size_t bits)
return 1;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY ||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY */
PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
psa_status_t mbedtls_to_psa_error(int ret)
{
@ -687,7 +686,7 @@ psa_status_t psa_import_key_into_slot(
return PSA_SUCCESS;
} else if (PSA_KEY_TYPE_IS_ASYMMETRIC(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
if (PSA_KEY_TYPE_IS_DH(type)) {
if (psa_is_dh_key_size_valid(PSA_BYTES_TO_BITS(data_length)) == 0) {
@ -699,7 +698,7 @@ psa_status_t psa_import_key_into_slot(
key_buffer_length,
bits);
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) ||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
@ -712,7 +711,8 @@ psa_status_t psa_import_key_into_slot(
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if (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_PUBLIC_KEY)
if (PSA_KEY_TYPE_IS_RSA(type)) {
return mbedtls_psa_rsa_import_key(attributes,
@ -721,7 +721,8 @@ psa_status_t psa_import_key_into_slot(
key_buffer_length,
bits);
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* (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_PUBLIC_KEY) */
}
@ -1088,13 +1089,10 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
{
/* Data pointer will always be either a valid pointer or NULL in an
* initialized slot, so we can just free it. */
if (slot->key.data != NULL) {
mbedtls_platform_zeroize(slot->key.data, slot->key.bytes);
mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes);
}
mbedtls_free(slot->key.data);
slot->key.data = NULL;
slot->key.bytes = 0;
@ -1249,7 +1247,7 @@ exit:
return overall_status;
}
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
static psa_status_t psa_get_rsa_public_exponent(
const mbedtls_rsa_context *rsa,
@ -1291,7 +1289,7 @@ exit:
}
return mbedtls_to_psa_error(ret);
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
/** Retrieve all the publicly-accessible attributes of a key.
@ -1322,7 +1320,8 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
switch (slot->attr.type) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if (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_PUBLIC_KEY)
case PSA_KEY_TYPE_RSA_KEY_PAIR:
case PSA_KEY_TYPE_RSA_PUBLIC_KEY:
@ -1348,7 +1347,8 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
mbedtls_free(rsa);
}
break;
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* (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_PUBLIC_KEY) */
default:
/* Nothing else to do. */
@ -1478,7 +1478,7 @@ psa_status_t psa_export_public_key_internal(
key_buffer, key_buffer_size,
data, data_size, data_length);
} else if (PSA_KEY_TYPE_IS_RSA(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
return mbedtls_psa_rsa_export_public_key(attributes,
key_buffer,
@ -1489,7 +1489,7 @@ psa_status_t psa_export_public_key_internal(
#else
/* We don't know how to convert a private RSA key to public. */
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
} else if (PSA_KEY_TYPE_IS_ECC(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
@ -1506,7 +1506,7 @@ psa_status_t psa_export_public_key_internal(
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
} else if (PSA_KEY_TYPE_IS_DH(type)) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
return mbedtls_psa_ffdh_export_public_key(attributes,
key_buffer,
@ -1515,7 +1515,7 @@ psa_status_t psa_export_public_key_internal(
data_length);
#else
return PSA_ERROR_NOT_SUPPORTED;
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) ||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) */
} else {
(void) key_buffer;
@ -1955,7 +1955,8 @@ static psa_status_t psa_validate_optional_attributes(
}
if (attributes->domain_parameters_size != 0) {
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if (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_PUBLIC_KEY)
if (PSA_KEY_TYPE_IS_RSA(slot->attr.type)) {
mbedtls_rsa_context *rsa = NULL;
@ -1996,7 +1997,8 @@ rsa_exit:
return mbedtls_to_psa_error(ret);
}
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* (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_PUBLIC_KEY) */
{
return PSA_ERROR_INVALID_ARGUMENT;
@ -5091,7 +5093,7 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
defined(PSA_HAVE_SOFT_PBKDF2)
#define AT_LEAST_ONE_BUILTIN_KDF
#endif /* At least one builtin KDF */
@ -5159,27 +5161,23 @@ psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
/* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
if (operation->ctx.tls12_prf.secret != NULL) {
mbedtls_platform_zeroize(operation->ctx.tls12_prf.secret,
mbedtls_zeroize_and_free(operation->ctx.tls12_prf.secret,
operation->ctx.tls12_prf.secret_length);
mbedtls_free(operation->ctx.tls12_prf.secret);
}
if (operation->ctx.tls12_prf.seed != NULL) {
mbedtls_platform_zeroize(operation->ctx.tls12_prf.seed,
mbedtls_zeroize_and_free(operation->ctx.tls12_prf.seed,
operation->ctx.tls12_prf.seed_length);
mbedtls_free(operation->ctx.tls12_prf.seed);
}
if (operation->ctx.tls12_prf.label != NULL) {
mbedtls_platform_zeroize(operation->ctx.tls12_prf.label,
mbedtls_zeroize_and_free(operation->ctx.tls12_prf.label,
operation->ctx.tls12_prf.label_length);
mbedtls_free(operation->ctx.tls12_prf.label);
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
if (operation->ctx.tls12_prf.other_secret != NULL) {
mbedtls_platform_zeroize(operation->ctx.tls12_prf.other_secret,
mbedtls_zeroize_and_free(operation->ctx.tls12_prf.other_secret,
operation->ctx.tls12_prf.other_secret_length);
mbedtls_free(operation->ctx.tls12_prf.other_secret);
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
status = PSA_SUCCESS;
@ -5195,17 +5193,16 @@ psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
sizeof(operation->ctx.tls12_ecjpake_to_pms.data));
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
#if defined(PSA_HAVE_SOFT_PBKDF2)
if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
if (operation->ctx.pbkdf2.salt != NULL) {
mbedtls_platform_zeroize(operation->ctx.pbkdf2.salt,
mbedtls_zeroize_and_free(operation->ctx.pbkdf2.salt,
operation->ctx.pbkdf2.salt_length);
mbedtls_free(operation->ctx.pbkdf2.salt);
}
status = PSA_SUCCESS;
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC) */
#endif /* defined(PSA_HAVE_SOFT_PBKDF2) */
{
status = PSA_ERROR_BAD_STATE;
}
@ -5532,7 +5529,7 @@ static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read(
}
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#if defined(PSA_HAVE_SOFT_PBKDF2)
static psa_status_t psa_key_derivation_pbkdf2_generate_block(
psa_pbkdf2_key_derivation_t *pbkdf2,
psa_algorithm_t prf_alg,
@ -5581,11 +5578,14 @@ static psa_status_t psa_key_derivation_pbkdf2_generate_block(
memcpy(U_accumulator, U_i, prf_output_length);
for (i = 1; i < pbkdf2->input_cost; i++) {
/* We are passing prf_output_length as mac_size because the driver
* function directly sets mac_output_length as mac_size upon success.
* See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
status = psa_driver_wrapper_mac_compute(attributes,
pbkdf2->password,
pbkdf2->password_length,
prf_alg, U_i, prf_output_length,
U_i, sizeof(U_i),
U_i, prf_output_length,
&mac_output_length);
if (status != PSA_SUCCESS) {
goto cleanup;
@ -5617,6 +5617,10 @@ static psa_status_t psa_key_derivation_pbkdf2_read(
prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg));
prf_output_length = PSA_HASH_LENGTH(prf_alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
} else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
prf_alg = PSA_ALG_CMAC;
prf_output_length = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
@ -5661,7 +5665,7 @@ static psa_status_t psa_key_derivation_pbkdf2_read(
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
psa_status_t psa_key_derivation_output_bytes(
psa_key_derivation_operation_t *operation,
@ -5716,12 +5720,12 @@ psa_status_t psa_key_derivation_output_bytes(
&operation->ctx.tls12_ecjpake_to_pms, output, output_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
#if defined(PSA_HAVE_SOFT_PBKDF2)
if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
status = psa_key_derivation_pbkdf2_read(&operation->ctx.pbkdf2, kdf_alg,
output, output_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
{
(void) kdf_alg;
@ -6147,6 +6151,11 @@ static int is_kdf_alg_supported(psa_algorithm_t kdf_alg)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
return 1;
}
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
return 1;
}
#endif
return 0;
}
@ -6173,10 +6182,14 @@ static psa_status_t psa_key_derivation_setup_kdf(
}
/* All currently supported key derivation algorithms (apart from
* ecjpake to pms) are based on a hash algorithm. */
* ecjpake to pms and pbkdf2_aes_cmac_128) are based on a hash algorithm. */
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
if (kdf_alg != PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
if (kdf_alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
hash_size = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
} else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
hash_size = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
} else {
if (hash_size == 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
@ -6188,8 +6201,6 @@ static psa_status_t psa_key_derivation_setup_kdf(
if (status != PSA_SUCCESS) {
return status;
}
} else {
hash_size = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
}
if ((PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
@ -6563,8 +6574,7 @@ static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
status = psa_tls12_prf_set_key(prf, pms, cur - pms);
mbedtls_platform_zeroize(pms, pms_len);
mbedtls_free(pms);
mbedtls_zeroize_and_free(pms, pms_len);
return status;
}
@ -6642,7 +6652,7 @@ static psa_status_t psa_tls12_ecjpake_to_pms_input(
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
#if defined(PSA_HAVE_SOFT_PBKDF2)
static psa_status_t psa_pbkdf2_set_input_cost(
psa_pbkdf2_key_derivation_t *pbkdf2,
psa_key_derivation_step_t step,
@ -6709,6 +6719,7 @@ static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2,
return PSA_SUCCESS;
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
const uint8_t *input,
size_t input_len,
@ -6725,6 +6736,39 @@ static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
}
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
static psa_status_t psa_pbkdf2_cmac_set_password(const uint8_t *input,
size_t input_len,
uint8_t *output,
size_t *output_len)
{
psa_status_t status = PSA_SUCCESS;
if (input_len != PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC)) {
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t zeros[16] = { 0 };
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(zeros)));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
/* Passing PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC) as
* mac_size as the driver function sets mac_output_length = mac_size
* on success. See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
status = psa_driver_wrapper_mac_compute(&attributes,
zeros, sizeof(zeros),
PSA_ALG_CMAC, input, input_len,
output,
PSA_MAC_LENGTH(PSA_KEY_TYPE_AES,
128U,
PSA_ALG_CMAC),
output_len);
} else {
memcpy(output, input, input_len);
*output_len = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
}
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */
static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
psa_algorithm_t kdf_alg,
@ -6736,13 +6780,23 @@ static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
return PSA_ERROR_BAD_STATE;
}
if (data_length != 0) {
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
pbkdf2->password,
&pbkdf2->password_length);
}
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
pbkdf2->password,
&pbkdf2->password_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
status = psa_pbkdf2_cmac_set_password(data, data_length,
pbkdf2->password,
&pbkdf2->password_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */
{
return PSA_ERROR_INVALID_ARGUMENT;
}
pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET;
@ -6765,7 +6819,7 @@ static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2,
return PSA_ERROR_INVALID_ARGUMENT;
}
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
/** Check whether the given key type is acceptable for the given
* input step of a key derivation.
@ -6862,12 +6916,12 @@ static psa_status_t psa_key_derivation_input_internal(
&operation->ctx.tls12_ecjpake_to_pms, step, data, data_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
#if defined(PSA_HAVE_SOFT_PBKDF2)
if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
status = psa_pbkdf2_input(&operation->ctx.pbkdf2, kdf_alg,
step, data, data_length);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
{
/* This can't happen unless the operation object was not initialized */
(void) data;
@ -6891,12 +6945,12 @@ static psa_status_t psa_key_derivation_input_integer_internal(
psa_status_t status;
psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation);
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
#if defined(PSA_HAVE_SOFT_PBKDF2)
if (PSA_ALG_IS_PBKDF2(kdf_alg)) {
status = psa_pbkdf2_set_input_cost(
&operation->ctx.pbkdf2, step, value);
} else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_HAVE_SOFT_PBKDF2 */
{
(void) step;
(void) value;
@ -7365,11 +7419,14 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation(
return status;
}
} else
#if defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
if (PSA_KEY_TYPE_IS_RSA(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (bits < PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS) {
return PSA_ERROR_NOT_SUPPORTED;
}
/* Accept only byte-aligned keys, for the same reasons as
* in psa_import_rsa_key(). */
@ -7377,7 +7434,7 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation(
return PSA_ERROR_NOT_SUPPORTED;
}
} else
#endif /* defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY) */
#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
@ -7386,13 +7443,13 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation(
} else
#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */
#if defined(MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY)
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
if (psa_is_dh_key_size_valid(bits) == 0) {
return PSA_ERROR_NOT_SUPPORTED;
}
} else
#endif /* defined(MBEDTLS_PSA_WANT_KEY_TYPE_DH_KEY_PAIR_LEGACY) */
#endif /* defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) */
{
return PSA_ERROR_NOT_SUPPORTED;
}
@ -7425,16 +7482,14 @@ psa_status_t psa_generate_key_internal(
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */
} else
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) && \
defined(MBEDTLS_GENPRIME)
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
return mbedtls_psa_rsa_generate_key(attributes,
key_buffer,
key_buffer_size,
key_buffer_length);
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
* defined(MBEDTLS_GENPRIME) */
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
if (PSA_KEY_TYPE_IS_ECC(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
@ -7445,14 +7500,14 @@ psa_status_t psa_generate_key_internal(
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY)
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
if (PSA_KEY_TYPE_IS_DH(type) && PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
return mbedtls_psa_ffdh_generate_key(attributes,
key_buffer,
key_buffer_size,
key_buffer_length);
} else
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) */
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) */
{
(void) key_buffer_length;
return PSA_ERROR_NOT_SUPPORTED;
@ -7648,6 +7703,7 @@ exit:
return status;
}
#if defined(PSA_WANT_ALG_SOME_PAKE)
psa_status_t psa_crypto_driver_pake_get_password_len(
const psa_crypto_driver_pake_inputs_t *inputs,
size_t *password_len)
@ -7754,7 +7810,6 @@ psa_status_t psa_crypto_driver_pake_get_cipher_suite(
return PSA_SUCCESS;
}
#if defined(PSA_WANT_ALG_SOME_PAKE)
psa_status_t psa_pake_setup(
psa_pake_operation_t *operation,
const psa_pake_cipher_suite_t *cipher_suite)
@ -7981,7 +8036,7 @@ static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_s
} else {
return PSA_JPAKE_STEP_INVALID;
}
return key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE;
return (psa_crypto_driver_pake_step_t) (key_share_step + stage->step - PSA_PAKE_STEP_KEY_SHARE);
}
#endif /* PSA_WANT_ALG_JPAKE */
@ -8009,8 +8064,7 @@ static psa_status_t psa_pake_complete_inputs(
status = psa_driver_wrapper_pake_setup(operation, &inputs);
/* Driver is responsible for creating its own copy of the password. */
mbedtls_platform_zeroize(inputs.password, inputs.password_len);
mbedtls_free(inputs.password);
mbedtls_zeroize_and_free(inputs.password, inputs.password_len);
/* User and peer are translated to role. */
mbedtls_free(inputs.user);
@ -8311,9 +8365,8 @@ psa_status_t psa_pake_abort(
if (operation->stage == PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
if (operation->data.inputs.password != NULL) {
mbedtls_platform_zeroize(operation->data.inputs.password,
mbedtls_zeroize_and_free(operation->data.inputs.password,
operation->data.inputs.password_len);
mbedtls_free(operation->data.inputs.password);
}
if (operation->data.inputs.user != NULL) {
mbedtls_free(operation->data.inputs.user);

View file

@ -29,7 +29,8 @@
#include "mbedtls/platform.h"
#include "mbedtls/error.h"
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
@ -118,11 +119,12 @@ cleanup:
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY ||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
MBEDTLS_PSA_BUILTIN_ALG_FFDH */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY) || \
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
psa_status_t mbedtls_psa_ffdh_export_public_key(
const psa_key_attributes_t *attributes,
@ -178,7 +180,10 @@ cleanup:
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
psa_status_t mbedtls_psa_ffdh_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
@ -212,7 +217,9 @@ cleanup:
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT)
psa_status_t mbedtls_psa_ffdh_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data, size_t data_length,
@ -230,9 +237,7 @@ psa_status_t mbedtls_psa_ffdh_import_key(
return PSA_SUCCESS;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_LEGACY ||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
psa_status_t mbedtls_psa_ffdh_key_agreement(

View file

@ -23,8 +23,6 @@
#include <psa/crypto.h>
#include "md_wrap.h"
/** Calculate the hash (digest) of a message using Mbed TLS routines.
*
* \note The signature of this function is that of a PSA driver hash_compute

View file

@ -559,8 +559,7 @@ psa_status_t mbedtls_psa_pake_get_implicit_key(
psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
{
mbedtls_platform_zeroize(operation->password, operation->password_len);
mbedtls_free(operation->password);
mbedtls_zeroize_and_free(operation->password, operation->password_len);
operation->password = NULL;
operation->password_len = 0;

View file

@ -43,7 +43,8 @@
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
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_PUBLIC_KEY)
/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
@ -123,12 +124,13 @@ exit:
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
* 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_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) || \
#if (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_PUBLIC_KEY)
psa_status_t mbedtls_psa_rsa_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data, size_t data_length,
@ -165,7 +167,12 @@ exit:
return status;
}
#endif /* (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_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
mbedtls_rsa_context *rsa,
uint8_t *data,
@ -235,11 +242,10 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
return status;
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) ||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY) && \
defined(MBEDTLS_GENPRIME)
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
static psa_status_t psa_rsa_read_exponent(const uint8_t *domain_parameters,
size_t domain_parameters_size,
int *exponent)
@ -301,8 +307,7 @@ psa_status_t mbedtls_psa_rsa_generate_key(
return status;
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
* defined(MBEDTLS_GENPRIME) */
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
/****************************************************************/
/* Sign/verify hashes */

View file

@ -354,18 +354,14 @@ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
status = psa_crypto_storage_store(attr->id,
storage_data, storage_data_length);
mbedtls_platform_zeroize(storage_data, storage_data_length);
mbedtls_free(storage_data);
mbedtls_zeroize_and_free(storage_data, storage_data_length);
return status;
}
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
{
if (key_data != NULL) {
mbedtls_platform_zeroize(key_data, key_data_length);
}
mbedtls_free(key_data);
mbedtls_zeroize_and_free(key_data, key_data_length);
}
psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
@ -403,8 +399,7 @@ psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
}
exit:
mbedtls_platform_zeroize(loaded_data, storage_data_length);
mbedtls_free(loaded_data);
mbedtls_zeroize_and_free(loaded_data, storage_data_length);
return status;
}

View file

@ -40,7 +40,7 @@
#include <mbedtls/ssl.h>
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
#include <mbedtls/rsa.h>
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
@ -85,7 +85,7 @@ const mbedtls_error_pair_t psa_to_ssl_errors[] =
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
{
{ PSA_SUCCESS, 0 },

View file

@ -73,7 +73,7 @@ extern const mbedtls_error_pair_t psa_to_ssl_errors[7];
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_LEGACY)
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
extern const mbedtls_error_pair_t psa_to_pk_rsa_errors[8];
#endif

View file

@ -56,6 +56,164 @@
#include "mbedtls/platform.h"
#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.
*/
static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
size_t ilen,
unsigned char *output,
size_t output_max_len,
size_t *olen)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, plaintext_max_size;
/* The following variables take sensitive values: their value must
* not leak into the observable behavior of the function other than
* the designated outputs (output, olen, return value). Otherwise
* this would open the execution of the function to
* side-channel-based variants of the Bleichenbacher padding oracle
* attack. Potential side channels include overall timing, memory
* access patterns (especially visible to an adversary who has access
* to a shared memory cache), and branches (especially visible to
* an adversary who has access to a shared code cache or to a shared
* branch predictor). */
size_t pad_count = 0;
mbedtls_ct_condition_t bad;
mbedtls_ct_condition_t pad_done;
size_t plaintext_size = 0;
mbedtls_ct_condition_t output_too_large;
plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11
: output_max_len;
/* Check and get padding length in constant time and constant
* memory trace. The first byte must be 0. */
bad = mbedtls_ct_bool(input[0]);
/* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
* where PS must be at least 8 nonzero bytes. */
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(input[1], MBEDTLS_RSA_CRYPT));
/* Read the whole buffer. Set pad_done to nonzero if we find
* the 0x00 byte and remember the padding length in pad_count. */
pad_done = MBEDTLS_CT_FALSE;
for (i = 2; i < ilen; i++) {
mbedtls_ct_condition_t found = mbedtls_ct_uint_eq(input[i], 0);
pad_done = mbedtls_ct_bool_or(pad_done, found);
pad_count += mbedtls_ct_uint_if_else_0(mbedtls_ct_bool_not(pad_done), 1);
}
/* If pad_done is still zero, there's no data, only unfinished padding. */
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_not(pad_done));
/* There must be at least 8 bytes of padding. */
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_gt(8, pad_count));
/* If the padding is valid, set plaintext_size to the number of
* remaining bytes after stripping the padding. If the padding
* is invalid, avoid leaking this fact through the size of the
* output: use the maximum message size that fits in the output
* buffer. Do it without branches to avoid leaking the padding
* validity through timing. RSA keys are small enough that all the
* size_t values involved fit in unsigned int. */
plaintext_size = mbedtls_ct_uint_if(
bad, (unsigned) plaintext_max_size,
(unsigned) (ilen - pad_count - 3));
/* Set output_too_large to 0 if the plaintext fits in the output
* buffer and to 1 otherwise. */
output_too_large = mbedtls_ct_uint_gt(plaintext_size,
plaintext_max_size);
/* Set ret without branches to avoid timing attacks. Return:
* - INVALID_PADDING if the padding is bad (bad != 0).
* - OUTPUT_TOO_LARGE if the padding is good but the decrypted
* plaintext does not fit in the output buffer.
* - 0 if the padding is correct. */
ret = -(int) mbedtls_ct_uint_if(
bad,
(unsigned) (-(MBEDTLS_ERR_RSA_INVALID_PADDING)),
mbedtls_ct_uint_if_else_0(
output_too_large,
(unsigned) (-(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE)))
);
/* If the padding is bad or the plaintext is too large, zero the
* data that we're about to copy to the output buffer.
* We need to copy the same amount of data
* from the same buffer whether the padding is good or not to
* avoid leaking the padding validity through overall timing or
* through memory or cache access patterns. */
mbedtls_ct_zeroize_if(mbedtls_ct_bool_or(bad, output_too_large), input + 11, ilen - 11);
/* If the plaintext is too large, truncate it to the buffer size.
* Copy anyway to avoid revealing the length through timing, because
* revealing the length is as bad as revealing the padding validity
* for a Bleichenbacher attack. */
plaintext_size = mbedtls_ct_uint_if(output_too_large,
(unsigned) plaintext_max_size,
(unsigned) plaintext_size);
/* Move the plaintext to the leftmost position where it can start in
* the working buffer, i.e. make it start plaintext_max_size from
* the end of the buffer. Do this with a memory access trace that
* does not depend on the plaintext size. After this move, the
* starting location of the plaintext is no longer sensitive
* information. */
mbedtls_ct_memmove_left(input + ilen - plaintext_max_size,
plaintext_max_size,
plaintext_max_size - plaintext_size);
/* Finally copy the decrypted plaintext plus trailing zeros into the output
* buffer. If output_max_len is 0, then output may be an invalid pointer
* and the result of memcpy() would be undefined; prevent undefined
* behavior making sure to depend only on output_max_len (the size of the
* user-provided output buffer), which is independent from plaintext
* length, validity of padding, success of the decryption, and other
* secrets. */
if (output_max_len != 0) {
memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size);
}
/* Report the amount of data we copied to the output buffer. In case
* of errors (bad padding or output too large), the value of *olen
* when this function returns is not specified. Making it equivalent
* to the good case limits the risks of leaking the padding validity. */
*olen = plaintext_size;
return ret;
}
#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
#if !defined(MBEDTLS_RSA_ALT)
int mbedtls_rsa_import(mbedtls_rsa_context *ctx,
@ -545,7 +703,12 @@ int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
mbedtls_mpi_init(&G);
mbedtls_mpi_init(&L);
if (nbits < 128 || exponent < 3 || nbits % 2 != 0) {
if (exponent < 3 || nbits % 2 != 0) {
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
if (nbits < MBEDTLS_RSA_GEN_KEY_MIN_BITS) {
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
goto cleanup;
}
@ -1266,13 +1429,13 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
/* maskedDB: Apply dbMask to DB */
if ((ret = mgf_mask(output + hlen + 1, olen - hlen - 1, output + 1, hlen,
ctx->hash_id)) != 0) {
(mbedtls_md_type_t) ctx->hash_id)) != 0) {
return ret;
}
/* maskedSeed: Apply seedMask to seed */
if ((ret = mgf_mask(output + 1, hlen, output + hlen + 1, olen - hlen - 1,
ctx->hash_id)) != 0) {
(mbedtls_md_type_t) ctx->hash_id)) != 0) {
return ret;
}
@ -1420,10 +1583,10 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
*/
/* seed: Apply seedMask to maskedSeed */
if ((ret = mgf_mask(buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
ctx->hash_id)) != 0 ||
(mbedtls_md_type_t) ctx->hash_id)) != 0 ||
/* DB: Apply dbMask to maskedDB */
(ret = mgf_mask(buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
ctx->hash_id)) != 0) {
(mbedtls_md_type_t) ctx->hash_id)) != 0) {
goto cleanup;
}
@ -1649,7 +1812,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
p += slen;
/* Generate H = Hash( M' ) */
ret = hash_mprime(hash, hashlen, salt, slen, p, ctx->hash_id);
ret = hash_mprime(hash, hashlen, salt, slen, p, (mbedtls_md_type_t) ctx->hash_id);
if (ret != 0) {
return ret;
}
@ -1661,7 +1824,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
/* maskedDB: Apply dbMask to DB */
ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen,
ctx->hash_id);
(mbedtls_md_type_t) ctx->hash_id);
if (ret != 0) {
return ret;
}
@ -1905,10 +2068,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
memcpy(sig, sig_try, ctx->len);
cleanup:
mbedtls_platform_zeroize(sig_try, ctx->len);
mbedtls_platform_zeroize(verif, ctx->len);
mbedtls_free(sig_try);
mbedtls_free(verif);
mbedtls_zeroize_and_free(sig_try, ctx->len);
mbedtls_zeroize_and_free(verif, ctx->len);
if (ret != 0) {
memset(sig, '!', ctx->len);
@ -2152,13 +2313,11 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx,
cleanup:
if (encoded != NULL) {
mbedtls_platform_zeroize(encoded, sig_len);
mbedtls_free(encoded);
mbedtls_zeroize_and_free(encoded, sig_len);
}
if (encoded_expected != NULL) {
mbedtls_platform_zeroize(encoded_expected, sig_len);
mbedtls_free(encoded_expected);
mbedtls_zeroize_and_free(encoded_expected, sig_len);
}
return ret;

View file

@ -131,8 +131,7 @@ static void ssl_cache_entry_zeroize(mbedtls_ssl_cache_entry *entry)
/* zeroize and free session structure */
if (entry->session != NULL) {
mbedtls_platform_zeroize(entry->session, entry->session_len);
mbedtls_free(entry->session);
mbedtls_zeroize_and_free(entry->session, entry->session_len);
}
/* zeroize the whole entry structure */
@ -324,8 +323,7 @@ exit:
#endif
if (session_serialized != NULL) {
mbedtls_platform_zeroize(session_serialized, session_serialized_len);
mbedtls_free(session_serialized);
mbedtls_zeroize_and_free(session_serialized, session_serialized_len);
session_serialized = NULL;
}

View file

@ -1931,7 +1931,7 @@ size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersui
return key_bits;
#else
const mbedtls_cipher_info_t * const cipher_info =
mbedtls_cipher_info_from_type(info->cipher);
mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) info->cipher);
return mbedtls_cipher_info_get_key_bitlen(cipher_info);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
@ -2021,7 +2021,8 @@ mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersu
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info)
{
@ -2038,7 +2039,8 @@ int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info)
return 0;
}
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
* MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info)

View file

@ -374,7 +374,8 @@ static int ssl_write_client_hello_cipher_suites(
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
(defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
(defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED))
*tls12_uses_ec |= mbedtls_ssl_ciphersuite_uses_ec(ciphersuite_info);
#endif

View file

@ -753,32 +753,20 @@ struct mbedtls_ssl_handshake_params {
mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_USE_PSA_CRYPTO)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
#endif /* MBEDTLS_ECDH_C && !MBEDTLS_USE_PSA_CRYPTO */
#endif /* !MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */
#if defined(PSA_WANT_ALG_ECDH) && defined(PSA_WANT_ALG_FFDH)
#if (MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH >= MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH)
#define SSL_XXDH_PSA_PEERKEY_SIZE MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH
#else
#define SSL_XXDH_PSA_PEERKEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#endif
#elif defined(PSA_WANT_ALG_ECDH)
#define SSL_XXDH_PSA_PEERKEY_SIZE MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#else
#define SSL_XXDH_PSA_PEERKEY_SIZE MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH
#endif
#if (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED)
psa_key_type_t xxdh_psa_type;
size_t xxdh_bits;
size_t xxdh_psa_bits;
mbedtls_svc_key_id_t xxdh_psa_privkey;
uint8_t xxdh_psa_privkey_is_external;
unsigned char xxdh_psa_peerkey[SSL_XXDH_PSA_PEERKEY_SIZE];
unsigned char xxdh_psa_peerkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
size_t xxdh_psa_peerkey_len;
#endif /* (PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH) &&
(MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3) */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -794,7 +782,8 @@ struct mbedtls_ssl_handshake_params {
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_PK_CAN_ECDH) || defined(MBEDTLS_PK_CAN_ECDSA_SOME) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) || \
defined(MBEDTLS_PK_CAN_ECDSA_SOME) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
uint16_t *curves_tls_id; /*!< List of TLS IDs of supported elliptic curves */
#endif
@ -2807,4 +2796,64 @@ static inline void mbedtls_ssl_session_clear_ticket_flags(
int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl);
#endif
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
/** 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.
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
psa_algorithm_t mac_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 /* defined(MBEDTLS_USE_PSA_CRYPTO) */
#endif /* MBEDTLS_TEST_HOOKS && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) */
#endif /* ssl_misc.h */

View file

@ -60,6 +60,234 @@ static int local_err_translation(psa_status_t status)
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
#endif
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_SHA_384)
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384)
#elif defined(PSA_WANT_ALG_SHA_256)
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)
#else /* See check_config.h */
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1)
#endif
MBEDTLS_STATIC_TESTABLE
int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
psa_algorithm_t mac_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)
{
/*
* This function breaks the HMAC abstraction and uses psa_hash_clone()
* extension in order to get constant-flow behaviour.
*
* HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
* concatenation, and okey/ikey are the XOR of the key with some fixed bit
* patterns (see RFC 2104, sec. 2).
*
* We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
* hashing up to minlen, then cloning the context, and for each byte up
* to maxlen finishing up the hash computation, keeping only the
* correct result.
*
* Then we only need to compute HASH(okey + inner_hash) and we're done.
*/
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
size_t hash_length;
unsigned char aux_out[PSA_HASH_MAX_SIZE];
psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
size_t offset;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t mac_key_length;
size_t i;
#define PSA_CHK(func_call) \
do { \
status = (func_call); \
if (status != PSA_SUCCESS) \
goto cleanup; \
} while (0)
/* Export MAC key
* We assume key length is always exactly the output size
* which is never more than the block size, thus we use block_size
* as the key buffer size.
*/
PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
/* Calculate ikey */
for (i = 0; i < mac_key_length; i++) {
key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
}
for (; i < block_size; ++i) {
key_buf[i] = 0x36;
}
PSA_CHK(psa_hash_setup(&operation, hash_alg));
/* Now compute inner_hash = HASH(ikey + msg) */
PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
PSA_CHK(psa_hash_update(&operation, data, min_data_len));
/* Fill the hash buffer in advance with something that is
* not a valid hash (barring an attack on the hash and
* deliberately-crafted input), in case the caller doesn't
* check the return status properly. */
memset(output, '!', hash_size);
/* For each possible length, compute the hash up to that point */
for (offset = min_data_len; offset <= max_data_len; offset++) {
PSA_CHK(psa_hash_clone(&operation, &aux_operation));
PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
PSA_HASH_MAX_SIZE, &hash_length));
/* Keep only the correct inner_hash in the output buffer */
mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
output, aux_out, NULL, hash_size);
if (offset < max_data_len) {
PSA_CHK(psa_hash_update(&operation, data + offset, 1));
}
}
/* Abort current operation to prepare for final operation */
PSA_CHK(psa_hash_abort(&operation));
/* Calculate okey */
for (i = 0; i < mac_key_length; i++) {
key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
}
for (; i < block_size; ++i) {
key_buf[i] = 0x5C;
}
/* Now compute HASH(okey + inner_hash) */
PSA_CHK(psa_hash_setup(&operation, hash_alg));
PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
PSA_CHK(psa_hash_update(&operation, output, hash_size));
PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
#undef PSA_CHK
cleanup:
mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
psa_hash_abort(&operation);
psa_hash_abort(&aux_operation);
return PSA_TO_MBEDTLS_ERR(status);
}
#undef MAX_HASH_BLOCK_LENGTH
#else
MBEDTLS_STATIC_TESTABLE
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)
{
/*
* This function breaks the HMAC abstraction and uses the md_clone()
* extension to the MD API in order to get constant-flow behaviour.
*
* HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
* concatenation, and okey/ikey are the XOR of the key with some fixed bit
* patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
*
* We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
* minlen, then cloning the context, and for each byte up to maxlen
* finishing up the hash computation, keeping only the correct result.
*
* Then we only need to compute HASH(okey + inner_hash) and we're done.
*/
const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
/* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
* all of which have the same block size except SHA-384. */
const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
const unsigned char * const ikey = ctx->hmac_ctx;
const unsigned char * const okey = ikey + block_size;
const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
mbedtls_md_context_t aux;
size_t offset;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_init(&aux);
#define MD_CHK(func_call) \
do { \
ret = (func_call); \
if (ret != 0) \
goto cleanup; \
} while (0)
MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
/* After hmac_start() of hmac_reset(), ikey has already been hashed,
* so we can start directly with the message */
MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
/* Fill the hash buffer in advance with something that is
* not a valid hash (barring an attack on the hash and
* deliberately-crafted input), in case the caller doesn't
* check the return status properly. */
memset(output, '!', hash_size);
/* For each possible length, compute the hash up to that point */
for (offset = min_data_len; offset <= max_data_len; offset++) {
MD_CHK(mbedtls_md_clone(&aux, ctx));
MD_CHK(mbedtls_md_finish(&aux, aux_out));
/* Keep only the correct inner_hash in the output buffer */
mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
output, aux_out, NULL, hash_size);
if (offset < max_data_len) {
MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
}
}
/* The context needs to finish() before it starts() again */
MD_CHK(mbedtls_md_finish(ctx, aux_out));
/* Now compute HASH(okey + inner_hash) */
MD_CHK(mbedtls_md_starts(ctx));
MD_CHK(mbedtls_md_update(ctx, okey, block_size));
MD_CHK(mbedtls_md_update(ctx, output, hash_size));
MD_CHK(mbedtls_md_finish(ctx, output));
/* Done, get ready for next time */
MD_CHK(mbedtls_md_hmac_reset(ctx));
#undef MD_CHK
cleanup:
mbedtls_md_free(&aux);
return ret;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
/*
@ -1690,11 +1918,11 @@ hmac_failed_etm_enabled:
padlen = data[rec->data_len - 1];
if (auth_done == 1) {
const size_t mask = mbedtls_ct_size_mask_ge(
const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
rec->data_len,
padlen + 1);
correct &= mask;
padlen &= mask;
correct = mbedtls_ct_size_if_else_0(ge, correct);
padlen = mbedtls_ct_size_if_else_0(ge, padlen);
} else {
#if defined(MBEDTLS_SSL_DEBUG_ALL)
if (rec->data_len < transform->maclen + padlen + 1) {
@ -1706,12 +1934,11 @@ hmac_failed_etm_enabled:
padlen + 1));
}
#endif
const size_t mask = mbedtls_ct_size_mask_ge(
const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
rec->data_len,
transform->maclen + padlen + 1);
correct &= mask;
padlen &= mask;
correct = mbedtls_ct_size_if_else_0(ge, correct);
padlen = mbedtls_ct_size_if_else_0(ge, padlen);
}
padlen++;
@ -1740,19 +1967,20 @@ hmac_failed_etm_enabled:
/* pad_count += (idx >= padding_idx) &&
* (check[idx] == padlen - 1);
*/
const size_t mask = mbedtls_ct_size_mask_ge(idx, padding_idx);
const size_t equal = mbedtls_ct_size_bool_eq(check[idx],
padlen - 1);
pad_count += mask & equal;
const mbedtls_ct_condition_t a = mbedtls_ct_uint_ge(idx, padding_idx);
size_t increment = mbedtls_ct_size_if_else_0(a, 1);
const mbedtls_ct_condition_t b = mbedtls_ct_uint_eq(check[idx], padlen - 1);
increment = mbedtls_ct_size_if_else_0(b, increment);
pad_count += increment;
}
correct &= mbedtls_ct_size_bool_eq(pad_count, padlen);
correct = mbedtls_ct_size_if_else_0(mbedtls_ct_uint_eq(pad_count, padlen), padlen);
#if defined(MBEDTLS_SSL_DEBUG_ALL)
if (padlen > 0 && correct == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
}
#endif
padlen &= mbedtls_ct_size_mask(correct);
padlen = mbedtls_ct_size_if_else_0(mbedtls_ct_bool(correct), padlen);
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@ -3602,8 +3830,9 @@ static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
*/
rec->ver[0] = buf[rec_hdr_version_offset + 0];
rec->ver[1] = buf[rec_hdr_version_offset + 1];
tls_version = mbedtls_ssl_read_version(buf + rec_hdr_version_offset,
ssl->conf->transport);
tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(
buf + rec_hdr_version_offset,
ssl->conf->transport);
if (tls_version > ssl->conf->max_tls_version) {
MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u",
@ -5829,8 +6058,7 @@ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
if (hs_buf->is_valid == 1) {
hs->buffering.total_bytes_buffered -= hs_buf->data_len;
mbedtls_platform_zeroize(hs_buf->data, hs_buf->data_len);
mbedtls_free(hs_buf->data);
mbedtls_zeroize_and_free(hs_buf->data, hs_buf->data_len);
memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
}
}
@ -5849,15 +6077,19 @@ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
void mbedtls_ssl_write_version(unsigned char version[2], int transport,
mbedtls_ssl_protocol_version tls_version)
{
uint16_t tls_version_formatted;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
tls_version =
tls_version_formatted =
~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201));
}
} else
#else
((void) transport);
#endif
MBEDTLS_PUT_UINT16_BE(tls_version, version, 0);
{
tls_version_formatted = (uint16_t) tls_version;
}
MBEDTLS_PUT_UINT16_BE(tls_version_formatted, version, 0);
}
uint16_t mbedtls_ssl_read_version(const unsigned char version[2],

View file

@ -327,8 +327,7 @@ static int resize_buffer(unsigned char **buffer, size_t len_new, size_t *len_old
* lost, are done outside of this function. */
memcpy(resized_buffer, *buffer,
(len_new < *len_old) ? len_new : *len_old);
mbedtls_platform_zeroize(*buffer, *len_old);
mbedtls_free(*buffer);
mbedtls_zeroize_and_free(*buffer, *len_old);
*buffer = resized_buffer;
*len_old = len_new;
@ -987,7 +986,8 @@ static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake)
#if defined(MBEDTLS_DHM_C)
mbedtls_dhm_init(&handshake->dhm_ctx);
#endif
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
mbedtls_ecdh_init(&handshake->ecdh_ctx);
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@ -2123,9 +2123,7 @@ static void ssl_conf_remove_psk(mbedtls_ssl_config *conf)
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if (conf->psk != NULL) {
mbedtls_platform_zeroize(conf->psk, conf->psk_len);
mbedtls_free(conf->psk);
mbedtls_zeroize_and_free(conf->psk, conf->psk_len);
conf->psk = NULL;
conf->psk_len = 0;
}
@ -2217,9 +2215,8 @@ static void ssl_remove_psk(mbedtls_ssl_context *ssl)
}
#else
if (ssl->handshake->psk != NULL) {
mbedtls_platform_zeroize(ssl->handshake->psk,
mbedtls_zeroize_and_free(ssl->handshake->psk,
ssl->handshake->psk_len);
mbedtls_free(ssl->handshake->psk);
ssl->handshake->psk_len = 0;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
@ -2436,7 +2433,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite(
}
#else
const mbedtls_cipher_info_t *cipher =
mbedtls_cipher_info_from_type(suite->cipher);
mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) suite->cipher);
if (cipher != NULL) {
base_mode =
mbedtls_ssl_get_base_mode(
@ -2975,8 +2972,7 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
* so we can free it safely */
if (ssl->hostname != NULL) {
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
mbedtls_free(ssl->hostname);
mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname));
}
/* Passing NULL as hostname shall clear the old one */
@ -3116,12 +3112,12 @@ void mbedtls_ssl_get_dtls_srtp_negotiation_result(const mbedtls_ssl_context *ssl
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor)
{
conf->max_tls_version = (major << 8) | minor;
conf->max_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor);
}
void mbedtls_ssl_conf_min_version(mbedtls_ssl_config *conf, int major, int minor)
{
conf->min_tls_version = (major << 8) | minor;
conf->min_tls_version = (mbedtls_ssl_protocol_version) ((major << 8) | minor);
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */
@ -3749,7 +3745,7 @@ static int ssl_session_load(mbedtls_ssl_session *session,
if (1 > (size_t) (end - p)) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
session->tls_version = 0x0300 | *p++;
session->tls_version = (mbedtls_ssl_protocol_version) (0x0300 | *p++);
/* Dispatch according to TLS version. */
remaining_len = (end - p);
@ -3852,7 +3848,7 @@ int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_CLI_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
MBEDTLS_SSL_DEBUG_MSG(2, ("client state: %s",
mbedtls_ssl_states_str(ssl->state)));
mbedtls_ssl_states_str((mbedtls_ssl_states) ssl->state)));
switch (ssl->state) {
case MBEDTLS_SSL_HELLO_REQUEST:
@ -4132,7 +4128,8 @@ void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_DHM_C)
mbedtls_dhm_free(&handshake->dhm_ctx);
#endif
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
mbedtls_ecdh_free(&handshake->ecdh_ctx);
#endif
@ -4158,7 +4155,8 @@ void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
#endif
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) || \
defined(MBEDTLS_PK_CAN_ECDSA_SOME) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/* explicit void pointer cast for buggy MS compiler */
mbedtls_free((void *) handshake->curves_tls_id);
@ -4177,8 +4175,7 @@ void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
}
#else
if (handshake->psk != NULL) {
mbedtls_platform_zeroize(handshake->psk, handshake->psk_len);
mbedtls_free(handshake->psk);
mbedtls_zeroize_and_free(handshake->psk, handshake->psk_len);
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
@ -4216,13 +4213,11 @@ void mbedtls_ssl_handshake_free(mbedtls_ssl_context *ssl)
mbedtls_ssl_buffering_free(ssl);
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED)
if (handshake->xxdh_psa_privkey_is_external == 0) {
psa_destroy_key(handshake->xxdh_psa_privkey);
}
#endif /* (PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH) &&
(MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3) */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_XXDH_PSA_ANY_ENABLED */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_transform_free(handshake->transform_handshake);
@ -4851,8 +4846,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
#endif
mbedtls_platform_zeroize(ssl->out_buf, out_buf_len);
mbedtls_free(ssl->out_buf);
mbedtls_zeroize_and_free(ssl->out_buf, out_buf_len);
ssl->out_buf = NULL;
}
@ -4863,8 +4857,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
#endif
mbedtls_platform_zeroize(ssl->in_buf, in_buf_len);
mbedtls_free(ssl->in_buf);
mbedtls_zeroize_and_free(ssl->in_buf, in_buf_len);
ssl->in_buf = NULL;
}
@ -4898,8 +4891,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_X509_CRT_PARSE_C)
if (ssl->hostname != NULL) {
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
mbedtls_free(ssl->hostname);
mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname));
}
#endif
@ -5382,15 +5374,13 @@ void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if (conf->psk != NULL) {
mbedtls_platform_zeroize(conf->psk, conf->psk_len);
mbedtls_free(conf->psk);
mbedtls_zeroize_and_free(conf->psk, conf->psk_len);
conf->psk = NULL;
conf->psk_len = 0;
}
if (conf->psk_identity != NULL) {
mbedtls_platform_zeroize(conf->psk_identity, conf->psk_identity_len);
mbedtls_free(conf->psk_identity);
mbedtls_zeroize_and_free(conf->psk_identity, conf->psk_identity_len);
conf->psk_identity = NULL;
conf->psk_identity_len = 0;
}
@ -6548,7 +6538,7 @@ int mbedtls_ssl_derive_keys(mbedtls_ssl_context *ssl)
/* Set PRF, calc_verify and calc_finished function pointers */
ret = ssl_set_handshake_prfs(ssl->handshake,
ciphersuite_info->mac);
(mbedtls_md_type_t) ciphersuite_info->mac);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "ssl_set_handshake_prfs", ret);
return ret;
@ -8224,7 +8214,7 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
goto end;
}
#else
cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher);
cipher_info = mbedtls_cipher_info_from_type((mbedtls_cipher_type_t) ciphersuite_info->cipher);
if (cipher_info == NULL) {
MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found",
ciphersuite_info->cipher));
@ -8240,7 +8230,7 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
#else
md_info = mbedtls_md_info_from_type(ciphersuite_info->mac);
md_info = mbedtls_md_info_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
if (md_info == NULL) {
MBEDTLS_SSL_DEBUG_MSG(1, ("mbedtls_md info for %u not found",
(unsigned) ciphersuite_info->mac));
@ -9569,9 +9559,8 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session,
/* Now it's clear that we will overwrite the old hostname,
* so we can free it safely */
if (session->hostname != NULL) {
mbedtls_platform_zeroize(session->hostname,
mbedtls_zeroize_and_free(session->hostname,
strlen(session->hostname));
mbedtls_free(session->hostname);
}
/* Passing NULL as hostname shall clear the old one */

View file

@ -99,7 +99,8 @@ static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_RENEGOTIATION */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
@ -130,8 +131,8 @@ static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
return 0;
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
@ -547,7 +548,8 @@ int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl,
p += ext_len;
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if (uses_ec) {
if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end,
@ -815,7 +817,8 @@ static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
@ -837,9 +840,10 @@ static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
while (list_size > 0) {
if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED) {
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
ssl->handshake->ecdh_ctx.point_format = p[0];
#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_ECDH_C */
#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */
#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx,
@ -858,8 +862,8 @@ static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
@ -1271,7 +1275,8 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
buf += mbedtls_ssl_hs_hdr_len(ssl);
MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2);
ssl->tls_version = mbedtls_ssl_read_version(buf, ssl->conf->transport);
ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
ssl->conf->transport);
ssl->session_negotiate->tls_version = ssl->tls_version;
if (ssl->tls_version < ssl->conf->min_tls_version ||
@ -1542,8 +1547,8 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_ECDSA_C) || defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG(3,
("found supported_point_formats extension"));
@ -1554,7 +1559,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
}
break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@ -1762,7 +1767,7 @@ static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
handshake->xxdh_psa_type = key_type;
handshake->xxdh_bits = ec_bits;
handshake->xxdh_psa_bits = ec_bits;
/* Keep a copy of the peer's public key */
ecpoint_len = *(*p)++;
@ -1770,18 +1775,9 @@ static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
/* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account
the sizes of the FFDH keys which are at least 2048 bits.
The size of the array is thus greater than 256 bytes which is greater than any
possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/
#if !defined(PSA_WANT_ALG_FFDH)
if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
if (ecpoint_len > PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) {
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
#else
MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX,
"peer key buffer too small");
#endif
memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len);
handshake->xxdh_psa_peerkey_len = ecpoint_len;
@ -2045,7 +2041,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
/* If the above conversion to TLS ID was fine, then also this one will be,
so there is no need to check the return value here */
mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
&ssl->handshake->xxdh_bits);
&ssl->handshake->xxdh_psa_bits);
ssl->handshake->xxdh_psa_type = key_type;
@ -2796,7 +2792,7 @@ static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl)
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
psa_set_key_bits(&key_attributes, handshake->xxdh_bits);
psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
/* Generate ECDH private key. */
status = psa_generate_key(&key_attributes,
@ -2968,7 +2964,7 @@ ecdh_calc_secret:
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
psa_set_key_bits(&key_attributes, handshake->xxdh_bits);
psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
/* Generate ECDH private key. */
status = psa_generate_key(&key_attributes,
@ -3148,7 +3144,8 @@ ecdh_calc_secret:
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
ciphersuite_info->key_exchange)) != 0) {
(mbedtls_key_exchange_type_t) ciphersuite_info->
key_exchange)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1,
"mbedtls_ssl_psk_derive_premaster", ret);
return ret;
@ -3459,16 +3456,14 @@ static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl)
}
if (ssl->session != NULL && ssl->session->ticket != NULL) {
mbedtls_platform_zeroize(ssl->session->ticket,
mbedtls_zeroize_and_free(ssl->session->ticket,
ssl->session->ticket_len);
mbedtls_free(ssl->session->ticket);
ssl->session->ticket = NULL;
ssl->session->ticket_len = 0;
}
mbedtls_platform_zeroize(ssl->session_negotiate->ticket,
mbedtls_zeroize_and_free(ssl->session_negotiate->ticket,
ssl->session_negotiate->ticket_len);
mbedtls_free(ssl->session_negotiate->ticket);
ssl->session_negotiate->ticket = NULL;
ssl->session_negotiate->ticket_len = 0;

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