mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-01 13:13:28 +00:00
Merge remote-tracking branch 'restricted/development' into mbedtls-3.5.2rc
This commit is contained in:
commit
13f2f4e7f1
4
.gitignore
vendored
4
.gitignore
vendored
@ -63,5 +63,7 @@ massif-*
|
||||
/cscope*.out
|
||||
/tags
|
||||
|
||||
# Clangd compilation database
|
||||
# clangd compilation database
|
||||
compile_commands.json
|
||||
# clangd index files
|
||||
/.cache/clangd/index/
|
||||
|
2
3rdparty/Makefile.inc
vendored
2
3rdparty/Makefile.inc
vendored
@ -1,3 +1,3 @@
|
||||
THIRDPARTY_DIR = $(dir $(word 2, $(MAKEFILE_LIST)))
|
||||
THIRDPARTY_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
include $(THIRDPARTY_DIR)/everest/Makefile.inc
|
||||
include $(THIRDPARTY_DIR)/p256-m/Makefile.inc
|
||||
|
@ -62,7 +62,7 @@ if(CMAKE_HOST_WIN32)
|
||||
# CMakeLists.txt.
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" OFF) # off in development
|
||||
else()
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" OFF)
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" ON)
|
||||
endif()
|
||||
|
||||
option(DISABLE_PACKAGE_CONFIG_AND_INSTALL "Disable package configuration, target export and installation" ${MBEDTLS_AS_SUBPROJECT})
|
||||
@ -117,7 +117,7 @@ endif()
|
||||
# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
|
||||
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan TSanDbg"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
@ -212,6 +212,8 @@ if(CMAKE_COMPILER_IS_GNU)
|
||||
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
|
||||
set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
|
||||
set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3")
|
||||
set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_CHECK "-Os")
|
||||
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
|
||||
endif(CMAKE_COMPILER_IS_GNU)
|
||||
@ -225,6 +227,8 @@ if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_MEMSAN "-fsanitize=memory -O3")
|
||||
set(CMAKE_C_FLAGS_MEMSANDBG "-fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
|
||||
set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3")
|
||||
set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_CHECK "-Os")
|
||||
endif(CMAKE_COMPILER_IS_CLANG)
|
||||
|
||||
|
@ -86,7 +86,7 @@ License and Copyright
|
||||
|
||||
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license. See the [LICENSE](LICENSE) file for the full text of these licenses. This means that users may choose which of these licenses they take the code under.
|
||||
|
||||
Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 or GPL-2.0-or-later licenses.
|
||||
Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses.
|
||||
|
||||
All new files should include the standard SPDX license identifier where possible, i.e. "SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later".
|
||||
|
||||
|
3
ChangeLog.d/7764.txt
Normal file
3
ChangeLog.d/7764.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa()
|
||||
to convert between Mbed TLS and PSA curve identifiers.
|
4
ChangeLog.d/8340.txt
Normal file
4
ChangeLog.d/8340.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Features
|
||||
* Add functions mbedtls_md_psa_alg_from_type() and
|
||||
mbedtls_md_type_from_psa_alg() to convert between mbedtls_md_type_t and
|
||||
psa_algorithm_t.
|
3
ChangeLog.d/8372.txt
Normal file
3
ChangeLog.d/8372.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* AES-NI is now supported in Windows builds with clang and clang-cl.
|
||||
Resolves #8372.
|
4
ChangeLog.d/8461.txt
Normal file
4
ChangeLog.d/8461.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Bugfix
|
||||
* Fix unsupported PSA asymmetric encryption and decryption
|
||||
(psa_asymmetric_[en|de]crypt) with opaque keys.
|
||||
Resolves #8461.
|
6
ChangeLog.d/8482.txt
Normal file
6
ChangeLog.d/8482.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Changes
|
||||
* PSA_WANT_ALG_CCM and PSA_WANT_ALG_CCM_STAR_NO_TAG are no more synonyms and
|
||||
they are now treated separately. This means that they should be
|
||||
individually enabled in order to enable respective support; also the
|
||||
corresponding MBEDTLS_PSA_ACCEL symbol should be defined in case
|
||||
acceleration is required.
|
6
ChangeLog.d/add-block-cipher-no-decrypt.txt
Normal file
6
ChangeLog.d/add-block-cipher-no-decrypt.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Features
|
||||
* Enable the new option MBEDTLS_BLOCK_CIPHER_NO_DECRYPT to omit
|
||||
the decryption direction of block ciphers (AES, ARIA, Camellia).
|
||||
This affects both the low-level modules and the high-level APIs
|
||||
(the cipher and PSA interfaces). This option is incompatible with modes
|
||||
that use the decryption direction (ECB in PSA, CBC, XTS, KW) and with DES.
|
2
ChangeLog.d/add-psa-example-program-hash.txt
Normal file
2
ChangeLog.d/add-psa-example-program-hash.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Features
|
||||
* Added an example program showing how to hash with the PSA API.
|
5
ChangeLog.d/add-record-size-limit-extension-support.txt
Normal file
5
ChangeLog.d/add-record-size-limit-extension-support.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Features
|
||||
* Add support for record size limit extension as defined by RFC 8449
|
||||
and configured with MBEDTLS_SSL_RECORD_SIZE_LIMIT.
|
||||
Application data sent and received will be fragmented according to
|
||||
Record size limits negotiated during handshake.
|
3
ChangeLog.d/armv8-aesce.txt
Normal file
3
ChangeLog.d/armv8-aesce.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Support use of Armv8-A Cryptographic Extensions for hardware acclerated
|
||||
AES when compiling for Thumb (T32) or 32-bit Arm (A32).
|
3
ChangeLog.d/ctr-perf.txt
Normal file
3
ChangeLog.d/ctr-perf.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Improve performance of AES-GCM, AES-CTR and CTR-DRBG when
|
||||
hardware accelerated AES is not present (around 13-23% on 64-bit Arm).
|
11
ChangeLog.d/driver-only-cipher.txt
Normal file
11
ChangeLog.d/driver-only-cipher.txt
Normal file
@ -0,0 +1,11 @@
|
||||
Features
|
||||
* If a cipher or AEAD mechanism has a PSA driver, you can now build the
|
||||
library without the corresponding built-in implementation. Generally
|
||||
speaking that requires both the key type and algorithm to be accelerated
|
||||
or they'll both be built in. However, for CCM and GCM the built-in
|
||||
implementation is able to take advantage of a driver that only
|
||||
accelerates the key type (that is, the block cipher primitive). See
|
||||
docs/driver-only-builds.md for full details and current limitations.
|
||||
* The CTR_DRBG module will now use AES from a PSA driver if MBEDTLS_AES_C is
|
||||
disabled. This requires PSA_WANT_ALG_ECB_NO_PADDING in addition to
|
||||
MBEDTLS_PSA_CRYPTO_C and PSA_WANT_KEY_TYPE_AES.
|
5
ChangeLog.d/ecp-keypair-utilities.txt
Normal file
5
ChangeLog.d/ecp-keypair-utilities.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Features
|
||||
* Add utility functions to manipulate mbedtls_ecp_keypair objects, filling
|
||||
gaps made by making its fields private: mbedtls_ecp_set_public_key(),
|
||||
mbedtls_ecp_write_public_key(), mbedtls_ecp_keypair_calc_public(),
|
||||
mbedtls_ecp_keypair_get_group_id(). Fixes #5017, #5441, #8367, #8652.
|
3
ChangeLog.d/fix-cmake-3rdparty-custom-config.txt
Normal file
3
ChangeLog.d/fix-cmake-3rdparty-custom-config.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix the build with CMake when Everest or P256-m is enabled through
|
||||
a user configuration file or the compiler command line. Fixes #8165.
|
3
ChangeLog.d/fix-cpp-compilation-error.txt
Normal file
3
ChangeLog.d/fix-cpp-compilation-error.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix compilation error in C++ programs when MBEDTLS_ASN1_PARSE_C is
|
||||
disabled.
|
@ -0,0 +1,6 @@
|
||||
Features
|
||||
* Add new mbedtls_x509_csr_parse_der_with_ext_cb() routine which allows
|
||||
parsing unsupported certificate extensions via user provided callback.
|
||||
|
||||
Bugfix
|
||||
* Fix parsing of CSRs with critical extensions.
|
3
ChangeLog.d/fix-issue-x509-cert_req.txt
Normal file
3
ChangeLog.d/fix-issue-x509-cert_req.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix possible NULL dereference issue in X509 cert_req program if an entry
|
||||
in the san parameter is not separated by a colon.
|
3
ChangeLog.d/fix-issue-x509-cert_write.txt
Normal file
3
ChangeLog.d/fix-issue-x509-cert_write.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix possible NULL dereference issue in X509 cert_write program if an entry
|
||||
in the san parameter is not separated by a colon.
|
2
ChangeLog.d/fix-linux-builds-in-conda-forge.txt
Normal file
2
ChangeLog.d/fix-linux-builds-in-conda-forge.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Bugfix
|
||||
* Fix build failure in conda-forge. Fixes #8422.
|
4
ChangeLog.d/fix-mingw32-build.txt
Normal file
4
ChangeLog.d/fix-mingw32-build.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Bugfix
|
||||
* Fix an inconsistency between implementations and usages of `__cpuid`,
|
||||
which mainly causes failures when building Windows target using
|
||||
mingw or clang. Fixes #8334 & #8332.
|
3
ChangeLog.d/fix-tls-SuiteB.txt
Normal file
3
ChangeLog.d/fix-tls-SuiteB.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Remove accidental introduction of RSA signature algorithms
|
||||
in TLS Suite B Profile. Fixes #8221.
|
3
ChangeLog.d/fix-tls13-server-min-version-check.txt
Normal file
3
ChangeLog.d/fix-tls13-server-min-version-check.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix TLS server accepting TLS 1.2 handshake while TLS 1.2
|
||||
is disabled at runtime. Fixes #8593.
|
5
ChangeLog.d/gnutls_anti_replay_fail.txt
Normal file
5
ChangeLog.d/gnutls_anti_replay_fail.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Bugfix
|
||||
* Switch to milliseconds as the unit for ticket creation and reception time
|
||||
instead of seconds. That avoids rounding errors when computing the age of
|
||||
tickets compared to peer using a millisecond clock (observed with GnuTLS).
|
||||
Fixes #6623.
|
3
ChangeLog.d/move-mbedtls-ecc-psa-helpers.txt
Normal file
3
ChangeLog.d/move-mbedtls-ecc-psa-helpers.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Changes
|
||||
* Moved declaration of functions mbedtls_ecc_group_to_psa and
|
||||
mbedtls_ecc_group_of_psa from psa/crypto_extra.h to mbedtls/psa_util.h
|
9
ChangeLog.d/no-cipher.txt
Normal file
9
ChangeLog.d/no-cipher.txt
Normal file
@ -0,0 +1,9 @@
|
||||
Features
|
||||
* Fewer modules depend on MBEDTLS_CIPHER_C, making it possible to save code
|
||||
size by disabling it in more circumstances. In particular, the CCM and
|
||||
GCM modules no longer depend on MBEDTLS_CIPHER_C. Also,
|
||||
MBEDTLS_PSA_CRYPTO can now be enabled without MBEDTLS_CIPHER_C if all
|
||||
unauthenticated (non-AEAD) ciphers are disabled, or if they're all
|
||||
fully provided by drivers. See docs/driver-only-builds.md for full
|
||||
details and current limitations; in particular, NIST_KW and PKCS5/PKCS12
|
||||
decryption still unconditionally depend on MBEDTLS_CIPHER_C.
|
3
ChangeLog.d/non-psa-pk-implementation.txt
Normal file
3
ChangeLog.d/non-psa-pk-implementation.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Changes
|
||||
* mbedtls_pk_sign_ext() is now always available, not just when
|
||||
PSA (MBEDTLS_PSA_CRYPTO_C) is enabled.
|
4
ChangeLog.d/pkwrite-pem-use-heap.txt
Normal file
4
ChangeLog.d/pkwrite-pem-use-heap.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Changes
|
||||
* Use heap memory to allocate DER encoded public/private key.
|
||||
This reduces stack usage significantly for writing a public/private
|
||||
key to a PEM string.
|
4
ChangeLog.d/rename-conf-early-data-API.txt
Normal file
4
ChangeLog.d/rename-conf-early-data-API.txt
Normal file
@ -0,0 +1,4 @@
|
||||
API changes
|
||||
* Remove `tls13_` in mbedtls_ssl_tls13_conf_early_data() and
|
||||
mbedtls_ssl_tls13_conf_max_early_data_size() API names. Early data
|
||||
feature may not be TLS 1.3 specific in the future. Fixes #6909.
|
7
ChangeLog.d/sha256-armce-arm.txt
Normal file
7
ChangeLog.d/sha256-armce-arm.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Features
|
||||
* Support Armv8-A Crypto Extension acceleration for SHA-256
|
||||
when compiling for Thumb (T32) or 32-bit Arm (A32).
|
||||
New deprecations
|
||||
* Rename the MBEDTLS_SHA256_USE_A64_CRYPTO_xxx config options to
|
||||
MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_xxx. The old names may still
|
||||
be used, but are deprecated.
|
2
Makefile
2
Makefile
@ -45,7 +45,7 @@ generated_files: visualc_files
|
||||
# that lacks some of the necessary tools to re-generate the files.
|
||||
# If $(GEN_FILES) is non-empty, the generated source files' dependencies
|
||||
# are treated ordinarily, based on file timestamps.
|
||||
GEN_FILES ?=
|
||||
GEN_FILES ?= yes
|
||||
|
||||
# In dependencies where the target is a configuration-independent generated
|
||||
# file, use `TARGET: $(gen_file_dep) DEPENDENCY1 DEPENDENCY2 ...`
|
||||
|
68
configs/config-tfm.h
Normal file
68
configs/config-tfm.h
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* \file config-tfm.h
|
||||
*
|
||||
* \brief TF-M medium profile, adapted to work on other platforms.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* TF-M medium profile: mbedtls legacy configuration */
|
||||
#include "../configs/ext/tfm_mbedcrypto_config_profile_medium.h"
|
||||
|
||||
/* TF-M medium profile: PSA crypto configuration */
|
||||
#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "../configs/ext/crypto_config_profile_medium.h"
|
||||
|
||||
/***********************************************************/
|
||||
/* Tweak the configuration to remove dependencies on TF-M. */
|
||||
/***********************************************************/
|
||||
|
||||
/* MBEDTLS_PSA_CRYPTO_SPM needs third-party files, so disable it. */
|
||||
#undef MBEDTLS_PSA_CRYPTO_SPM
|
||||
|
||||
/* Disable buffer-based memory allocator. This isn't strictly required,
|
||||
* but using the native allocator is faster and works better with
|
||||
* memory management analysis frameworks such as ASan. */
|
||||
#undef MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
#undef MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
// These platform-related TF-M settings are not useful here.
|
||||
#undef MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#undef MBEDTLS_PLATFORM_STD_MEM_HDR
|
||||
#undef MBEDTLS_PLATFORM_SNPRINTF_MACRO
|
||||
#undef MBEDTLS_PLATFORM_PRINTF_ALT
|
||||
#undef MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
|
||||
#undef MBEDTLS_PLATFORM_STD_EXIT_FAILURE
|
||||
|
||||
/*
|
||||
* In order to get an example config that works cleanly out-of-the-box
|
||||
* for both baremetal and non-baremetal builds, we detect baremetal builds
|
||||
* (either IAR, Arm compiler or __ARM_EABI__ defined), and adjust some
|
||||
* variables accordingly.
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__) || defined(__ARMCC_VERSION) || defined(__ARM_EABI__)
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#else
|
||||
/* Use built-in platform entropy functions (TF-M provides its own). */
|
||||
#undef MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Local changes to crypto config below this delimiter
|
||||
**********************************************************************/
|
||||
|
||||
// We expect TF-M to pick this up soon
|
||||
#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
|
||||
|
||||
/* CCM is the only cipher/AEAD enabled in TF-M configuration files, but it
|
||||
* does not need CIPHER_C to be enabled, so we can disable it in order
|
||||
* to reduce code size further. */
|
||||
#undef MBEDTLS_CIPHER_C
|
25
configs/ext/README.md
Normal file
25
configs/ext/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
Summary
|
||||
-------
|
||||
|
||||
The two files:
|
||||
|
||||
* crypto_config_profile_medium.h
|
||||
* tfm_mbedcrypto_config_profile_medium.h
|
||||
|
||||
are copyright The Mbed TLS Contributors, and are distributed under the license normally
|
||||
used by Mbed TLS: a dual Apache 2.0 or GPLv2-or-later license.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
The two files crypto_config_profile_medium.h and tfm_mbedcrypto_config_profile_medium.h
|
||||
are taken verbatim from the TF-M source code here:
|
||||
|
||||
https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/lib/ext/mbedcrypto/mbedcrypto_config
|
||||
|
||||
In TF-M, they are distributed under a 3-Clause BSD license, as noted at the top of the files.
|
||||
|
||||
In Mbed TLS, with permission from the TF-M project, they are distributed under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license, with copyright assigned to The Mbed TLS Contributors.
|
||||
|
||||
We only retain the note at the top of the files because we are taking the files verbatim, for ease of
|
||||
maintenance.
|
13
configs/ext/config_tfm.h
Normal file
13
configs/ext/config_tfm.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Empty placeholder
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is intentionally empty.
|
||||
*
|
||||
* Having an empty file here allows us to build the TF-M config, which references this file,
|
||||
* without making any changes to the TF-M config.
|
||||
*/
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
* Copyright (c) 2018-2023, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file psa/crypto_config.h
|
||||
@ -49,7 +51,7 @@
|
||||
//#define PSA_WANT_ALG_CFB 1
|
||||
//#define PSA_WANT_ALG_CHACHA20_POLY1305 1
|
||||
//#define PSA_WANT_ALG_CTR 1
|
||||
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
//#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
//#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECDH 1
|
||||
#define PSA_WANT_ALG_ECDSA 1
|
||||
@ -104,33 +106,27 @@
|
||||
//#define PSA_WANT_KEY_TYPE_CAMELLIA 1
|
||||
//#define PSA_WANT_KEY_TYPE_CHACHA20 1
|
||||
//#define PSA_WANT_KEY_TYPE_DES 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
|
||||
//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 /* Deprecated */
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 /* Deprecated */
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
|
||||
/*
|
||||
* The following symbols extend and deprecate the legacy
|
||||
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR ones. They include the usage of that key in
|
||||
* the name's suffix. "_USE" is the most generic and it can be used to describe
|
||||
* a generic suport, whereas other ones add more features on top of that and
|
||||
* they are more specific.
|
||||
*/
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 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
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
#include "crypto_accelerator_config.h"
|
||||
#endif
|
||||
|
||||
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */
|
13
configs/ext/mbedtls_entropy_nv_seed_config.h
Normal file
13
configs/ext/mbedtls_entropy_nv_seed_config.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Empty placeholder
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is intentionally empty.
|
||||
*
|
||||
* Having an empty file here allows us to build the TF-M config, which references this file,
|
||||
* without making any changes to the TF-M config.
|
||||
*/
|
@ -8,13 +8,29 @@
|
||||
* memory footprint.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
* Copyright (C) 2006-2023, ARM Limited, All Rights Reserved
|
||||
* 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.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_M_MBEDTLS_CONFIG_H
|
||||
#define PROFILE_M_MBEDTLS_CONFIG_H
|
||||
|
||||
#include "config_tfm.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
@ -80,44 +96,6 @@
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MD2_PROCESS_ALT
|
||||
*
|
||||
* MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
|
||||
* alternate core implementation of symmetric crypto or hash function. Keep in
|
||||
* mind that function prototypes should remain the same.
|
||||
*
|
||||
* This replaces only one function. The header file from mbed TLS is still
|
||||
* used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
|
||||
*
|
||||
* Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
|
||||
* no longer provide the mbedtls_sha1_process() function, but it will still provide
|
||||
* the other function (using your mbedtls_sha1_process() function) and the definition
|
||||
* of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
|
||||
* with this definition.
|
||||
*
|
||||
* \note Because of a signature change, the core AES encryption and decryption routines are
|
||||
* currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
|
||||
* respectively. When setting up alternative implementations, these functions should
|
||||
* be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
|
||||
* must stay untouched.
|
||||
*
|
||||
* \note If you use the AES_xxx_ALT macros, then is is recommended to also set
|
||||
* MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
|
||||
* tables.
|
||||
*
|
||||
* Uncomment a macro to enable alternate implementation of the corresponding
|
||||
* function.
|
||||
*
|
||||
* \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
|
||||
* constitutes a security risk. If possible, we recommend avoiding
|
||||
* dependencies on them, and considering stronger message digests
|
||||
* and ciphers instead.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_SETKEY_DEC_ALT
|
||||
#define MBEDTLS_AES_DECRYPT_ALT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ROM_TABLES
|
||||
*
|
||||
@ -171,21 +149,6 @@
|
||||
*/
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ERROR_STRERROR_DUMMY
|
||||
*
|
||||
* Enable a dummy error function to make use of mbedtls_strerror() in
|
||||
* third party libraries easier when MBEDTLS_ERROR_C is disabled
|
||||
* (no effect when MBEDTLS_ERROR_C is enabled).
|
||||
*
|
||||
* You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
|
||||
* not using mbedtls_strerror() or error_strerror() in your application.
|
||||
*
|
||||
* Disable if you run into name conflicts and want to really remove the
|
||||
* mbedtls_strerror()
|
||||
*/
|
||||
#define MBEDTLS_ERROR_STRERROR_DUMMY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
*
|
||||
@ -223,26 +186,7 @@
|
||||
* \note The entropy collector will write to the seed file before entropy is
|
||||
* given to an external source, to update it.
|
||||
*/
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
//#define MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
*
|
||||
* Enable key identifiers that encode a key owner identifier.
|
||||
*
|
||||
* This is only meaningful when building the library as part of a
|
||||
* multi-client service. When you activate this option, you must provide an
|
||||
* implementation of the type mbedtls_key_owner_id_t and a translation from
|
||||
* mbedtls_svc_key_id_t to file name in all the storage backends that you
|
||||
* you wish to support.
|
||||
*
|
||||
* Note that while this define has been removed from TF-M's copy of this config
|
||||
* file, TF-M still passes this option to Mbed TLS during the build via CMake.
|
||||
* Therefore we keep it in our copy. See discussion on PR #7426 for more info.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
#define MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_SPM
|
||||
@ -325,6 +269,23 @@
|
||||
*/
|
||||
#define MBEDTLS_AES_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
|
||||
*
|
||||
* Use only 128-bit keys in AES operations to save ROM.
|
||||
*
|
||||
* Uncomment this macro to remove support for AES operations that use 192-
|
||||
* or 256-bit keys.
|
||||
*
|
||||
* Uncommenting this macro reduces the size of AES code by ~300 bytes
|
||||
* on v8-M/Thumb2.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
*
|
||||
* Requires: MBEDTLS_AES_C
|
||||
*/
|
||||
#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CIPHER_C
|
||||
*
|
||||
@ -366,18 +327,6 @@
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ERROR_C
|
||||
*
|
||||
* Enable error code to error string conversion.
|
||||
*
|
||||
* Module: library/error.c
|
||||
* Caller:
|
||||
*
|
||||
* This module enables mbedtls_strerror().
|
||||
*/
|
||||
#define MBEDTLS_ERROR_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HKDF_C
|
||||
*
|
||||
@ -391,40 +340,7 @@
|
||||
* This module adds support for the Hashed Message Authentication Code
|
||||
* (HMAC)-based key derivation function (HKDF).
|
||||
*/
|
||||
#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MD_C
|
||||
*
|
||||
* Enable the generic layer for message digest (hashing) and HMAC.
|
||||
*
|
||||
* Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C,
|
||||
* MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C,
|
||||
* MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least
|
||||
* one hash.
|
||||
* Module: library/md.c
|
||||
* Caller: library/constant_time.c
|
||||
* library/ecdsa.c
|
||||
* library/ecjpake.c
|
||||
* library/hkdf.c
|
||||
* library/hmac_drbg.c
|
||||
* library/pk.c
|
||||
* library/pkcs5.c
|
||||
* library/pkcs12.c
|
||||
* library/psa_crypto_ecp.c
|
||||
* library/psa_crypto_rsa.c
|
||||
* library/rsa.c
|
||||
* library/ssl_cookie.c
|
||||
* library/ssl_msg.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509.c
|
||||
* library/x509_crt.c
|
||||
* library/x509write_crt.c
|
||||
* library/x509write_csr.c
|
||||
*
|
||||
* Uncomment to enable generic message digest wrappers.
|
||||
*/
|
||||
#define MBEDTLS_MD_C
|
||||
//#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
@ -462,6 +378,15 @@
|
||||
*/
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
|
||||
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#define MBEDTLS_PLATFORM_STD_MEM_HDR <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
|
||||
#define MBEDTLS_PLATFORM_PRINTF_ALT
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_C
|
||||
@ -486,9 +411,7 @@
|
||||
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
|
||||
* the PSA ITS interface
|
||||
*/
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
||||
/* \} name SECTION: mbed TLS modules */
|
||||
|
||||
@ -592,6 +515,47 @@
|
||||
/* ECP options */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Disable fixed-point speed-up */
|
||||
|
||||
/**
|
||||
* Uncomment to enable p256-m. This is an alternative implementation of
|
||||
* key generation, ECDH and (randomized) ECDSA on the curve SECP256R1.
|
||||
* Compared to the default implementation:
|
||||
*
|
||||
* - p256-m has a much smaller code size and RAM footprint.
|
||||
* - p256-m is only available via the PSA API. This includes the pk module
|
||||
* when #MBEDTLS_USE_PSA_CRYPTO is enabled.
|
||||
* - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols
|
||||
* over the core arithmetic, or deterministic derivation of keys.
|
||||
*
|
||||
* We recommend enabling this option if your application uses the PSA API
|
||||
* and the only elliptic curve support it needs is ECDH and ECDSA over
|
||||
* SECP256R1.
|
||||
*
|
||||
* If you enable this option, you do not need to enable any ECC-related
|
||||
* MBEDTLS_xxx option. You do need to separately request support for the
|
||||
* cryptographic mechanisms through the PSA API:
|
||||
* - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based
|
||||
* configuration;
|
||||
* - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS;
|
||||
* - #PSA_WANT_ECC_SECP_R1_256;
|
||||
* - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed;
|
||||
* - #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 and/or
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed.
|
||||
*
|
||||
* \note To benefit from the smaller code size of p256-m, make sure that you
|
||||
* do not enable any ECC-related option not supported by p256-m: this
|
||||
* would cause the built-in ECC implementation to be built as well, in
|
||||
* order to provide the required option.
|
||||
* Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than
|
||||
* SECP256R1 are disabled as they are not supported by this driver.
|
||||
* Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or
|
||||
* #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of
|
||||
* the built-in ECC implementation, see docs/driver-only-builds.md.
|
||||
*/
|
||||
#define MBEDTLS_PSA_P256M_DRIVER_ENABLED
|
||||
|
||||
/* \} name SECTION: Customisation configuration options */
|
||||
|
||||
#if CRYPTO_NV_SEED
|
@ -99,8 +99,8 @@ We can classify code that implements or uses cryptographic mechanisms into sever
|
||||
* Software implementations of primitive cryptographic mechanisms. These are not expected to change.
|
||||
* Software implementations of constructed cryptographic mechanisms (e.g. HMAC, CTR_DRBG, RSA (calling a hash for PSS/OAEP, and needing to know the hash length in PKCS1v1.5 sign/verify), …). These need to keep working whenever a legacy implementation of the auxiliary mechanism is available, regardless of whether a PSA implementation is also available.
|
||||
* Code implementing the PSA crypto interface. This is not expected to change, except perhaps to expose some internal functionality to overhauled glue code.
|
||||
* Code that's subject to `MBEDTLS_USE_PSA_CRYPTO`: `pk.h`, X.509, TLS (excluding TLS 1.3).
|
||||
* Code that always uses PSA for crypto: TLS 1.3, LMS.
|
||||
* Code that's subject to `MBEDTLS_USE_PSA_CRYPTO`: `pk.h`, X.509, TLS (excluding parts specific TLS 1.3).
|
||||
* Code that always uses PSA for crypto: TLS 1.3 (except things common with 1.2), LMS.
|
||||
|
||||
For the purposes of this work, three domains emerge:
|
||||
|
||||
@ -110,23 +110,79 @@ For the purposes of this work, three domains emerge:
|
||||
|
||||
#### Non-use-PSA modules
|
||||
|
||||
The following modules in Mbed TLS call another module to perform cryptographic operations which, in the long term, will be provided through a PSA interface, but cannot make any PSA-related assumption:
|
||||
The following modules in Mbed TLS call another module to perform cryptographic operations which, in the long term, will be provided through a PSA interface, but cannot make any PSA-related assumption.
|
||||
|
||||
* CCM (block cipher in ECB mode; interdependent with cipher)
|
||||
* cipher (cipher and AEAD algorithms)
|
||||
* CMAC (AES-ECB and DES-ECB, but could be extended to the other block ciphers; interdependent with cipher)
|
||||
* CTR\_DRBG (AES-ECB, but could be extended to the other block ciphers)
|
||||
* entropy (hashes via low-level)
|
||||
Hashes and HMAC (after the work on driver-only hashes):
|
||||
|
||||
* entropy (hashes via MD-light)
|
||||
* ECDSA (HMAC\_DRBG; `md.h` exposed through API)
|
||||
* ECJPAKE (hashes via md; `md.h` exposed through API)
|
||||
* GCM (block cipher in ECB mode; interdependent with cipher)
|
||||
* md (hashes and HMAC)
|
||||
* NIST\_KW (AES-ECB; interdependent with cipher)
|
||||
* ECJPAKE (hashes via MD-light; `md.h` exposed through API)
|
||||
* MD (hashes and HMAC)
|
||||
* HKDF (HMAC via `md.h`; `md.h` exposed through API)
|
||||
* HMAC\_DRBG (hashes and HMAC via `md.h`; `md.h` exposed through API)
|
||||
* PEM (AES and DES in CBC mode without padding; MD5 hash via low-level)
|
||||
* PKCS12 (cipher, generically, selected from ASN.1 or function parameters; hashes via md; `cipher.h` exposed through API)
|
||||
* PKCS5 (cipher, generically, selected from ASN.1; HMAC via `md.h`; `md.h` exposed through API)
|
||||
* RSA (hash via md for PSS and OAEP; `md.h` exposed through API)
|
||||
* PKCS12 (hashes via MD-light)
|
||||
* PKCS5 (HMAC via `md.h`; `md.h` exposed through API)
|
||||
* PKCS7 (hashes via MD)
|
||||
* RSA (hash via MD-light for PSS and OAEP; `md.h` exposed through API)
|
||||
* PEM (MD5 hash via MD-light)
|
||||
|
||||
Symmetric ciphers and AEADs (before work on driver-only cipher):
|
||||
|
||||
* PEM:
|
||||
* AES, DES or 3DES in CBC mode without padding, decrypt only (!).
|
||||
* Currently using low-level non-generic APIs.
|
||||
* No hard dependency, features guarded by `AES_C` resp. `DES_C`.
|
||||
* Functions called: `setkey_dec()` + `crypt_cbc()`.
|
||||
* PKCS12:
|
||||
* In practice: 2DES or 3DES in CBC mode with PKCS7 padding, decrypt only
|
||||
(when called from pkparse).
|
||||
* In principle: any cipher-mode (default padding), passed an
|
||||
`mbedtls_cipher_type_t` as an argument, no documented restriction.
|
||||
* Cipher, generically, selected from ASN.1 or function parameters;
|
||||
no documented restriction but in practice TODO (inc. padding and
|
||||
en/decrypt, look at standards and tests)
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: `cipher.h` exposed through API.
|
||||
* Functions called: `setup`, `setkey`, `set_iv`, `reset`, `update`, `finish` (in sequence, once).
|
||||
* PKCS5 (PBES2, `mbedtls_pkcs5_pbes2()`):
|
||||
* 3DES or DES in CBC mode with PKCS7 padding, both encrypt and decrypt.
|
||||
* Note: could also be AES in the future, see #7038.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Functions called: `setup`, `setkey`, `crypt`.
|
||||
* CTR\_DRBG:
|
||||
* AES in ECB mode, encrypt only.
|
||||
* Currently using low-level non-generic API (`aes.h`).
|
||||
* Unconditional dependency on `AES_C` in `check_config.h`.
|
||||
* Functions called: `setkey_enc`, `crypt_ecb`.
|
||||
* CCM:
|
||||
* AES, Camellia or Aria in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || CAMELLIA_C || ARIA_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* CMAC:
|
||||
* AES or DES in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || DES_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* GCM:
|
||||
* AES, Camellia or Aria in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || CAMELLIA_C || ARIA_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* NIST\_KW:
|
||||
* AES in ECB mode, both encryt and decrypt.
|
||||
* Unconditional dependency on `AES_C || DES_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Note: `cipher.h` exposed through API.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* Cipher:
|
||||
* potentially any cipher/AEAD in any mode and any direction
|
||||
|
||||
Note: PSA cipher is built on Cipher, but PSA AEAD directly calls the underlying AEAD modules (GCM, CCM, ChachaPoly).
|
||||
|
||||
### Difficulties
|
||||
|
||||
@ -263,12 +319,72 @@ These problems are easily solvable.
|
||||
* We can make names and HMAC optional. The mixed-domain hash interface won't be the full `MBEDTLS_MD_C` but a subset.
|
||||
* We can optimize `md.c` without making API changes to `md.h`.
|
||||
|
||||
### Scope reductions and priorities for 3.x
|
||||
|
||||
This section documents things that we chose to temporarily exclude from the scope in the 3.x branch (which will eventually be in scope again after 4.0) as well as things we chose to prioritize if we don't have time to support everything.
|
||||
|
||||
#### Don't support PK, X.509 and TLS without `MBEDTLS_USE_PSA_CRYPTO`
|
||||
|
||||
We do not need to support driver-only hashes and ciphers in PK. X.509 and TLS without `MBEDTLS_USE_PSA_CRYPTO`. Users who want to take full advantage of drivers will need to enabled this macro.
|
||||
|
||||
Note that this applies to TLS 1.3 as well, as some uses of hashes and all uses of ciphers there are common with TLS 1.2, hence governed by `MBEDTLS_USE_PSA_CRYPTO`, see [this macro's extended documentation](../../docs/use-psa-crypto.html).
|
||||
|
||||
This will go away naturally in 4.0 when this macros is not longer an option (because it's always on).
|
||||
|
||||
#### Don't support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`
|
||||
|
||||
We generally don't really support builds with `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`. For example, both `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_SSL_PROTO_TLS1_3` require `MBEDTLS_PSA_CRYPTO_C`, while in principle they should only require `MBEDTLS_PSA_CRYPTO_CLIENT`.
|
||||
|
||||
Considering this existing restriction which we do not plan to lift before 4.0, it is acceptable driver-only hashes and cipher support to have the same restriction in 3.x.
|
||||
|
||||
It is however desirable for the design to keep support for `MBEDTLS_PSA_CRYPTO_CLIENT` in mind, in order to avoid making it more difficult to add in the future.
|
||||
|
||||
#### For cipher: prioritize constrained devices and modern TLS
|
||||
|
||||
The primary target is a configuration like TF-M's medium profile, plus TLS with only AEAD ciphersuites.
|
||||
|
||||
This excludes things like:
|
||||
- Support for encrypted PEM, PKCS5 and PKCS12 encryption, and PKCS8 encrypted keys in PK parse. (Not widely used on highly constrained devices.)
|
||||
- Support for NIST-KW. (Same justification.)
|
||||
- Support for CMAC. (Same justification, plus can be directly accelerated.)
|
||||
- Support for CBC ciphersuites in TLS. (They've been recommended against for a while now.)
|
||||
|
||||
### Dual-dispatch for block cipher primitives
|
||||
|
||||
Considering the priorities stated above, initially we want to support GCM, CCM and CTR-DRBG. All three of them use the block cipher primitive only in the encrypt direction. Currently, GCM and CCM use the Cipher layer in order to work with AES, Aria and Camellia (DES is excluded by the standards due to its smaller block size) and CTR-DRBG directly uses the low-level API from `aes.h`. In all cases, access to the "block cipher primitive" is done by using "ECB mode" (which for both Cipher and `aes.h` only allows a single block, contrary to PSA which implements actual ECB mode).
|
||||
|
||||
The two AEAD modes, GCM and CCM, have very similar needs and positions in the stack, strongly suggesting using the same design for both. On the other hand, there are a number of differences between CTR-DRBG and them.
|
||||
- CTR-DRBG only uses AES (and there is no plan to extend it to other block ciphers at the moment), while GCM and CCM need to work with 3 block ciphers already.
|
||||
- CTR-DRBG holds a special position in the stack: most users don't care about it per se, they only care about getting random numbers - in fact PSA users don't even need to know what DRBG is used. In particular, no part of the stack is asking questions like "is CTR-DRBG-AES available?" - an RNG needs to be available and that's it - contrary to similar questions about AES-GCM etc. which are asked for example by TLS.
|
||||
|
||||
So, it makes sense to use different designs for CTR-DRBG on one hand, and GCM/CCM on the other hand:
|
||||
- CTR-DRBG can just check if `AES_C` is present and "fall back" to PSA if not.
|
||||
- GCM and CCM need an common abstraction layer that allows:
|
||||
- Using AES, Aria or Camellia in a uniform way.
|
||||
- Dispatching to built-in or driver.
|
||||
|
||||
The abstraction layer used by GCM and CCM may either be a new internal module, or a subset of the existing Cipher API, extended with the ability to dispatch to a PSA driver.
|
||||
|
||||
Reasons for making this layer's API a subset of the existing Cipher API:
|
||||
- No need to design, implement and test a new module. (Will need to test the new subset though, as well as the extended behaviour.)
|
||||
- No code change in GCM and CCM - only need to update dependencies.
|
||||
- No risk for code duplication between a potential new module and Cipher: source-level, and in in particular in builds that still have `CIPHER_C` enabled. (Compiled-code duplication could be avoided by excluding the new module in such builds, though.)
|
||||
- If want to support other users of Cipher later (such as NIST-KW, CMAC, PKCS5 and PKCS12), we can just extend dual-dispatch support to other modes/operations in Cipher and keep those extra modules unchanged as well.
|
||||
|
||||
Possible costs of re-using (a subset of) the existing Cipher API instead of defining a new one:
|
||||
- We carry over costs associated with `cipher_info_t` structures. (Currently the info structure is used for 3 things: (1) to check if the cipher is supported, (2) to check its block size, (3) because `setup()` requires it).
|
||||
- We carry over questionable implementation decisions, like dynamic allocation of context.
|
||||
|
||||
Those costs could be avoided by refactoring (parts of) Cipher, but that would probably mean either:
|
||||
- significant differences in how the `cipher.h` API is implemented between builds with the full Cipher or only a subset;
|
||||
- or more work to apply the simplifications to all of Cipher.
|
||||
|
||||
Prototyping both approaches showed better code size savings and cleaner code with a new internal module (see section "Internal "block cipher" abstraction (Cipher light)" below).
|
||||
|
||||
## Specification
|
||||
|
||||
### MD light
|
||||
|
||||
https://github.com/Mbed-TLS/mbedtls/pull/6474 implements part of this specification, but it's based on Mbed TLS 3.2, so it needs to be rewritten for 3.3.
|
||||
|
||||
#### Definition of MD light
|
||||
|
||||
MD light is a subset of `md.h` that implements the hash calculation interface described in ”[Designing an interface for hashes](#designing-an-interface-for-hashes)”. It is activated by `MBEDTLS_MD_LIGHT` in `mbedtls_config.h`.
|
||||
@ -378,7 +494,7 @@ int psa_can_do_hash(psa_algorithm_t hash_alg);
|
||||
|
||||
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA.
|
||||
|
||||
As a starting point, return 1 if PSA crypto has been initialized. This will be refined later (to return 1 if the [accelerator subsystem](https://github.com/Mbed-TLS/mbedtls/issues/6007) has been initialized).
|
||||
As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
|
||||
|
||||
Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
|
||||
|
||||
@ -398,31 +514,7 @@ Note that this assumes that an operation that has been started via PSA can be co
|
||||
|
||||
#### Error code conversion
|
||||
|
||||
After calling a PSA function, call `mbedtls_md_error_from_psa` to convert its status code. This function is currently defined in `hash_info.c`.
|
||||
|
||||
### Migration to MD light
|
||||
|
||||
#### Migration of modules that used to call MD and now do the legacy-or-PSA dance
|
||||
|
||||
Get rid of the case where `MBEDTLS_MD_C` is undefined. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of modules that used to call a low-level hash module and now do the legacy-or-PSA dance
|
||||
|
||||
Switch to calling MD (light) unconditionally. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of modules that call a low-level hash module
|
||||
|
||||
Switch to calling MD (light). Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of use-PSA mixed code
|
||||
|
||||
Instead of calling `hash_info.h` functions to obtain metadata, get it from `md.h`.
|
||||
|
||||
Optionally, code that currently tests on `MBEDTLS_USE_PSA_CRYPTO` just to determine whether to call MD or PSA to calculate hashes can switch to just having the MD variant.
|
||||
|
||||
#### Remove `legacy_or_psa.h`
|
||||
|
||||
It's no longer used.
|
||||
After calling a PSA function, MD light calls `mbedtls_md_error_from_psa` to convert its status code.
|
||||
|
||||
### Support all legacy algorithms in PSA
|
||||
|
||||
@ -461,10 +553,6 @@ static inline psa_algorithm_t psa_alg_of_md_info(
|
||||
|
||||
Work in progress on this conversion is at https://github.com/gilles-peskine-arm/mbedtls/tree/hash-unify-ids-wip-1
|
||||
|
||||
#### Get rid of the hash_info module
|
||||
|
||||
The hash_info module is redundant with MD light. Move `mbedtls_md_error_from_psa` to `md.c`, defined only when `MBEDTLS_MD_SOME_PSA` is defined. The rest is no longer used.
|
||||
|
||||
#### Unify HMAC with PSA
|
||||
|
||||
PSA has its own HMAC implementation. In builds with both `MBEDTLS_MD_C` and `PSA_WANT_ALG_HMAC` not fully provided by drivers, we should have a single implementation. Replace the one in `md.h` by calls to the PSA driver interface. This will also give mixed-domain modules access to HMAC accelerated directly by a PSA driver (eliminating the need to a HMAC interface in software if all supported hashes have an accelerator that includes HMAC support).
|
||||
@ -477,3 +565,52 @@ The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a l
|
||||
|
||||
* Compile-time dependencies: instead of checking `defined(MBEDTLS_PSA_CRYPTO_C)`, check `defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)`.
|
||||
* Implementers of `MBEDTLS_PSA_CRYPTO_CLIENT` will need to provide `psa_can_do_hash()` (or a more general function `psa_can_do`) alongside `psa_crypto_init()`. Note that at this point, it will become a public interface, hence we won't be able to change it at a whim.
|
||||
|
||||
### Internal "block cipher" abstraction (previously known as "Cipher light")
|
||||
|
||||
#### Definition
|
||||
|
||||
The new module is automatically enabled in `config_adjust_legacy_crypto.h` by modules that need
|
||||
it (namely: CCM, GCM) only when `CIPHER_C` is not available, or the new module
|
||||
is needed for PSA dispatch (see next section). Note: CCM and GCM currently
|
||||
depend on the full `CIPHER_C` (enforced by `check_config.h`); this hard
|
||||
dependency would be replaced by the above auto-enablement.
|
||||
|
||||
The following API functions are offered:
|
||||
```
|
||||
void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx);
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx);
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id);
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen);
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
```
|
||||
|
||||
The only supported ciphers are AES, ARIA and Camellia. They are identified by
|
||||
an `mbedtls_cipher_id_t` in the `setup()` function, because that's how they're
|
||||
identifed by callers (GCM/CCM).
|
||||
|
||||
#### Block cipher dual dispatch
|
||||
|
||||
Support for dual dispatch in the new internal module `block_cipher` is extremely similar to that in MD light.
|
||||
|
||||
A block cipher context contains either a legacy module's context (AES, ARIA, Camellia) or a PSA key identifier; it has a field indicating which one is in use. All fields are private.
|
||||
|
||||
The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
|
||||
|
||||
Support is determined at runtime using the new internal function
|
||||
```
|
||||
int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);
|
||||
```
|
||||
|
||||
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA. As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
|
||||
|
||||
Each function in the module needs to know whether to dispatch via PSA or legacy. All functions consult the context's `engine` field, except `setup()` which will set it according to the key type and the return value of `psa_can_do_cipher()` as discussed above.
|
||||
|
||||
Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress.
|
||||
|
||||
After calling a PSA function, `block_cipher` functions call `mbedtls_cipher_error_from_psa` to convert its status code.
|
||||
|
@ -1,284 +0,0 @@
|
||||
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.
|
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
450
docs/architecture/psa-thread-safety/psa-thread-safety.md
Normal file
450
docs/architecture/psa-thread-safety/psa-thread-safety.md
Normal file
@ -0,0 +1,450 @@
|
||||
# Thread safety of the PSA subsystem
|
||||
|
||||
Currently PSA Crypto API calls in Mbed TLS releases are not thread-safe. In Mbed TLS 3.6 we are planning to add a minimal support for thread-safety of the PSA Crypto API (see section [Strategy for 3.6](#strategy-for-36)).
|
||||
|
||||
In the [Design analysis](#design-analysis) section we analyse design choices. This discussion is not constrained to what is planned for 3.6 and considers future developments. It also leaves some questions open and discusses options that have been (or probably will be) rejected.
|
||||
|
||||
## Design analysis
|
||||
|
||||
This section explores possible designs and does not reflect what is currently implemented.
|
||||
|
||||
### 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 (excluding resource-management errors), 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.
|
||||
|
||||
* **Policy 1:** 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.
|
||||
* **Policy 2:** At most one driver entry point is active at any given time.
|
||||
|
||||
Combining the two we arrive at **Policy 3**:
|
||||
|
||||
* 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 short-term requirements
|
||||
|
||||
##### Summary of guarantees in the short term
|
||||
|
||||
When `psa_destroy_key` returns:
|
||||
|
||||
1. 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.
|
||||
2. 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.
|
||||
3. 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 particular, it is only acceptable for `psa_destroy_key` to block, when waiting for another thread to complete a PSA Cryptography API call that it had already started.
|
||||
|
||||
When `psa_destroy_key` is called on a key that is in use, guarantee 2. might be violated. (This is consistent with the requirement [“Correctness out of the box”](#correctness-out-of-the-box), as destroying a key while it's in use is undefined behavior.)
|
||||
|
||||
#### Key destruction long-term requirements
|
||||
|
||||
The [PSA Crypto API specification](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#key-destruction) mandates that implementations make a best effort to ensure that the key material cannot be recovered. In the long term, it would be good to guarantee that `psa_destroy_key` wipes all copies of the key material.
|
||||
|
||||
##### Summary of guarantees in the long term
|
||||
|
||||
When `psa_destroy_key` returns:
|
||||
|
||||
1. 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.
|
||||
2. 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.
|
||||
3. 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 particular, it is only acceptable for `psa_destroy_key` to block, when waiting for another thread to complete a PSA Cryptography API call that it had already started.
|
||||
4. 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 satisfy this security requirement in the future.
|
||||
|
||||
As opposed to the short term requirements, all the above guarantees hold even if `psa_destroy_key` is called on a key that is in use.
|
||||
|
||||
### 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.
|
||||
|
||||
Alternatively, we could use a dedicated indicator that the slot is occupied. The advantage of this is that no field of the `attr` structure would be needed to determine the slot state. This would be a clean separation between key attributes and slot state and `attr` could be treated exactly like key slot content. This would save code size and maintenance effort. The cost of it would be that each slot would need an extra field to indicate whether it is occupied.
|
||||
|
||||
##### 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 four states:
|
||||
|
||||
* EMPTY: no thread is currently accessing the slot, and no information is stored in the slot. Any thread is able to change the slot's state to FILLING and begin loading data.
|
||||
* FILLING: one thread is currently loading or creating material to fill the slot, this thread is responsible for the next state transition. Other threads cannot read the contents of a slot which is in FILLING.
|
||||
* FULL: the slot contains a key, and any thread is able to use the key after registering as a reader.
|
||||
* PENDING_DELETION: the key within the slot has been destroyed or marked for destruction, but at least one thread is still registered as a reader. No thread can register to read this slot. The slot must not be wiped until the last reader de-registers, wiping the slot by calling `psa_wipe_key_slot`.
|
||||
|
||||
To change `slot` to state `new_state`, a function must call `psa_slot_state_transition(slot, new_state)`.
|
||||
|
||||
A counter field within each slot keeps track of how many readers have registered. Library functions must call `psa_register_read` before reading the key data within a slot, and `psa_unregister_read` after they have finished operating.
|
||||
|
||||
Any call to `psa_slot_state_transition`, `psa_register_read` or `psa_unregister_read` must be performed by a thread which holds the global mutex.
|
||||
|
||||
##### Linearizability of the system
|
||||
|
||||
To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearizable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order.
|
||||
|
||||
The standard way of reasoning that this is the case is to identify a "linearization point" for each call, this is a single execution step where the function takes effect (this is usually a step in which the effects of the call become visible to other threads). If every call has a linearization point, the set of calls is equivalent to sequentially performing the calls in order of when their linearization point occurred.
|
||||
|
||||
We only require linearizability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a PSA_ERROR_INSUFFICIENT_MEMORY return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct.
|
||||
|
||||
We only access and modify a slot's state and reader count while we hold the global lock. This ensures the memory in which these fields are stored is correctly synchronized. It also ensures that the key data within the slot is synchronised where needed (the writer unlocks the mutex after filling the data, and any reader must lock the mutex before reading the data).
|
||||
|
||||
To help justify that our system is linearizable, here is a list of key slot state changing functions and their linearization points (for the sake of brevity not all failure cases are covered, but those cases are not complex):
|
||||
* `psa_wipe_key_slot, psa_register_read, psa_unregister_read, psa_slot_state_transition,` - These functions are all always performed under the global mutex, so they have no effects visible to other threads (this implies that they are linearizable).
|
||||
* `psa_get_empty_key_slot, psa_get_and_lock_key_slot_in_memory, psa_load_X_key_into_slot, psa_fail_key_creation` - These functions hold the mutex for all non-setup/finalizing code, their linearization points are the release of the mutex.
|
||||
* `psa_get_and_lock_key_slot` - If the key is already in a slot, the linearization point is the linearization point of the call to `psa_get_and_lock_key_slot_in_memory`. If the key is not in a slot and is loaded into one, the linearization point is the linearization point of the call to `psa_load_X_key_into_slot`.
|
||||
* `psa_start_key_creation` - From the perspective of other threads, the only effect of a successful call to this function is that the amount of usable resources decreases (a key slot which was usable is now unusable). Since we do not consider resource management as linearizable behaviour, when arguing for linearizability of the system we consider this function to have no visible effect to other threads.
|
||||
* `psa_finish_key_creation` - On a successful load, we lock the mutex and set the state of the slot to FULL, the linearization point is then the following unlock. On an unsuccessful load, the linearization point is when we return - no action we have performed has been made visible to another thread as the slot is still in a FILLING state.
|
||||
* `psa_destroy_key, psa_close_key, psa_purge_key` - As per the requirements, we need only argue for the case where the key is not in use here. The linearization point is the unlock after wiping the data and setting the slot state to EMPTY.
|
||||
* `psa_import_key, psa_copy_key, psa_generate_key, mbedtls_psa_register_se_key` - These functions call both `psa_start_key_creation` and `psa_finish_key_creation`, the linearization point of a successful call is the linearization point of the call to `psa_finish_key_creation`. The linearization point of an unsuccessful call is the linearization point of the call to `psa_fail_key_creation`.
|
||||
* `psa_key_derivation_output_key` - Same as above. If the operation object is in use by multiple threads, the behaviour need not be linearizable.
|
||||
|
||||
Library functions which operate on a slot will return `PSA_ERROR_BAD_STATE` if the slot is in an inappropriate state for the function at the linearization point.
|
||||
|
||||
##### Key slot state transition diagram
|
||||
|
||||

|
||||
|
||||
In the state transition diagram above, an arrow between two states `q1` and `q2` with label `f` indicates that if the state of a slot is `q1` immediately before `f`'s linearization point, it may be `q2` immediately after `f`'s linearization point.
|
||||
|
||||
##### Generating the key slot state transition diagram from source
|
||||
|
||||
To generate the state transition diagram in https://app.diagrams.net/, open the following url:
|
||||
|
||||
https://viewer.diagrams.net/?tags=%7B%7D&highlight=FFFFFF&edit=_blank&layers=1&nav=1&title=key-slot-state-transitions#R5Vxbd5s4EP4t%2B%2BDH5iAJcXms4ySbrdtNT7qX9MWHgGyrxcABHNv59SsM2EhgDBhs3PVL0CANoBl9fDMaMkC3i%2FWDb3jzz65F7AGUrPUAjQYQAqBh9ieSbGKJIqFYMPOplXTaC57pO0mEUiJdUosEXMfQde2QerzQdB2HmCEnM3zfXfHdpq7NX9UzZiQneDYNOy%2F9h1rhPJZqUN3Lfyd0Nk%2BvDBQ9PrMw0s7JkwRzw3JXGRG6G6Bb33XD%2BGixviV2NHnpvMTj7g%2Bc3d2YT5ywyoDv4H08%2Ffvxj9VX3XGGw5cf3o9PHxJjvBn2MnngAVRspm9o0Td2OIsO7%2F8aj1Mx0585U9B5bgQTnxgW8YP07Ksv9he1bOcn3KSTzm6c2Zc1hqs5DcmzZ5jRmRVzsegK4cJmLcAOjcCLjT6la2LtVGUnJZmnN%2BKHZJ0RJZP0QNwFCf0N65KclbXEYDuPTdqrjP0T0Txj%2BlRmJB4322neG4UdJHapYSMACowkzphjfYy8nbVM2wgCavIT5btLx4pmaCSxFpscf%2FNvcmrbeMk2Rutsv9Emba1puBvEjl8y8v2QqJGOOGiNwF36Jjnul6Hhz0hY0k%2BO%2BxGLW8V522Zshwtsl8p8YhshfePXfpFBkys8uZQ92UHXwYrgE%2FFzJ6Oya1VUpOo3euancWplJKiNpymnduttu0k4wQFhzgGXjk9mNAiJv13seX9kBhkbr%2BxlwK9Xm86cyEeZQxCfCaJlSRnafkxOLKhlRTqGPgnou%2FG61Re5khc93PZx8XCAR4XOVb56RADYvTOSq3CwXAQM0g2UVJ2zxAd4mt%2BkaoAwxJ1OA9KNLasA%2Ft3np28v14nevQNvvXXwTmBYysAwKIXhHdxLWbiXjsB9c%2FCGFcEb9Au8ec%2FJgWxl7D7yDugYrFO6mXE4LzAmU4Pak59kMzEZXofUdfoM2ema6SNkJ5ohp1Qc3x1%2B51%2FF94%2Fj8eOXh17DMFIuDMNyldderTjnt18u0Lm4kXAVIz3dfRlt3b2inUZ347tvj39%2BuU4b9Y7PqF3RmepRZbPotTmdSdNOx%2BgM7BWdgRJ7%2BWkyVAGLJmWs8G9BLCs3KsAq1FTMGkhQX5XrAEUgTfJ5yY5WyHXYFSdk4YWbLeEJbDfsMdlJF1Qfuc5OjXwuegOKXtTt48sNbhIwxaMuGjL1K98VYYwkpRijMDjg0QBEWawUZJAmqc1QRpYElGG%2BjgSX7DoFVow0U%2BrQYH41cVW6uE7Gmg%2FM7rKu8mCDWvEpRSvUegboKaKfgi3Npf%2B2RZaYbZwv51492dMcg6rm3FGvMEhWMecwitowb4MVQZHIoQ9ADPMBY5PplizPwzes82imSlL5fUGhPzjSX9bK9LOD%2BI6bLp7RUDYBfTA9%2B50sH%2Bkz%2Fvi0rha6CVsGFQO4lNEZjjWxXfNnhtTV0GDabkCiobVGeUtm8uyo%2BtFjf9A%2FtVEb6A%2BQxntZO1k1nr5CfC7sR0X74K3QzixwVwxrMzyz2zy9XBHw%2B5WnhyrkvATjhoAPDuVWzsQpUVGsUwhDFglC392cDl%2FtQGVvIW63jFsIpmVN4aOZdBmc6L47HN5wkNc9xsmX4LfHwKs%2BTB6Eu57AE6N3mcwa0gBnbaSCorO1uaqsZpJ7CtDrXKQjHouQVn7P4l2iIzwWl%2BrvhsfmyyOup9JFbo3gsegeC47bEvh1kUgsNGT7%2BxSXxrfW6BzsFV4iIbzFTesukCpkCSvG72153HXtRZQumlYiRF3YcmqLPqVZzC4ThIWzc5ZKrspbEzwMdbg1UTUtiHsNKwpoCitCPZfSXfFtMSMprufiQsLeAkprhVwRoECekbQVj%2FG7GF0UchXb9UxV%2FcehoQkMNYcTXBFO%2BhXVwQNJ%2BNpwAgWWonRXHlrsdrDA7XJpoFzQUyN9tKIeyeXoryNvXr5Q26jQ2H0P1y6IAXQhEMuT3pwlz55TOohNfcESIXHSeMcSbbNAGpahrMs6RBoS9XLVGbAS0NRNA7GnyV4F6PxNqBK6UaG0%2B6HyJwJ6qTIA6ijDze%2Bso%2BxSPoToZXqpfK3%2Fz9JLT3S5Hk%2FhRNNmX9%2B%2B338yHccr%2FIyqHfLGlZw1%2BiSzM%2BpWtRC2X0VqSKgew2JeqDLc4iOZqvaoW6HPVWJuEQOzXcOaeMQPIlxxwi0ZY%2Ffk1q%2Ba2Gp6XVI7pM4JakrLN66DGpaiQAuIiGVQGIie6Pxnq6CAl6wAqu9Cv9gXl1VT%2F1VL9%2Fa74OmW%2Brk2T%2Fnkbu57gsolw4KiqrUde0WnLBnW3P9fj7j7%2Fr%2BjoLv%2FAA%3D%3D
|
||||
|
||||
#### Destruction of a key in use
|
||||
|
||||
Problem: In [Key destruction long-term requirements](#key-destruction-long-term-requirements) we require that the key slot is destroyed (by `psa_wipe_key_slot`) even while it's in use (FILLING or with at least one reader).
|
||||
|
||||
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.
|
||||
|
||||
##### Mutex only
|
||||
|
||||
When calling `psa_wipe_key_slot` it is the callers responsibility to set the slot state to PENDING_DELETION first. For most functions this is a clean {FULL, !has_readers} -> PENDING_DELETION transition: psa_get_empty_key_slot, psa_get_and_lock_key_slot, psa_close_key, psa_purge_key.
|
||||
|
||||
`psa_wipe_all_key_slots` is only called from `mbedtls_psa_crypto_free`, here we will need to return an error as we won't be able to free the key store if a key is in use without compromising the state of the secure side. This is acceptable as an untrusted application cannot call `mbedtls_psa_crypto_free` in a crypto service. In a service integration, `mbedtls_psa_crypto_free` on the client cuts the communication with the crypto service. Also, this is the current behaviour.
|
||||
|
||||
`psa_destroy_key` registers as a reader, marks the slot as deleted, deletes persistent keys and opaque keys and unregisters before returning. This will free the key ID, but the slot might be still in use. This only works if drivers are protected by a mutex (and the persistent storage as well if needed). `psa_destroy_key` transfers to PENDING_DELETION as an intermediate state. The last reading operation will wipe the key slot upon unregistering. In case of volatile keys freeing up the ID while the slot is still in use does not provide any benefit and we don't need to do it.
|
||||
|
||||
These are serious limitations, but this can be implemented with mutexes only and arguably satisfies the [Key destruction short-term requirements](#key-destruction-short-term-requirements).
|
||||
|
||||
Variations:
|
||||
|
||||
1. As a first step the multipart operations would lock the keys for reading on setup and release on free
|
||||
2. In a later stage this would be improved by locking the keys on entry into multi-part API calls and released before exiting.
|
||||
|
||||
The second variant can't be implemented as a backward compatible improvement on the first as multipart operations that were successfully completed in the first case, would fail in the second. If we want to implement these incrementally, multipart operations in a multithreaded environment must be left unsupported in the first variant. This makes the first variant impractical (multipart operations returning an error in builds with multithreading enabled is not a behaviour that would be very useful to release).
|
||||
|
||||
We can't reuse the `lock_count` field to mark key slots deleted, as we still need to keep track the lock count while the slot is marked for deletion. This means that we will need to add a new field to key slots. This new field can be reused to indicate whether the slot is occupied (see section [Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied)). (There would be three states: deleted, occupied, empty.)
|
||||
|
||||
#### Condition variables
|
||||
|
||||
Clean UNUSED -> PENDING_DELETION transition works as before.
|
||||
|
||||
`psa_wipe_all_key_slots` and `psa_destroy_key` mark the slot as deleted and go to sleep until the slot has no registered readers. When waking up, they wipe the slot, and return.
|
||||
|
||||
If the slot is already marked as deleted the threads calling `psa_wipe_all_key_slots` and `psa_destroy_key` go to sleep until the deletion completes. To satisfy [Key destruction long-term requirements](#key-destruction-long-term-requirements) none of the threads may return from the call until the slot is deleted completely. This can be achieved by signalling them when the slot has already been wiped and ready for use, that is not marked for deletion anymore. To handle spurious wake-ups, these threads need to be able to tell whether the slot was already deleted. This is not trivial, because by the time the thread wakes up, theoretically the slot might be in any state. It might have been reused and maybe even marked for deletion again.
|
||||
|
||||
To resolve this, we can either:
|
||||
|
||||
1. Depend on the deletion marker. If the slot has been reused and is marked for deletion again, the threads keep waiting until the second deletion completes.
|
||||
2. Introduce a uuid (eg a global counter plus a slot ID), which is recorded by the thread waiting for deletion and checks whether it matches. If it doesn't, the function can return as the slot was already reallocated. If it does match, it can check whether it is still marked for deletion, if it is, the thread goes back to sleep, if it isn't, the function can return.
|
||||
|
||||
##### Platform abstraction
|
||||
|
||||
Introducing condition variables to the platform abstraction layer would be best done in a major version. If we can't wait until that, we will need to introduce a new compile time flag. Considering that this only will be needed on the PSA Crypto side and the upcoming split, it makes sense to make this flag responsible for the entire PSA Crypto threading support. Therefore if we want to keep the option open for implementing this in a backward compatible manner, we need to introduce and use this new flag already when implementing [Mutex only](#mutex-only). (If we keep the abstraction layer for mutexes the same, this shouldn't mean increase in code size and would mean only minimal effort on the porting side.)
|
||||
|
||||
#### Operation contexts
|
||||
|
||||
Concurrent access to the same operation context can compromise the crypto service for example if the operation context has a pointer (depending on the compiler and the platform, the pointer assignment may or may not be atomic). This violates the functional correctness requirement of the crypto service. (Concurrent calls to operations is undefined behaviour, but still should not compromise the CIA of the crypto service.)
|
||||
|
||||
If we want to protect against this in the library, operations will need a status field protected by a global mutex similarly to key slots. On entry, API calls would check the state and return an error if it is already ACTIVE. Otherwise they set it to ACTIVE and restore it to INACTIVE before returning.
|
||||
|
||||
Alternatively, protecting operation contexts can be left as the responsibility of the crypto service. The [PSA Crypto API Specification](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls) does not require the library to provide any protection in this case. A crypto service can easily add its own mutex in its operation structure wrapper (the same structure where it keeps track of which client connection owns that operation object).
|
||||
|
||||
#### Drivers
|
||||
|
||||
Each driver that hasn’t got the "thread_safe” property set has a dedicated mutex.
|
||||
|
||||
Implementing "thread_safe” drivers depends on the condition variable protection in the key store, as we must guarantee that the core never starts the destruction of a key while there are operations in progress on it.
|
||||
|
||||
Start with implementing threading for drivers without the "thread_safe” property (all drivers behave like the property wasn't set). Add "thread_safe" drivers at some point after the [Condition variables](#condition-variables) approach is implemented in the core.
|
||||
|
||||
##### Reentrancy
|
||||
|
||||
It is natural sometimes to want to perform cryptographic operations from a driver, for example calculating a hash as part of various other crypto primitives, or using a block cipher in a driver for a mode, etc. Also encrypting/authenticating communication with a secure element.
|
||||
|
||||
**Non-thread-safe drivers:**
|
||||
|
||||
A driver is non-thread-safe if the `thread-safe` property (see [Driver requirements](#driver-requirements)) is set to false.
|
||||
|
||||
In the non-thread-safe case we have these natural assumptions/requirements:
|
||||
1. Drivers don't call the core for any operation for which they provide an entry point
|
||||
2. The core doesn't hold the driver mutex between calls to entry points
|
||||
|
||||
With these, the only way of a deadlock is when we have several drivers and they have circular dependencies. That is, Driver A makes a call that is despatched to Driver B and upon executing that Driver B makes a call that is despatched to Driver A. For example Driver A does CCM calls Driver B to do CBC-MAC, which in turn calls Driver A to do AES. This example is pretty contrived and it is hard to find a more practical example.
|
||||
|
||||
Potential ways for resolving this:
|
||||
1. Non-thread-safe drivers must not call the core
|
||||
2. Provide a new public API that drivers can safely call
|
||||
3. Make the dispatch layer public for drivers to call
|
||||
4. There is a whitelist of core APIs that drivers can call. Drivers providing entry points to these must not make a call to the core when handling these calls. (Drivers are still allowed to call any core API that can't have a driver entry point.)
|
||||
|
||||
The first is too restrictive, the second and the third would require making it a stable API, and would likely increase the code size for a relatively rare feature. We are choosing the fourth as that is the most viable option.
|
||||
|
||||
**Thread-safe drivers:**
|
||||
|
||||
A driver is non-thread-safe if the `thread-safe` property (see [Driver requirements](#driver-requirements)) is set to true.
|
||||
|
||||
To make reentrancy in non-thread-safe drivers work, thread-safe drivers must not make a call to the core when handling a call that is on the non-thread-safe driver core API whitelist.
|
||||
|
||||
Thread-safe drivers have less guarantees from the core and need to implement more complex logic and we can reasonably expect them to be more flexible in terms of reentrancy as well. At this point it is hard to see what further guarantees would be useful and feasible. Therefore, we don't provide any further guarantees for now.
|
||||
|
||||
Thread-safe drivers must not make any assumption about the operation of the core beyond what is discussed in the [Reentrancy](#reentrancy) and [Driver requirements](#driver-requirements) sections.
|
||||
|
||||
#### Global data
|
||||
|
||||
PSA Crypto makes use of a `global_data` variable that will be accessible from multiple threads and needs to be protected. Any function accessing this variable (or its members) must take the corresponding lock first. Since `global_data` holds the RNG state, these will involve relatively expensive operations and therefore ideally `global_data` should be protected by its own, dedicated lock (different from the one protecting the key store).
|
||||
|
||||
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. Still, doing so is conceptually simpler and we probably will want to remove the lower level mutex in the long run, since the corresponding interface will be removed from the public API. The two mutexes are different and are always taken in the same order, there is no risk of deadlock.
|
||||
|
||||
The purpose of `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is very similar to the driver interface (and might even be added to it in the long run), therefore it makes sense to handle it the same way. In particular, we can use the `global_data` mutex to protect it as a default and when we implement the "thread_safe” property for drivers, we implement it for `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as well.
|
||||
|
||||
#### Implementation notes
|
||||
|
||||
Since we only have simple mutexes, locking the same mutex from the same thread is a deadlock. Therefore functions taking the global mutex must not be called while holding the same mutex. Functions taking the mutex will document this fact and the implications.
|
||||
|
||||
Releasing the mutex before a function call might introduce race conditions. Therefore might not be practical to take the mutex in low level access functions. If functions like that don't take the mutex, they need to rely on the caller to take it for them. These functions will document that the caller is required to hold the mutex.
|
||||
|
||||
To avoid performance degradation, functions must hold mutexes for as short time as possible. In particular, they must not start expensive operations (eg. doing cryptography) while holding the mutex.
|
||||
|
||||
## Strategy for 3.6
|
||||
|
||||
The goal is to provide viable threading support without extending the platform abstraction. (Condition variables should be added in 4.0.) This means that we will be relying on mutexes only.
|
||||
|
||||
- Key Store
|
||||
- Slot states are described in the [Slot states](#slot-states) section. They guarantee safe concurrent access to slot contents.
|
||||
- Slot states will be protected by a global mutex as described in the introduction of the [Global lock excluding slot content](#global-lock-excluding-slot-content) section.
|
||||
- Simple key destruction strategy as described in the [Mutex only](#mutex-only) section (variant 2).
|
||||
- The slot state and key attributes will be separated as described in the last paragraph of the [Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied) section.
|
||||
- The main `global_data` (the one in `psa_crypto.c`) shall be protected by its own mutex as described in the [Global data](#global-data) section.
|
||||
- The solution shall use the pre-existing `MBEDTLS_THREADING_C` threading abstraction. That is, the flag proposed in the [Platform abstraction](#platform-abstraction) section won't be implemented.
|
||||
- The core makes no additional guarantees for drivers. That is, Policy 1 in section [Driver requirements](#driver-requirements) applies.
|
@ -16,6 +16,7 @@ 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
|
||||
@ -28,6 +29,7 @@ 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
|
||||
@ -52,9 +54,21 @@ 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.
|
||||
- RSA: PKCS#1 v1.5 and v2.1 signature and encryption algorithms, RSA key types
|
||||
(for now, only crypto, no X.509 or TLS support).
|
||||
- AEADs:
|
||||
- GCM and CCM with AES, ARIA and Camellia key types
|
||||
- ChachaPoly with ChaCha20 Key type
|
||||
- Unauthenticated ciphers:
|
||||
- key types: AES, ARIA, Camellia, DES
|
||||
- modes: ECB, CBC, CTR, CFB, OFB, XTS
|
||||
|
||||
For each family listed above, all the mentioned alorithms/key types are also
|
||||
all the mechanisms that exist in PSA API.
|
||||
|
||||
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
|
||||
@ -62,18 +76,13 @@ 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
|
||||
------
|
||||
|
||||
It is possible to have all hash operations provided only by a driver.
|
||||
|
||||
More precisely:
|
||||
|
||||
- you can enable `PSA_WANT_ALG_SHA_256` without `MBEDTLS_SHA256_C`, provided
|
||||
you have `MBEDTLS_PSA_ACCEL_ALG_SHA_256` enabled;
|
||||
- and similarly for all supported hash algorithms: `MD5`, `RIPEMD160`,
|
||||
@ -92,6 +101,7 @@ considerations](#general-considerations) above.
|
||||
If you want to check at compile-time whether a certain hash algorithm is
|
||||
available in the present build of Mbed TLS, regardless of whether it's
|
||||
provided by a driver or built-in, you should use the following macros:
|
||||
|
||||
- for code that uses only the PSA Crypto API: `PSA_WANT_ALG_xxx` from
|
||||
`psa/crypto.h`;
|
||||
- for code that uses non-PSA crypto APIs: `MBEDTLS_MD_CAN_xxx` from
|
||||
@ -101,10 +111,12 @@ Elliptic-curve cryptography (ECC)
|
||||
---------------------------------
|
||||
|
||||
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, if:
|
||||
|
||||
- you have driver support for ECC public and using private keys (that is,
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY` and
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC` are enabled), and
|
||||
@ -113,6 +125,7 @@ More precisely, if:
|
||||
`MBEDTLS_PSA_ACCEL_ECC_xxx` macros is enabled as well);
|
||||
|
||||
then you can:
|
||||
|
||||
- enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C`, provided
|
||||
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled
|
||||
- enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C`, provided
|
||||
@ -121,6 +134,7 @@ then you can:
|
||||
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
|
||||
|
||||
In addition, if:
|
||||
|
||||
- none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`, `MBEDTLS_ECJPAKE_C` are enabled
|
||||
(see conditions above), and
|
||||
- you have driver support for all enabled ECC key pair operations - that is,
|
||||
@ -132,9 +146,11 @@ then you can also disable `MBEDTLS_ECP_C`. However, a small subset of it might
|
||||
still be included in the build, see limitations sub-section below.
|
||||
|
||||
In addition, if:
|
||||
- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below), and
|
||||
- support for RSA key types and algorithms is fully disabled, and
|
||||
- support for DH key types and the FFDH algorithm is either disabled, or
|
||||
|
||||
- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below),
|
||||
- and support for RSA key types and algorithms is either fully disabled or
|
||||
fully provided by a driver,
|
||||
- and support for DH key types and the FFDH algorithm is either disabled or
|
||||
fully provided by a driver,
|
||||
|
||||
then you can also disable `MBEDTLS_BIGNUM_C`.
|
||||
@ -142,6 +158,7 @@ then you can also disable `MBEDTLS_BIGNUM_C`.
|
||||
In such builds, all crypto operations via the PSA Crypto API will work as
|
||||
usual, as well as the PK, X.509 and TLS modules if `MBEDTLS_USE_PSA_CRYPTO` is
|
||||
enabled, with the following exceptions:
|
||||
|
||||
- direct calls to APIs from the disabled modules are not possible;
|
||||
- PK, X.509 and TLS will not support restartable ECC operations (see
|
||||
limitation sub-section below).
|
||||
@ -149,6 +166,7 @@ enabled, with the following exceptions:
|
||||
If you want to check at compile-time whether a certain curve is available in
|
||||
the present build of Mbed TLS, regardless of whether ECC is provided by a
|
||||
driver or built-in, you should use the following macros:
|
||||
|
||||
- for code that uses only the PSA Crypto API: `PSA_WANT_ECC_xxx` from
|
||||
`psa/crypto.h`;
|
||||
- for code that may also use non-PSA crypto APIs: `MBEDTLS_ECP_HAVE_xxx` from
|
||||
@ -164,6 +182,7 @@ automatically defined when enabling `MBEDTLS_PSA_P256M_DRIVER_ENABLED`.
|
||||
|
||||
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
|
||||
@ -237,6 +256,184 @@ The same holds for the associated algorithm:
|
||||
`[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_FFDH` allow builds accelerating FFDH and
|
||||
removing builtin support (i.e. `MBEDTLS_DHM_C`).
|
||||
|
||||
### Limitations
|
||||
Support for deterministic derivation of a DH keypair
|
||||
(i.e. `PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE`) is not supported.
|
||||
RSA
|
||||
---
|
||||
|
||||
It is possible for all RSA operations to be provided only by a driver.
|
||||
|
||||
More precisely, if:
|
||||
|
||||
- all the RSA algorithms that are enabled (`PSA_WANT_ALG_RSA_*`) are also
|
||||
accelerated (`MBEDTLS_PSA_ACCEL_ALG_RSA_*`),
|
||||
- and all the RSA key types that are enabled (`PSA_WANT_KEY_TYPE_RSA_*`) are
|
||||
also accelerated (`MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_*`),
|
||||
|
||||
then you can disable `MBEDTLS_RSA_C`, `MBEDTLS_PKCS1_V15` and
|
||||
`MBEDTLS_PKCS1_V21`, and RSA will still work in PSA Crypto.
|
||||
|
||||
### Limitations on RSA acceleration
|
||||
|
||||
Unlike other mechanisms, for now in configurations with driver-only RSA, only
|
||||
PSA Crypto works. In particular, PK, X.509 and TLS will _not_ work with
|
||||
driver-only RSA even if `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
Currently (early 2024) we don't have plans to extend this support. If you're
|
||||
interested in wider driver-only support for RSA, please let us know.
|
||||
|
||||
Ciphers (unauthenticated and AEAD)
|
||||
----------------------------------
|
||||
|
||||
It is possible to have all ciphers and AEAD operations provided only by a
|
||||
driver. More precisely, for each desired combination of key type and
|
||||
algorithm/mode you can:
|
||||
|
||||
- Enable desired PSA key type(s):
|
||||
- `PSA_WANT_KEY_TYPE_AES`,
|
||||
- `PSA_WANT_KEY_TYPE_ARIA`,
|
||||
- `PSA_WANT_KEY_TYPE_CAMELLIA`,
|
||||
- `PSA_WANT_KEY_TYPE_CHACHA20`,
|
||||
- `PSA_WANT_KEY_TYPE_DES`.
|
||||
- Enable desired PSA algorithm(s):
|
||||
- Unauthenticated ciphers modes:
|
||||
- `PSA_WANT_ALG_CBC_NO_PADDING`,
|
||||
- `PSA_WANT_ALG_CBC_PKCS7`,
|
||||
- `PSA_WANT_ALG_CCM_STAR_NO_TAG`,
|
||||
- `PSA_WANT_ALG_CFB`,
|
||||
- `PSA_WANT_ALG_CTR`,
|
||||
- `PSA_WANT_ALG_ECB_NO_PADDING`,
|
||||
- `PSA_WANT_ALG_OFB`,
|
||||
- `PSA_WANT_ALG_STREAM_CIPHER`.
|
||||
- AEADs:
|
||||
- `PSA_WANT_ALG_CCM`,
|
||||
- `PSA_WANT_ALG_GCM`,
|
||||
- `PSA_WANT_ALG_CHACHA20_POLY1305`.
|
||||
- Enable `MBEDTLS_PSA_ACCEL_[KEY_TYPE_xxx|ALG_yyy]` symbol(s) which correspond
|
||||
to the `PSA_WANT_KEY_TYPE_xxx` and `PSA_WANT_ALG_yyy` of the previous steps.
|
||||
- Disable builtin support of key types:
|
||||
- `MBEDTLS_AES_C`,
|
||||
- `MBEDTLS_ARIA_C`,
|
||||
- `MBEDTLS_CAMELLIA_C`,
|
||||
- `MBEDTLS_DES_C`,
|
||||
- `MBEDTLS_CHACHA20_C`.
|
||||
and algorithms/modes:
|
||||
- `MBEDTLS_CBC_C`,
|
||||
- `MBEDTLS_CFB_C`,
|
||||
- `MBEDTLS_CTR_C`,
|
||||
- `MBEDTLS_OFB_C`,
|
||||
- `MBEDTLS_XTS_C`,
|
||||
- `MBEDTLS_CCM_C`,
|
||||
- `MBEDTLS_GCM_C`,
|
||||
- `MBEDTLS_CHACHAPOLY_C`,
|
||||
- `MBEDTLS_NULL_CIPHER`.
|
||||
|
||||
Once a key type and related algorithm are accelerated, all the PSA Crypto APIs
|
||||
will work, as well as X.509 and TLS (with `MBEDTLS_USE_PSA_CRYPTO` enabled) but
|
||||
some non-PSA APIs will be absent or have reduced functionality, see
|
||||
[Restrictions](#restrictions) for details.
|
||||
|
||||
### Restrictions
|
||||
|
||||
- If an algorithm other than CCM and GCM (see
|
||||
["Partial acceleration for CCM/GCM"](#partial-acceleration-for-ccmgcm) below)
|
||||
is enabled but not accelerated, then all key types that can be used with it
|
||||
will need to be built-in.
|
||||
- If a key type is enabled but not accelerated, then all algorithms that can be
|
||||
used with it will need to be built-in.
|
||||
|
||||
Some legacy modules can't take advantage of PSA drivers yet, and will either
|
||||
need to be disabled, or have reduced features when the built-in implementations
|
||||
of some ciphers are removed:
|
||||
|
||||
- `MBEDTLS_NIST_KW_C` needs built-in AES: it must be disabled when
|
||||
`MBEDTLS_AES_C` is disabled.
|
||||
- `MBEDTLS_CMAC_C` needs built-in AES/DES: it must be disabled when
|
||||
`MBEDTLS_AES_C` and `MBEDTLS_DES_C` are both disabled. When only one of them
|
||||
is enabled, then only the corresponding cipher will be available at runtime
|
||||
for use with `mbedtls_cipher_cmac_xxx`. (Note: if there is driver support for
|
||||
CMAC and all compatible key types, then `PSA_WANT_ALG_CMAC` can be enabled
|
||||
without `MBEDTLS_CMAC_C` and CMAC will be usable with `psa_max_xxx` APIs.)
|
||||
- `MBEDTLS_CIPHER_C`: the `mbedtls_cipher_xxx()` APIs will only work with
|
||||
ciphers that are built-in - that is, both the underlying cipher
|
||||
(eg `MBEDTLS_AES_C`) and the mode (eg `MBEDTLS_CIPHER_MODE_CBC` or
|
||||
`MBEDTLS_GCM_C`).
|
||||
- `MBEDTLS_PKCS5_C`: encryption/decryption (PBES2, PBE) will only work with
|
||||
ciphers that are built-in.
|
||||
- PEM decryption will only work with ciphers that are built-in.
|
||||
- PK parse will only be able to parse encrypted keys using built-in ciphers.
|
||||
|
||||
Note that if you also disable `MBEDTLS_CIPHER_C`, there will be additional
|
||||
restrictions, see [Disabling `MBEDTLS_CIPHER_C`](#disabling-mbedtls_cipher_c).
|
||||
|
||||
### Legacy <-> PSA matching
|
||||
|
||||
Note that the relationship between legacy (i.e. `MBEDTLS_xxx_C`) and PSA
|
||||
(i.e. `PSA_WANT_xxx`) symbols is not always 1:1. For example:
|
||||
|
||||
- ECB mode is always enabled in the legacy configuration for each key type that
|
||||
allows it (AES, ARIA, Camellia, DES), whereas it must be explicitly enabled
|
||||
in PSA with `PSA_WANT_ALG_ECB_NO_PADDING`.
|
||||
- In the legacy API, `MBEDTLS_CHACHA20_C` enables the ChaCha20 stream cipher, and
|
||||
enabling `MBEDTLS_CHACHAPOLY_C` also enables the ChaCha20-Poly1305 AEAD. In the
|
||||
PSA API, you need to enable `PSA_KEY_TYPE_CHACHA20` for both, plus
|
||||
`PSA_ALG_STREAM_CIPHER` or `PSA_ALG_CHACHA20_POLY1305` as desired.
|
||||
- The legacy symbol `MBEDTLS_CCM_C` adds support for both cipher and AEAD,
|
||||
whereas in PSA there are 2 different symbols: `PSA_WANT_ALG_CCM_STAR_NO_TAG`
|
||||
and `PSA_WANT_ALG_CCM`, respectively.
|
||||
|
||||
### Partial acceleration for CCM/GCM
|
||||
|
||||
[This section depends on #8598 so it might be updated while that PR progresses.]
|
||||
|
||||
In case legacy CCM/GCM algorithms are enabled, it is still possible to benefit
|
||||
from PSA acceleration of the underlying block cipher by enabling support for
|
||||
ECB mode (`PSA_WANT_ALG_ECB_NO_PADDING` + `MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING`)
|
||||
together with desired key type(s) (`PSA_WANT_KEY_TYPE_[AES|ARIA|CAMELLIA]` +
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_[AES|ARIA|CAMELLIA]`).
|
||||
|
||||
In such configurations it is possible to:
|
||||
|
||||
- Use CCM and GCM via the PSA Crypto APIs.
|
||||
- Use CCM and GCM via legacy functions `mbedtls_[ccm|gcm]_xxx()` (but not the
|
||||
legacy functions `mbedtls_cipher_xxx()`).
|
||||
- Disable legacy key types (`MBEDTLS_[AES|ARIA|CAMELLIA]_C`) if there is no
|
||||
other dependency requiring them.
|
||||
|
||||
ChaChaPoly has no such feature, so it requires full acceleration (key type +
|
||||
algorithm) in order to work with a driver.
|
||||
|
||||
### CTR-DRBG
|
||||
|
||||
The legacy CTR-DRBG module (enabled by `MBEDTLS_CTR_DRBG_C`) can also benefit
|
||||
from PSA acceleration if both of the following conditions are met:
|
||||
|
||||
- The legacy AES module (`MBEDTLS_AES_C`) is not enabled and
|
||||
- AES is supported on the PSA side together with ECB mode, i.e.
|
||||
`PSA_WANT_KEY_TYPE_AES` + `PSA_WANT_ALG_ECB_NO_PADDING`.
|
||||
|
||||
### Disabling `MBEDTLS_CIPHER_C`
|
||||
|
||||
It is possible to save code size by disabling MBEDTLS_CIPHER_C when all of the
|
||||
following conditions are met:
|
||||
|
||||
- The application is not using the `mbedtls_cipher_` API.
|
||||
- In PSA, all unauthenticated (that is, non-AEAD) ciphers are either disabled or
|
||||
fully accelerated (that is, all compatible key types are accelerated too).
|
||||
- Either TLS is disabled, or `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
- `MBEDTLS_NIST_KW` is disabled.
|
||||
- `MBEDTLS_CMAC_C` is disabled. (Note: support for CMAC in PSA can be provided by
|
||||
a driver.)
|
||||
|
||||
In such a build, everything will work as usual except for the following:
|
||||
|
||||
- Encryption/decryption functions from the PKCS5 and PKCS12 module will not be
|
||||
available (only key derivation functions).
|
||||
- Parsing of PKCS5- or PKCS12-encrypted keys in PK parse will fail.
|
||||
|
||||
Note: AEAD ciphers (CCM, GCM, ChachaPoly) do not have a dependency on
|
||||
MBEDTLS_CIPHER_C even when using the built-in implementations.
|
||||
|
||||
If you also have some ciphers fully accelerated and the built-ins removed, see
|
||||
[Restrictions](#restrictions) for restrictions related to removing the built-ins.
|
||||
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@ Migrating to an auto generated psa_crypto_driver_wrappers.h file
|
||||
This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.h 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).
|
||||
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.md).
|
||||
|
||||
## Introduction
|
||||
|
||||
|
1349
docs/psa-transition.md
Normal file
1349
docs/psa-transition.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,5 +7,5 @@
|
||||
# expose it.
|
||||
|
||||
- type: exact
|
||||
from_url: /projects/api/en/latest/$rest
|
||||
to_url: /projects/api/en/development/
|
||||
from_url: /projects/api/en/latest/*
|
||||
to_url: /projects/api/en/development/:splat
|
||||
|
@ -155,6 +155,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
*
|
||||
@ -173,6 +174,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
@ -592,6 +594,7 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief Internal AES block decryption function. This is only
|
||||
* exposed to allow overriding it using see
|
||||
@ -607,6 +610,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
|
@ -98,6 +98,7 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
*
|
||||
@ -116,6 +117,7 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
|
||||
int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief This function performs an ARIA single-block encryption or
|
||||
|
@ -632,10 +632,10 @@ void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name);
|
||||
/** \} name Functions to parse ASN.1 data structures */
|
||||
/** \} addtogroup asn1_module */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
#endif /* asn1.h */
|
||||
|
76
include/mbedtls/block_cipher.h
Normal file
76
include/mbedtls/block_cipher.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \file block_cipher.h
|
||||
*
|
||||
* \brief Internal abstraction layer.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BLOCK_CIPHER_H
|
||||
#define MBEDTLS_BLOCK_CIPHER_H
|
||||
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#include "mbedtls/aes.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
#include "mbedtls/aria.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
#include "mbedtls/camellia.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include "psa/crypto_types.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_BLOCK_CIPHER_ID_NONE = 0, /**< Unset. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_AES, /**< The AES cipher. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_ARIA, /**< The Aria cipher. */
|
||||
} mbedtls_block_cipher_id_t;
|
||||
|
||||
/**
|
||||
* Used internally to indicate whether a context uses legacy or PSA.
|
||||
*
|
||||
* Internal use only.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY = 0,
|
||||
MBEDTLS_BLOCK_CIPHER_ENGINE_PSA,
|
||||
} mbedtls_block_cipher_engine_t;
|
||||
|
||||
typedef struct {
|
||||
mbedtls_block_cipher_id_t MBEDTLS_PRIVATE(id);
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
mbedtls_block_cipher_engine_t MBEDTLS_PRIVATE(engine);
|
||||
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psa_key_id);
|
||||
#endif
|
||||
union {
|
||||
unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
mbedtls_aria_context MBEDTLS_PRIVATE(aria);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
mbedtls_camellia_context MBEDTLS_PRIVATE(camellia);
|
||||
#endif
|
||||
} MBEDTLS_PRIVATE(ctx);
|
||||
} mbedtls_block_cipher_context_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_H */
|
@ -62,6 +62,27 @@
|
||||
#define MBEDTLS_ARCH_IS_X86
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
|
||||
(defined(_M_ARM64) || defined(_M_ARM64EC))
|
||||
#define MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64
|
||||
#endif
|
||||
|
||||
/* This is defined if the architecture is Armv8-A, or higher */
|
||||
#if !defined(MBEDTLS_ARCH_IS_ARMV8_A)
|
||||
#if defined(__ARM_ARCH) && defined(__ARM_ARCH_PROFILE)
|
||||
#if (__ARM_ARCH >= 8) && (__ARM_ARCH_PROFILE == 'A')
|
||||
/* GCC, clang, armclang and IAR */
|
||||
#define MBEDTLS_ARCH_IS_ARMV8_A
|
||||
#endif
|
||||
#elif defined(__ARM_ARCH_8A)
|
||||
/* Alternative defined by clang */
|
||||
#define MBEDTLS_ARCH_IS_ARMV8_A
|
||||
#elif defined(_M_ARM64) || defined(_M_ARM64EC)
|
||||
/* MSVC ARM64 is at least Armv8.0-A */
|
||||
#define MBEDTLS_ARCH_IS_ARMV8_A
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
@ -81,6 +81,7 @@ int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief Perform a CAMELLIA key schedule operation for decryption.
|
||||
*
|
||||
@ -96,6 +97,7 @@ int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
|
||||
int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
#include "mbedtls/block_cipher.h"
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_CCM_DECRYPT 0
|
||||
#define MBEDTLS_CCM_ENCRYPT 1
|
||||
#define MBEDTLS_CCM_STAR_DECRYPT 2
|
||||
@ -80,7 +84,11 @@ typedef struct mbedtls_ccm_context {
|
||||
#MBEDTLS_CCM_DECRYPT or
|
||||
#MBEDTLS_CCM_STAR_ENCRYPT or
|
||||
#MBEDTLS_CCM_STAR_DECRYPT. */
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
|
||||
#else
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
#endif
|
||||
int MBEDTLS_PRIVATE(state); /*!< Working value holding context's
|
||||
state. Used for chunked data input */
|
||||
}
|
||||
@ -501,7 +509,7 @@ int mbedtls_ccm_update(mbedtls_ccm_context *ctx,
|
||||
int mbedtls_ccm_finish(mbedtls_ccm_context *ctx,
|
||||
unsigned char *tag, size_t tag_len);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
|
||||
/**
|
||||
* \brief The CCM checkup routine.
|
||||
*
|
||||
|
@ -153,7 +153,9 @@
|
||||
#endif /* not all curves accelerated */
|
||||
#endif /* some curve accelerated */
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \
|
||||
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_AES) && \
|
||||
defined(PSA_WANT_ALG_ECB_NO_PADDING)))
|
||||
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -171,6 +173,36 @@
|
||||
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) && defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_NO_PADDING cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_CBC_PKCS7)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_PKCS7 cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(PSA_WANT_ALG_ECB_NO_PADDING)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_ECB_NO_PADDING cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(PSA_WANT_KEY_TYPE_DES)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_KEY_TYPE_DES cannot be defined simultaneously"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_CBC cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_XTS cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_DES_C cannot be defined simultaneously"
|
||||
#endif
|
||||
#if defined(MBEDTLS_NIST_KW_C)
|
||||
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_NIST_KW_C cannot be defined simultaneously"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
|
||||
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
|
||||
#endif
|
||||
@ -193,6 +225,15 @@
|
||||
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) && !defined(MBEDTLS_ASN1_WRITE_C)
|
||||
#error "MBEDTLS_PK_C with MBEDTLS_USE_PSA_CRYPTO needs MBEDTLS_ASN1_WRITE_C for ECDSA signature"
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && !defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#error "MBEDTLS_PK_C with MBEDTLS_USE_PSA_CRYPTO needs MBEDTLS_ASN1_PARSE_C for ECDSA verification"
|
||||
#endif
|
||||
#endif /* MBEDTLS_PK_C && MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_ECJPAKE_C) && \
|
||||
( !defined(MBEDTLS_ECP_C) || \
|
||||
!( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) )
|
||||
@ -219,7 +260,7 @@
|
||||
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
|
||||
#if defined(MBEDTLS_ECP_LIGHT) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
|
||||
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
|
||||
@ -233,22 +274,13 @@
|
||||
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \
|
||||
!defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) )
|
||||
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
|
||||
#error "MBEDTLS_ECP_C defined (or a subset enabled), but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS12_C) && !defined(MBEDTLS_CIPHER_C)
|
||||
#error "MBEDTLS_PKCS12_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS5_C) && \
|
||||
!defined(MBEDTLS_CIPHER_C)
|
||||
#error "MBEDTLS_PKCS5_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
/* Helpers for hash dependencies, will be undefined at the end of the file */
|
||||
/* Do SHA-256, 384, 512 to cover Entropy and TLS. */
|
||||
#if defined(MBEDTLS_SHA256_C) || \
|
||||
@ -292,21 +324,15 @@
|
||||
#endif
|
||||
#undef MBEDTLS_HAS_MEMSAN
|
||||
|
||||
#if defined(MBEDTLS_CCM_C) && ( \
|
||||
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
|
||||
#if defined(MBEDTLS_CCM_C) && \
|
||||
!(defined(MBEDTLS_CCM_GCM_CAN_AES) || defined(MBEDTLS_CCM_GCM_CAN_ARIA) || \
|
||||
defined(MBEDTLS_CCM_GCM_CAN_CAMELLIA))
|
||||
#error "MBEDTLS_CCM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C)
|
||||
#error "MBEDTLS_CCM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C) && ( \
|
||||
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
|
||||
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C)
|
||||
#if defined(MBEDTLS_GCM_C) && \
|
||||
!(defined(MBEDTLS_CCM_GCM_CAN_AES) || defined(MBEDTLS_CCM_GCM_CAN_ARIA) || \
|
||||
defined(MBEDTLS_CCM_GCM_CAN_CAMELLIA))
|
||||
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -754,7 +780,8 @@
|
||||
#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_CIPHER_C )
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_HAVE_SOFT_BLOCK_MODE) && \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER) && !defined(MBEDTLS_CIPHER_C)
|
||||
#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -837,25 +864,24 @@
|
||||
#error "MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY defined on non-Aarch64 system"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && \
|
||||
defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
|
||||
#error "Must only define one of MBEDTLS_SHA256_USE_A64_CRYPTO_*"
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) && \
|
||||
defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
#error "Must only define one of MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \
|
||||
defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY)
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT) || \
|
||||
defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
#if !defined(MBEDTLS_SHA256_C)
|
||||
#error "MBEDTLS_SHA256_USE_A64_CRYPTO_* defined without MBEDTLS_SHA256_C"
|
||||
#error "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_* defined without MBEDTLS_SHA256_C"
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA256_PROCESS_ALT)
|
||||
#error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_A64_CRYPTO_*"
|
||||
#error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_*"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && \
|
||||
!defined(__aarch64__) && !defined(_M_ARM64)
|
||||
#error "MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY defined on non-Aarch64 system"
|
||||
#if defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY) && !defined(MBEDTLS_ARCH_IS_ARMV8_A)
|
||||
#error "MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY defined on non-Armv8-A system"
|
||||
#endif
|
||||
|
||||
/* TLS 1.3 requires separate HKDF parts from PSA,
|
||||
@ -936,7 +962,8 @@
|
||||
#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && !defined(MBEDTLS_CIPHER_C)
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && !(defined(MBEDTLS_CIPHER_C) || \
|
||||
defined(MBEDTLS_USE_PSA_CRYPTO))
|
||||
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -1028,7 +1055,8 @@
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TICKET_C) && \
|
||||
!( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) )
|
||||
!( defined(MBEDTLS_SSL_HAVE_CCM) || defined(MBEDTLS_SSL_HAVE_GCM) || \
|
||||
defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) )
|
||||
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
@ -1129,7 +1157,9 @@
|
||||
#error "MBEDTLS_SSL_RECORD_SIZE_LIMIT defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && !( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) )
|
||||
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && \
|
||||
!( defined(MBEDTLS_SSL_HAVE_CCM) || defined(MBEDTLS_SSL_HAVE_GCM) || \
|
||||
defined(MBEDTLS_SSL_HAVE_CHACHAPOLY) )
|
||||
#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
|
@ -480,7 +480,7 @@ static inline size_t mbedtls_cipher_info_get_key_bitlen(
|
||||
if (info == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return info->MBEDTLS_PRIVATE(key_bitlen) << MBEDTLS_KEY_BITLEN_SHIFT;
|
||||
return ((size_t) info->MBEDTLS_PRIVATE(key_bitlen)) << MBEDTLS_KEY_BITLEN_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,20 @@
|
||||
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
|
||||
/* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin
|
||||
* in PSA. */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||
(defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG))
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#endif
|
||||
|
||||
/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
|
||||
* This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
|
||||
*/
|
||||
@ -44,6 +58,202 @@
|
||||
#define MBEDTLS_MD_LIGHT
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
/*
|
||||
* - MBEDTLS_MD_CAN_xxx is defined if the md module can perform xxx.
|
||||
* - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA
|
||||
* (see below).
|
||||
* - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed
|
||||
* via PSA (see below).
|
||||
* - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed
|
||||
* via a direct legacy call (see below).
|
||||
*
|
||||
* The md module performs an algorithm via PSA if there is a PSA hash
|
||||
* accelerator and the PSA driver subsytem is initialized at the time the
|
||||
* operation is started, and makes a direct legacy call otherwise.
|
||||
*/
|
||||
|
||||
/* PSA accelerated implementations */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
|
||||
#define MBEDTLS_MD_CAN_MD5
|
||||
#define MBEDTLS_MD_MD5_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
|
||||
#define MBEDTLS_MD_CAN_SHA1
|
||||
#define MBEDTLS_MD_SHA1_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||
#define MBEDTLS_MD_CAN_SHA224
|
||||
#define MBEDTLS_MD_SHA224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#define MBEDTLS_MD_CAN_SHA256
|
||||
#define MBEDTLS_MD_SHA256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
#define MBEDTLS_MD_CAN_SHA384
|
||||
#define MBEDTLS_MD_SHA384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||
#define MBEDTLS_MD_CAN_SHA512
|
||||
#define MBEDTLS_MD_SHA512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
|
||||
#define MBEDTLS_MD_CAN_RIPEMD160
|
||||
#define MBEDTLS_MD_RIPEMD160_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224)
|
||||
#define MBEDTLS_MD_CAN_SHA3_224
|
||||
#define MBEDTLS_MD_SHA3_224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256)
|
||||
#define MBEDTLS_MD_CAN_SHA3_256
|
||||
#define MBEDTLS_MD_SHA3_256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384)
|
||||
#define MBEDTLS_MD_CAN_SHA3_384
|
||||
#define MBEDTLS_MD_SHA3_384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512)
|
||||
#define MBEDTLS_MD_CAN_SHA3_512
|
||||
#define MBEDTLS_MD_SHA3_512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/* Built-in implementations */
|
||||
#if defined(MBEDTLS_MD5_C)
|
||||
#define MBEDTLS_MD_CAN_MD5
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
#define MBEDTLS_MD_CAN_SHA1
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
#define MBEDTLS_MD_CAN_SHA224
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
#define MBEDTLS_MD_CAN_SHA256
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
#define MBEDTLS_MD_CAN_SHA384
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
#define MBEDTLS_MD_CAN_SHA512
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA3_C)
|
||||
#define MBEDTLS_MD_CAN_SHA3_224
|
||||
#define MBEDTLS_MD_CAN_SHA3_256
|
||||
#define MBEDTLS_MD_CAN_SHA3_384
|
||||
#define MBEDTLS_MD_CAN_SHA3_512
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_RIPEMD160_C)
|
||||
#define MBEDTLS_MD_CAN_RIPEMD160
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_MD_LIGHT */
|
||||
|
||||
/* BLOCK_CIPHER module can dispatch to PSA when:
|
||||
* - PSA is enabled and drivers have been initialized
|
||||
* - desired key type is supported on the PSA side
|
||||
* If the above conditions are not met, but the legacy support is enabled, then
|
||||
* BLOCK_CIPHER will dynamically fallback to it.
|
||||
*
|
||||
* In case BLOCK_CIPHER is defined (see below) the following symbols/helpers
|
||||
* can be used to define its capabilities:
|
||||
* - MBEDTLS_BLOCK_CIPHER_SOME_PSA: there is at least 1 key type between AES,
|
||||
* ARIA and Camellia which is supported through a driver;
|
||||
* - MBEDTLS_BLOCK_CIPHER_xxx_VIA_PSA: xxx key type is supported through a
|
||||
* driver;
|
||||
* - MBEDTLS_BLOCK_CIPHER_xxx_VIA_LEGACY: xxx key type is supported through
|
||||
* a legacy module (i.e. MBEDTLS_xxx_C)
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
|
||||
#define MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
|
||||
#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY
|
||||
#endif
|
||||
|
||||
/* Helpers to state that BLOCK_CIPHER module supports AES, ARIA and/or Camellia
|
||||
* block ciphers via either PSA or legacy. */
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_AES
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_ARIA
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* GCM_C and CCM_C can either depend on (in order of preference) BLOCK_CIPHER_C
|
||||
* or CIPHER_C. The former is auto-enabled when:
|
||||
* - CIPHER_C is not defined, which is also the legacy solution;
|
||||
* - BLOCK_CIPHER_SOME_PSA because in this case BLOCK_CIPHER can take advantage
|
||||
* of the driver's acceleration.
|
||||
*/
|
||||
#if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \
|
||||
(!defined(MBEDTLS_CIPHER_C) || defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA))
|
||||
#define MBEDTLS_BLOCK_CIPHER_C
|
||||
#endif
|
||||
|
||||
/* Helpers for GCM/CCM capabilities */
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_AES))
|
||||
#define MBEDTLS_CCM_GCM_CAN_AES
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_ARIA_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_ARIA))
|
||||
#define MBEDTLS_CCM_GCM_CAN_ARIA
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_CAMELLIA_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA))
|
||||
#define MBEDTLS_CCM_GCM_CAN_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_ECP_LIGHT is auto-enabled by the following symbols:
|
||||
* - MBEDTLS_ECP_C because now it consists of MBEDTLS_ECP_LIGHT plus functions
|
||||
* for curve arithmetic. As a consequence if MBEDTLS_ECP_C is required for
|
||||
@ -67,7 +277,7 @@
|
||||
#define MBEDTLS_ECP_LIGHT
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in MbedTLS version 3.5, while
|
||||
/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in Mbed TLS version 3.5, while
|
||||
* in previous version compressed points were automatically supported as long
|
||||
* as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward
|
||||
* compatibility, we auto-enable PK_PARSE_EC_COMPRESSED when these conditions
|
||||
@ -114,9 +324,9 @@
|
||||
#define MBEDTLS_PSA_CRYPTO_CLIENT
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/* The PK wrappers need pk_write functions to format RSA key objects
|
||||
* when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO,
|
||||
* and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). */
|
||||
/* The PK wrappers need pk_write/pk_parse functions to format RSA key objects
|
||||
* when they are dispatching to the PSA API. This happens under MBEDTLS_USE_PSA_CRYPTO,
|
||||
* and even under just MBEDTLS_PSA_CRYPTO_C in psa_crypto_rsa.c. */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C)
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
@ -180,4 +390,54 @@
|
||||
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||
#endif
|
||||
|
||||
/* Backwards compatibility for some macros which were renamed to reflect that
|
||||
* they are related to Armv8, not aarch64. */
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && \
|
||||
!defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
|
||||
#endif
|
||||
|
||||
/* Some internal helpers to determine which keys are availble. */
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
|
||||
#define MBEDTLS_SSL_HAVE_AES
|
||||
#endif
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ARIA_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ARIA))
|
||||
#define MBEDTLS_SSL_HAVE_ARIA
|
||||
#endif
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CAMELLIA_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_CAMELLIA))
|
||||
#define MBEDTLS_SSL_HAVE_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* Some internal helpers to determine which operation modes are availble. */
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING))
|
||||
#define MBEDTLS_SSL_HAVE_CBC
|
||||
#endif
|
||||
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_GCM_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM))
|
||||
#define MBEDTLS_SSL_HAVE_GCM
|
||||
#endif
|
||||
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CCM_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CCM))
|
||||
#define MBEDTLS_SSL_HAVE_CCM
|
||||
#endif
|
||||
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CHACHAPOLY_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CHACHA20_POLY1305))
|
||||
#define MBEDTLS_SSL_HAVE_CHACHAPOLY
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_HAVE_GCM) || defined(MBEDTLS_SSL_HAVE_CCM) || \
|
||||
defined(MBEDTLS_SSL_HAVE_CHACHAPOLY)
|
||||
#define MBEDTLS_SSL_HAVE_AEAD
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H */
|
||||
|
@ -685,20 +685,13 @@
|
||||
#if (defined(PSA_WANT_ALG_CTR) && !defined(MBEDTLS_PSA_ACCEL_ALG_CTR)) || \
|
||||
(defined(PSA_WANT_ALG_CFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_CFB)) || \
|
||||
(defined(PSA_WANT_ALG_OFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_OFB)) || \
|
||||
defined(PSA_WANT_ALG_ECB_NO_PADDING) || \
|
||||
(defined(PSA_WANT_ALG_CBC_NO_PADDING) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \
|
||||
(defined(PSA_WANT_ALG_CBC_PKCS7) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)) || \
|
||||
(defined(PSA_WANT_ALG_ECB_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)) || \
|
||||
(defined(PSA_WANT_ALG_CBC_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \
|
||||
(defined(PSA_WANT_ALG_CBC_PKCS7) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)) || \
|
||||
(defined(PSA_WANT_ALG_CMAC) && !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC))
|
||||
#define PSA_HAVE_SOFT_BLOCK_MODE 1
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_ALG_GCM) && !defined(MBEDTLS_PSA_ACCEL_ALG_GCM)) || \
|
||||
(defined(PSA_WANT_ALG_CCM) && !defined(MBEDTLS_PSA_ACCEL_ALG_CCM))
|
||||
#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
|
||||
@ -711,9 +704,7 @@
|
||||
#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_PBKDF2_CMAC)
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
|
||||
#define MBEDTLS_AES_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
@ -724,8 +715,7 @@
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_ARIA 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_AEAD)
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
|
||||
#define MBEDTLS_ARIA_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
@ -736,8 +726,7 @@
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_AEAD)
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
|
||||
#define MBEDTLS_CAMELLIA_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
@ -754,8 +743,15 @@
|
||||
#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DES */
|
||||
|
||||
#if defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||
#endif /* MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER */
|
||||
#endif /* PSA_WANT_ALG_STREAM_CIPHER */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
|
||||
#define MBEDTLS_CHACHA20_C
|
||||
#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */
|
||||
@ -771,10 +767,6 @@
|
||||
#define PSA_HAVE_SOFT_BLOCK_CIPHER 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||
#endif /* PSA_WANT_ALG_STREAM_CIPHER */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_MAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_MAC)
|
||||
#error "CBC-MAC is not yet supported via the PSA API in Mbed TLS."
|
||||
@ -784,8 +776,7 @@
|
||||
|
||||
#if defined(PSA_WANT_ALG_CMAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER) || \
|
||||
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
|
||||
#define MBEDTLS_CMAC_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */
|
||||
@ -848,11 +839,20 @@
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
|
||||
#define MBEDTLS_CCM_C
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
|
||||
#define MBEDTLS_CCM_C
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CCM_STAR_NO_TAG */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
|
@ -25,9 +25,11 @@
|
||||
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
|
||||
#define PSA_WANT_ALG_CCM 1
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
|
||||
#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
#endif /* MBEDTLS_CCM_C */
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C)
|
||||
@ -226,9 +228,12 @@
|
||||
|
||||
#if defined(MBEDTLS_CHACHA20_C)
|
||||
#define PSA_WANT_KEY_TYPE_CHACHA20 1
|
||||
#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
|
||||
/* ALG_STREAM_CIPHER requires CIPHER_C in order to be supported in PSA */
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||
#endif
|
||||
#if defined(MBEDTLS_CHACHAPOLY_C)
|
||||
#define PSA_WANT_ALG_CHACHA20_POLY1305 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
|
||||
@ -244,8 +249,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
|
||||
defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)
|
||||
#if (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
|
||||
defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)) && \
|
||||
defined(MBEDTLS_CIPHER_C)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#endif
|
||||
|
@ -65,6 +65,7 @@
|
||||
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
|
||||
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
|
||||
#undef MBEDTLS_SSL_EARLY_DATA
|
||||
#undef MBEDTLS_SSL_RECORD_SIZE_LIMIT
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
|
||||
|
@ -32,7 +32,14 @@
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
/* In case AES_C is defined then it is the primary option for backward
|
||||
* compatibility purposes. If that's not available, PSA is used instead */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#include "mbedtls/aes.h"
|
||||
#else
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
#include "entropy.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
@ -150,6 +157,13 @@ extern "C" {
|
||||
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
typedef struct mbedtls_ctr_drbg_psa_context {
|
||||
mbedtls_svc_key_id_t key_id;
|
||||
psa_cipher_operation_t operation;
|
||||
} mbedtls_ctr_drbg_psa_context;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The CTR_DRBG context structure.
|
||||
*/
|
||||
@ -175,7 +189,11 @@ typedef struct mbedtls_ctr_drbg_context {
|
||||
* This is the maximum number of requests
|
||||
* that can be made between reseedings. */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */
|
||||
#else
|
||||
mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Callbacks (Entropy)
|
||||
|
@ -120,7 +120,12 @@
|
||||
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
|
||||
|
||||
#if !defined(MBEDTLS_PRINTF_MS_TIME)
|
||||
#include <inttypes.h>
|
||||
#if !defined(PRId64)
|
||||
#define MBEDTLS_PRINTF_MS_TIME MBEDTLS_PRINTF_LONGLONG
|
||||
#else
|
||||
#define MBEDTLS_PRINTF_MS_TIME PRId64
|
||||
#endif
|
||||
#endif /* MBEDTLS_PRINTF_MS_TIME */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -225,7 +230,7 @@ void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
|
||||
const char *text, const mbedtls_mpi *X);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
#if defined(MBEDTLS_ECP_LIGHT)
|
||||
/**
|
||||
* \brief Print an ECP point to the debug output. This function is always
|
||||
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
|
||||
|
@ -1259,9 +1259,56 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/** \brief Set the public key in a key pair object.
|
||||
*
|
||||
* \note This function does not check that the point actually
|
||||
* belongs to the given group. Call mbedtls_ecp_check_pubkey()
|
||||
* on \p Q before calling this function to check that.
|
||||
*
|
||||
* \note This function does not check that the public key matches
|
||||
* the private key that is already in \p key, if any.
|
||||
* To check the consistency of the resulting key pair object,
|
||||
* call mbedtls_ecp_check_pub_priv() after setting both
|
||||
* the public key and the private key.
|
||||
*
|
||||
* \param grp_id The ECP group identifier.
|
||||
* \param key The key pair object. It must be initialized.
|
||||
* If its group has already been set, it must match \p grp_id.
|
||||
* If its group has not been set, it will be set to \p grp_id.
|
||||
* If the public key has already been set, it is overwritten.
|
||||
* \param Q The public key to copy. This must be a point on the
|
||||
* curve indicated by \p grp_id.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p key does not
|
||||
* match \p grp_id.
|
||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
|
||||
* the group is not implemented.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id,
|
||||
mbedtls_ecp_keypair *key,
|
||||
const mbedtls_ecp_point *Q);
|
||||
|
||||
/**
|
||||
* \brief This function reads an elliptic curve private key.
|
||||
*
|
||||
* \note This function does not set the public key in the
|
||||
* key pair object. Without a public key, the key pair object
|
||||
* cannot be used with operations that require the public key.
|
||||
* Call mbedtls_ecp_keypair_calc_public() to set the public
|
||||
* key from the private key. Alternatively, you can call
|
||||
* mbedtls_ecp_set_public_key() to set the public key part,
|
||||
* and then optionally mbedtls_ecp_check_pub_priv() to check
|
||||
* that the private and public parts are consistent.
|
||||
*
|
||||
* \note If a public key has already been set in the key pair
|
||||
* object, this function does not check that it is consistent
|
||||
* with the private key. Call mbedtls_ecp_check_pub_priv()
|
||||
* after setting both the public key and the private key
|
||||
* to make that check.
|
||||
*
|
||||
* \param grp_id The ECP group identifier.
|
||||
* \param key The destination key.
|
||||
* \param buf The buffer containing the binary representation of the
|
||||
@ -1299,6 +1346,32 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
|
||||
unsigned char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief This function exports an elliptic curve public key.
|
||||
*
|
||||
* \param key The public key.
|
||||
* \param format The point format. This must be either
|
||||
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
|
||||
* (For groups without these formats, this parameter is
|
||||
* ignored. But it still has to be either of the above
|
||||
* values.)
|
||||
* \param olen The address at which to store the length of
|
||||
* the output in Bytes. This must not be \c NULL.
|
||||
* \param buf The output buffer. This must be a writable buffer
|
||||
* of length \p buflen Bytes.
|
||||
* \param buflen The length of the output buffer \p buf in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
|
||||
* is too small to hold the point.
|
||||
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
|
||||
* or the export for the given group is not implemented.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key,
|
||||
int format, size_t *olen,
|
||||
unsigned char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief This function checks that the keypair objects
|
||||
* \p pub and \p prv have the same group and the
|
||||
@ -1323,16 +1396,48 @@ int mbedtls_ecp_check_pub_priv(
|
||||
const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
|
||||
/** \brief Calculate the public key from a private key in a key pair.
|
||||
*
|
||||
* \param key A keypair structure. It must have a private key set.
|
||||
* If the public key is set, it will be overwritten.
|
||||
* \param f_rng The RNG function. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c
|
||||
* NULL if \p f_rng doesn't need a context.
|
||||
*
|
||||
* \return \c 0 on success. The key pair object can be used for
|
||||
* operations that require the public key.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
|
||||
* error code on calculation failure.
|
||||
*/
|
||||
int mbedtls_ecp_keypair_calc_public(
|
||||
mbedtls_ecp_keypair *key,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
|
||||
/** \brief Query the group that a key pair belongs to.
|
||||
*
|
||||
* \param key The key pair to query.
|
||||
*
|
||||
* \return The group ID for the group registered in the key pair
|
||||
* object.
|
||||
* This is \c MBEDTLS_ECP_DP_NONE if no group has been set
|
||||
* in the key pair object.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id(
|
||||
const mbedtls_ecp_keypair *key);
|
||||
|
||||
/**
|
||||
* \brief This function exports generic key-pair parameters.
|
||||
*
|
||||
* Each of the output parameters can be a null pointer
|
||||
* if you do not need that parameter.
|
||||
*
|
||||
* \param key The key pair to export from.
|
||||
* \param grp Slot for exported ECP group.
|
||||
* It must point to an initialized ECP group.
|
||||
* It must either be null or point to an initialized ECP group.
|
||||
* \param d Slot for the exported secret value.
|
||||
* It must point to an initialized mpi.
|
||||
* It must either be null or point to an initialized mpi.
|
||||
* \param Q Slot for the exported public value.
|
||||
* It must point to an initialized ECP point.
|
||||
* It must either be null or point to an initialized ECP point.
|
||||
*
|
||||
* \return \c 0 on success,
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
|
||||
|
@ -24,6 +24,10 @@
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
#include "mbedtls/block_cipher.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MBEDTLS_GCM_ENCRYPT 1
|
||||
@ -46,7 +50,11 @@ extern "C" {
|
||||
* \brief The GCM context structure.
|
||||
*/
|
||||
typedef struct mbedtls_gcm_context {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
|
||||
#else
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
#endif
|
||||
uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */
|
||||
uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */
|
||||
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
|
||||
|
@ -2191,6 +2191,8 @@
|
||||
* Enable parsing and verification of X.509 certificates, CRLs and CSRS
|
||||
* signed with RSASSA-PSS (aka PKCS#1 v2.1).
|
||||
*
|
||||
* Requires: MBEDTLS_PKCS1_V21
|
||||
*
|
||||
* Comment this macro to disallow using RSASSA-PSS in certificates.
|
||||
*/
|
||||
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
|
||||
@ -2238,7 +2240,7 @@
|
||||
/**
|
||||
* \def MBEDTLS_AESCE_C
|
||||
*
|
||||
* Enable AES cryptographic extension support on 64-bit Arm.
|
||||
* Enable AES cryptographic extension support on Armv8.
|
||||
*
|
||||
* Module: library/aesce.c
|
||||
* Caller: library/aes.c
|
||||
@ -2249,13 +2251,15 @@
|
||||
* system, Armv8-A Cryptographic Extensions must be supported by
|
||||
* the CPU when this option is enabled.
|
||||
*
|
||||
* \note Minimum compiler versions for this feature are Clang 4.0,
|
||||
* armclang 6.6, GCC 6.0 or MSVC 2019 version 16.11.2.
|
||||
* \note Minimum compiler versions for this feature when targeting aarch64
|
||||
* are Clang 4.0; armclang 6.6; GCC 6.0; or MSVC 2019 version 16.11.2.
|
||||
* Minimum compiler versions for this feature when targeting 32-bit
|
||||
* Arm or Thumb are Clang 11.0; armclang 6.20; or GCC 6.0.
|
||||
*
|
||||
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
|
||||
* armclang <= 6.9
|
||||
*
|
||||
* This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems.
|
||||
* This module adds support for the AES Armv8-A Cryptographic Extensions on Armv8 systems.
|
||||
*/
|
||||
#define MBEDTLS_AESCE_C
|
||||
|
||||
@ -2374,6 +2378,28 @@
|
||||
*/
|
||||
#define MBEDTLS_BASE64_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
|
||||
*
|
||||
* Remove decryption operation for AES, ARIA and Camellia block cipher.
|
||||
*
|
||||
* \note This feature is incompatible with insecure block cipher,
|
||||
* MBEDTLS_DES_C, and cipher modes which always require decryption
|
||||
* operation, MBEDTLS_CIPHER_MODE_CBC, MBEDTLS_CIPHER_MODE_XTS and
|
||||
* MBEDTLS_NIST_KW_C. When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled,
|
||||
* this feature is incompatible with following supported PSA equivalence,
|
||||
* PSA_WANT_ALG_ECB_NO_PADDING, PSA_WANT_ALG_CBC_NO_PADDING,
|
||||
* PSA_WANT_ALG_CBC_PKCS7 and PSA_WANT_KEY_TYPE_DES.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
* library/aesce.c
|
||||
* library/aesni.c
|
||||
* library/aria.c
|
||||
* library/camellia.c
|
||||
* library/cipher.c
|
||||
*/
|
||||
//#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_BIGNUM_C
|
||||
*
|
||||
@ -2553,6 +2579,8 @@
|
||||
* library/ssl_ciphersuites.c
|
||||
* library/ssl_msg.c
|
||||
* library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled)
|
||||
* Auto-enabled by: MBEDTLS_PSA_CRYPTO_C depending on which ciphers are enabled
|
||||
* (see the documentation of that option for details).
|
||||
*
|
||||
* Uncomment to enable generic cipher wrappers.
|
||||
*/
|
||||
@ -2583,6 +2611,13 @@
|
||||
* The CTR_DRBG generator uses AES-256 by default.
|
||||
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
|
||||
*
|
||||
* AES support can either be achived through builtin (MBEDTLS_AES_C) or PSA.
|
||||
* Builtin is the default option when MBEDTLS_AES_C is defined otherwise PSA
|
||||
* is used.
|
||||
*
|
||||
* \warning When using PSA, the user should call `psa_crypto_init()` before
|
||||
* using any CTR_DRBG operation (except `mbedtls_ctr_drbg_init()`).
|
||||
*
|
||||
* \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set.
|
||||
*
|
||||
* \note To achieve a 256-bit security strength with CTR_DRBG,
|
||||
@ -2592,7 +2627,9 @@
|
||||
* Module: library/ctr_drbg.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_AES_C
|
||||
* Requires: MBEDTLS_AES_C or
|
||||
* (PSA_WANT_KEY_TYPE_AES and PSA_WANT_ALG_ECB_NO_PADDING and
|
||||
* MBEDTLS_PSA_CRYPTO_C)
|
||||
*
|
||||
* This module provides the CTR_DRBG AES random number generator.
|
||||
*/
|
||||
@ -3049,7 +3086,6 @@
|
||||
*
|
||||
* Module: library/pkcs5.c
|
||||
*
|
||||
* Requires: MBEDTLS_CIPHER_C
|
||||
* Auto-enables: MBEDTLS_MD_C
|
||||
*
|
||||
* \warning If using a hash that is only provided by PSA drivers, you must
|
||||
@ -3084,8 +3120,8 @@
|
||||
* Module: library/pkcs12.c
|
||||
* Caller: library/pkparse.c
|
||||
*
|
||||
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C and either
|
||||
* MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C.
|
||||
* Requires: MBEDTLS_ASN1_PARSE_C and either MBEDTLS_MD_C or
|
||||
* MBEDTLS_PSA_CRYPTO_C.
|
||||
*
|
||||
* \warning If using a hash that is only provided by PSA drivers, you must
|
||||
* call psa_crypto_init() before doing any PKCS12 operations.
|
||||
@ -3131,11 +3167,12 @@
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
*
|
||||
* Requires: MBEDTLS_CIPHER_C,
|
||||
* either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
|
||||
* Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
|
||||
* or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
|
||||
* or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
|
||||
*
|
||||
* Auto-enables: MBEDTLS_CIPHER_C if any unauthenticated (ie, non-AEAD) cipher
|
||||
* is enabled in PSA (unless it's fully accelerated, see
|
||||
* docs/driver-only-builds.md about that).
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
@ -3261,14 +3298,14 @@
|
||||
#define MBEDTLS_SHA256_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
|
||||
* \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
*
|
||||
* Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms
|
||||
* with the ARMv8 cryptographic extensions if they are available at runtime.
|
||||
* If not, the library will fall back to the C implementation.
|
||||
*
|
||||
* \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building
|
||||
* for a non-Aarch64 build it will be silently ignored.
|
||||
* \note If MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT is defined when building
|
||||
* for a non-Armv8-A build it will be silently ignored.
|
||||
*
|
||||
* \note Minimum compiler versions for this feature are Clang 4.0,
|
||||
* armclang 6.6 or GCC 6.0.
|
||||
@ -3276,27 +3313,40 @@
|
||||
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
|
||||
* armclang <= 6.9
|
||||
*
|
||||
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the
|
||||
* same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY.
|
||||
* \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT.
|
||||
* That name is deprecated, but may still be used as an alternative form for this
|
||||
* option.
|
||||
*
|
||||
* \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT cannot be defined at the
|
||||
* same time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY.
|
||||
*
|
||||
* Requires: MBEDTLS_SHA256_C.
|
||||
*
|
||||
* Module: library/sha256.c
|
||||
*
|
||||
* Uncomment to have the library check for the A64 SHA-256 crypto extensions
|
||||
* Uncomment to have the library check for the Armv8-A SHA-256 crypto extensions
|
||||
* and use them if available.
|
||||
*/
|
||||
//#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
|
||||
*
|
||||
* \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT.
|
||||
* This name is now deprecated, but may still be used as an alternative form for
|
||||
* this option.
|
||||
*/
|
||||
//#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
|
||||
* \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
|
||||
*
|
||||
* Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms
|
||||
* with the ARMv8 cryptographic extensions, which must be available at runtime
|
||||
* or else an illegal instruction fault will occur.
|
||||
*
|
||||
* \note This allows builds with a smaller code size than with
|
||||
* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
|
||||
* MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
*
|
||||
* \note Minimum compiler versions for this feature are Clang 4.0,
|
||||
* armclang 6.6 or GCC 6.0.
|
||||
@ -3304,16 +3354,29 @@
|
||||
* \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for
|
||||
* armclang <= 6.9
|
||||
*
|
||||
* \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same
|
||||
* time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT.
|
||||
* \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY.
|
||||
* That name is deprecated, but may still be used as an alternative form for this
|
||||
* option.
|
||||
*
|
||||
* \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY cannot be defined at the same
|
||||
* time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT.
|
||||
*
|
||||
* Requires: MBEDTLS_SHA256_C.
|
||||
*
|
||||
* Module: library/sha256.c
|
||||
*
|
||||
* Uncomment to have the library use the A64 SHA-256 crypto extensions
|
||||
* Uncomment to have the library use the Armv8-A SHA-256 crypto extensions
|
||||
* unconditionally.
|
||||
*/
|
||||
//#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
|
||||
*
|
||||
* \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY.
|
||||
* This name is now deprecated, but may still be used as an alternative form for
|
||||
* this option.
|
||||
*/
|
||||
//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
|
||||
|
||||
/**
|
||||
@ -4057,7 +4120,7 @@
|
||||
* \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE
|
||||
*
|
||||
* The default maximum amount of 0-RTT data. See the documentation of
|
||||
* \c mbedtls_ssl_tls13_conf_max_early_data_size() for more information.
|
||||
* \c mbedtls_ssl_conf_max_early_data_size() for more information.
|
||||
*
|
||||
* It must be positive and smaller than UINT32_MAX.
|
||||
*
|
||||
@ -4073,20 +4136,23 @@
|
||||
/**
|
||||
* \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
|
||||
*
|
||||
* Maximum time difference in milliseconds tolerated between the age of a
|
||||
* ticket from the server and client point of view.
|
||||
* From the client point of view, the age of a ticket is the time difference
|
||||
* between the time when the client proposes to the server to use the ticket
|
||||
* (time of writing of the Pre-Shared Key Extension including the ticket) and
|
||||
* the time the client received the ticket from the server.
|
||||
* From the server point of view, the age of a ticket is the time difference
|
||||
* between the time when the server receives a proposition from the client
|
||||
* to use the ticket and the time when the ticket was created by the server.
|
||||
* The server age is expected to be always greater than the client one and
|
||||
* MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
|
||||
* maximum difference tolerated for the server to accept the ticket.
|
||||
* This is not used in TLS 1.2.
|
||||
* Maximum allowed ticket age difference in milliseconds tolerated between
|
||||
* server and client. Default value is 6000. This is not used in TLS 1.2.
|
||||
*
|
||||
* - The client ticket age is the time difference between the time when the
|
||||
* client proposes to the server to use the ticket and the time the client
|
||||
* received the ticket from the server.
|
||||
* - The server ticket age is the time difference between the time when the
|
||||
* server receives a proposition from the client to use the ticket and the
|
||||
* time when the ticket was created by the server.
|
||||
*
|
||||
* The ages might be different due to the client and server clocks not running
|
||||
* at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts
|
||||
* per million (360 to 72 milliseconds per hour). Default tolerance window is
|
||||
* 6s, thus in the worst case clients and servers must sync up their system time
|
||||
* every 6000/360/2~=8 hours.
|
||||
*
|
||||
* See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000
|
||||
|
||||
|
@ -20,120 +20,6 @@
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
|
||||
/*
|
||||
* - MBEDTLS_MD_CAN_xxx is defined if the md module can perform xxx.
|
||||
* - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA
|
||||
* (see below).
|
||||
* - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed
|
||||
* via PSA (see below).
|
||||
* - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed
|
||||
* via a direct legacy call (see below).
|
||||
*
|
||||
* The md module performs an algorithm via PSA if there is a PSA hash
|
||||
* accelerator and the PSA driver subsytem is initialized at the time the
|
||||
* operation is started, and makes a direct legacy call otherwise.
|
||||
*/
|
||||
|
||||
/* PSA accelerated implementations */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
|
||||
#define MBEDTLS_MD_CAN_MD5
|
||||
#define MBEDTLS_MD_MD5_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
|
||||
#define MBEDTLS_MD_CAN_SHA1
|
||||
#define MBEDTLS_MD_SHA1_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||
#define MBEDTLS_MD_CAN_SHA224
|
||||
#define MBEDTLS_MD_SHA224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#define MBEDTLS_MD_CAN_SHA256
|
||||
#define MBEDTLS_MD_SHA256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
#define MBEDTLS_MD_CAN_SHA384
|
||||
#define MBEDTLS_MD_SHA384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||
#define MBEDTLS_MD_CAN_SHA512
|
||||
#define MBEDTLS_MD_SHA512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
|
||||
#define MBEDTLS_MD_CAN_RIPEMD160
|
||||
#define MBEDTLS_MD_RIPEMD160_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224)
|
||||
#define MBEDTLS_MD_CAN_SHA3_224
|
||||
#define MBEDTLS_MD_SHA3_224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256)
|
||||
#define MBEDTLS_MD_CAN_SHA3_256
|
||||
#define MBEDTLS_MD_SHA3_256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384)
|
||||
#define MBEDTLS_MD_CAN_SHA3_384
|
||||
#define MBEDTLS_MD_SHA3_384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512)
|
||||
#define MBEDTLS_MD_CAN_SHA3_512
|
||||
#define MBEDTLS_MD_SHA3_512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/* Built-in implementations */
|
||||
#if defined(MBEDTLS_MD5_C)
|
||||
#define MBEDTLS_MD_CAN_MD5
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
#define MBEDTLS_MD_CAN_SHA1
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
#define MBEDTLS_MD_CAN_SHA224
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
#define MBEDTLS_MD_CAN_SHA256
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
#define MBEDTLS_MD_CAN_SHA384
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
#define MBEDTLS_MD_CAN_SHA512
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA3_C)
|
||||
#define MBEDTLS_MD_CAN_SHA3_224
|
||||
#define MBEDTLS_MD_CAN_SHA3_256
|
||||
#define MBEDTLS_MD_CAN_SHA3_384
|
||||
#define MBEDTLS_MD_CAN_SHA3_512
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_RIPEMD160_C)
|
||||
#define MBEDTLS_MD_CAN_RIPEMD160
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_MD_LIGHT */
|
||||
|
||||
/** The selected feature is not available. */
|
||||
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080
|
||||
/** Bad input parameters to function. */
|
||||
|
@ -143,7 +143,7 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
|
||||
* \param client_ctx Will contain the connected client socket
|
||||
* \param client_ip Will contain the client IP address, can be NULL
|
||||
* \param buf_size Size of the client_ip buffer
|
||||
* \param ip_len Will receive the size of the client IP written,
|
||||
* \param cip_len Will receive the size of the client IP written,
|
||||
* can be NULL if client_ip is null
|
||||
*
|
||||
* \return 0 if successful, or
|
||||
@ -156,7 +156,7 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
|
||||
*/
|
||||
int mbedtls_net_accept(mbedtls_net_context *bind_ctx,
|
||||
mbedtls_net_context *client_ctx,
|
||||
void *client_ip, size_t buf_size, size_t *ip_len);
|
||||
void *client_ip, size_t buf_size, size_t *cip_len);
|
||||
|
||||
/**
|
||||
* \brief Check and wait for the context to be ready for read/write
|
||||
|
@ -698,7 +698,6 @@ int mbedtls_oid_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg);
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
#if defined(MBEDTLS_PKCS12_C)
|
||||
/**
|
||||
@ -714,6 +713,7 @@ int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_
|
||||
int mbedtls_oid_get_pkcs12_pbe_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
|
||||
mbedtls_cipher_type_t *cipher_alg);
|
||||
#endif /* MBEDTLS_PKCS12_C */
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
@ -229,7 +229,7 @@ typedef struct mbedtls_pk_context {
|
||||
void *MBEDTLS_PRIVATE(pk_ctx); /**< Underlying public key context */
|
||||
/* The following field is used to store the ID of a private key in the
|
||||
* following cases:
|
||||
* - opaque key when MBEDTLS_PSA_CRYPTO_C is defined
|
||||
* - opaque key when MBEDTLS_USE_PSA_CRYPTO is defined
|
||||
* - normal key when MBEDTLS_PK_USE_PSA_EC_DATA is defined. In this case:
|
||||
* - the pk_ctx above is not not used to store the private key anymore.
|
||||
* Actually that field not populated at all in this case because also
|
||||
@ -239,15 +239,10 @@ typedef struct mbedtls_pk_context {
|
||||
*
|
||||
* Note: this private key storing solution only affects EC keys, not the
|
||||
* other ones. The latters still use the pk_ctx to store their own
|
||||
* context.
|
||||
*
|
||||
* Note: this priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not by
|
||||
* MBEDTLS_PK_USE_PSA_EC_DATA (as the public counterpart below) because,
|
||||
* when working with opaque keys, it can be used also in
|
||||
* mbedtls_pk_sign_ext for RSA keys. */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
* context. */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id); /**< Key ID for opaque keys */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
/* The following fields are meant for storing the public key in raw format
|
||||
* which is handy for:
|
||||
* - easily importing it into the PSA context
|
||||
@ -615,7 +610,6 @@ int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
/**
|
||||
* \brief Make signature given a signature type.
|
||||
*
|
||||
@ -652,7 +646,6 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/**
|
||||
* \brief Restartable version of \c mbedtls_pk_sign()
|
||||
|
@ -31,14 +31,14 @@
|
||||
#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */
|
||||
#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */
|
||||
|
||||
#define MBEDTLS_PKCS12_PBE_DECRYPT 0
|
||||
#define MBEDTLS_PKCS12_PBE_ENCRYPT 1
|
||||
#define MBEDTLS_PKCS12_PBE_DECRYPT MBEDTLS_DECRYPT
|
||||
#define MBEDTLS_PKCS12_PBE_ENCRYPT MBEDTLS_ENCRYPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
@ -145,7 +145,7 @@ int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */
|
||||
|
||||
/**
|
||||
* \brief The PKCS#12 derivation function uses a password and a salt
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -30,14 +31,14 @@
|
||||
/** Given private key password does not allow for correct decryption. */
|
||||
#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00
|
||||
|
||||
#define MBEDTLS_PKCS5_DECRYPT 0
|
||||
#define MBEDTLS_PKCS5_ENCRYPT 1
|
||||
#define MBEDTLS_PKCS5_DECRYPT MBEDTLS_DECRYPT
|
||||
#define MBEDTLS_PKCS5_ENCRYPT MBEDTLS_ENCRYPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
@ -129,7 +130,7 @@ int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode,
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C*/
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC without using the HMAC context
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* Expose whatever RNG the PSA subsystem uses to applications using the
|
||||
@ -100,5 +102,81 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
|
||||
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
|
||||
/** \defgroup psa_tls_helpers TLS helper functions
|
||||
* @{
|
||||
*/
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#include <mbedtls/ecp.h>
|
||||
|
||||
/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA.
|
||||
*
|
||||
* \param grpid An Mbed TLS elliptic curve identifier
|
||||
* (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \param[out] bits On success the bit size of the curve; 0 on failure.
|
||||
*
|
||||
* \return If the curve is supported in the PSA API, this function
|
||||
* returns the proper PSA curve identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`). This holds even if the curve is
|
||||
* not supported by the ECP module.
|
||||
* \return \c 0 if the curve is not supported in the PSA API.
|
||||
*/
|
||||
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
|
||||
size_t *bits);
|
||||
|
||||
/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS.
|
||||
*
|
||||
* \param family A PSA elliptic curve family identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`).
|
||||
* \param bits The bit-length of a private key on \p curve.
|
||||
*
|
||||
* \return If the curve is supported in the PSA API, this function
|
||||
* returns the corresponding Mbed TLS elliptic curve
|
||||
* identifier (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve
|
||||
* and \p bits is not supported.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
|
||||
size_t bits);
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/**
|
||||
* \brief This function returns the PSA algorithm identifier
|
||||
* associated with the given digest type.
|
||||
*
|
||||
* \param md_type The type of digest to search for. Must not be NONE.
|
||||
*
|
||||
* \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will
|
||||
* not return \c PSA_ALG_NONE, but an invalid algorithm.
|
||||
*
|
||||
* \warning This function does not check if the algorithm is
|
||||
* supported, it always returns the corresponding identifier.
|
||||
*
|
||||
* \return The PSA algorithm identifier associated with \p md_type,
|
||||
* regardless of whether it is supported or not.
|
||||
*/
|
||||
static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
|
||||
{
|
||||
return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function returns the given digest type
|
||||
* associated with the PSA algorithm identifier.
|
||||
*
|
||||
* \param psa_alg The PSA algorithm identifier to search for.
|
||||
*
|
||||
* \warning This function does not check if the algorithm is
|
||||
* supported, it always returns the corresponding identifier.
|
||||
*
|
||||
* \return The MD type associated with \p psa_alg,
|
||||
* regardless of whether it is supported or not.
|
||||
*/
|
||||
static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
|
||||
{
|
||||
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_PSA_UTIL_H */
|
||||
|
@ -878,6 +878,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig);
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
/**
|
||||
* \brief This function performs a PKCS#1 v2.1 PSS signature
|
||||
* operation (RSASSA-PSS-SIGN).
|
||||
@ -978,6 +979,7 @@ int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig);
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
|
||||
/**
|
||||
* \brief This function performs a public RSA operation and checks
|
||||
|
@ -41,8 +41,10 @@ typedef struct mbedtls_sha256_context {
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */
|
||||
uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */
|
||||
uint32_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
int MBEDTLS_PRIVATE(is224); /*!< Determines which function to use:
|
||||
0: Use SHA-256, or 1: Use SHA-224. */
|
||||
#endif
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
|
@ -447,7 +447,7 @@
|
||||
|
||||
/*
|
||||
* TLS 1.3 signature algorithms
|
||||
* RFC 8446, Section 4.2.2
|
||||
* RFC 8446, Section 4.2.3
|
||||
*/
|
||||
|
||||
/* RSASSA-PKCS1-v1_5 algorithms */
|
||||
@ -613,7 +613,7 @@
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_AES_C) && defined(MBEDTLS_GCM_C) && \
|
||||
defined(MBEDTLS_SSL_HAVE_AES) && defined(MBEDTLS_SSL_HAVE_GCM) && \
|
||||
defined(MBEDTLS_MD_CAN_SHA384)
|
||||
#define MBEDTLS_PSK_MAX_LEN 48 /* 384 bits */
|
||||
#else
|
||||
@ -687,7 +687,6 @@ typedef enum {
|
||||
MBEDTLS_SSL_SERVER_FINISHED,
|
||||
MBEDTLS_SSL_FLUSH_BUFFERS,
|
||||
MBEDTLS_SSL_HANDSHAKE_WRAPUP,
|
||||
|
||||
MBEDTLS_SSL_NEW_SESSION_TICKET,
|
||||
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
|
||||
MBEDTLS_SSL_HELLO_RETRY_REQUEST,
|
||||
@ -1189,6 +1188,11 @@ struct mbedtls_ssl_session {
|
||||
unsigned char MBEDTLS_PRIVATE(mfl_code); /*!< MaxFragmentLength negotiated by peer */
|
||||
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
||||
|
||||
/*!< RecordSizeLimit received from the peer */
|
||||
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
|
||||
uint16_t MBEDTLS_PRIVATE(record_size_limit);
|
||||
#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
|
||||
|
||||
unsigned char MBEDTLS_PRIVATE(exported);
|
||||
|
||||
/** TLS version negotiated in the session. Used if and when renegotiating
|
||||
@ -1197,7 +1201,7 @@ struct mbedtls_ssl_session {
|
||||
mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< starting time */
|
||||
mbedtls_time_t MBEDTLS_PRIVATE(start); /*!< start time of current session */
|
||||
#endif
|
||||
int MBEDTLS_PRIVATE(ciphersuite); /*!< chosen ciphersuite */
|
||||
size_t MBEDTLS_PRIVATE(id_len); /*!< session id length */
|
||||
@ -1234,12 +1238,21 @@ struct mbedtls_ssl_session {
|
||||
char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
|
||||
mbedtls_time_t MBEDTLS_PRIVATE(ticket_received); /*!< time ticket was received */
|
||||
#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_CLI_C */
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); /*!< time when ticket was received. */
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time); /*!< time when ticket was created. */
|
||||
#endif
|
||||
#endif /* MBEDTLS_HAVE_TIME */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
uint32_t MBEDTLS_PRIVATE(max_early_data_size); /*!< maximum amount of early data in tickets */
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
||||
int MBEDTLS_PRIVATE(encrypt_then_mac); /*!< flag for EtM activation */
|
||||
#endif
|
||||
@ -1828,7 +1841,7 @@ struct mbedtls_ssl_context {
|
||||
* and #MBEDTLS_SSL_CID_DISABLED. */
|
||||
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
int MBEDTLS_PRIVATE(early_data_status);
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
@ -2000,8 +2013,8 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode);
|
||||
* \warning This interface is experimental and may change without notice.
|
||||
*
|
||||
*/
|
||||
void mbedtls_ssl_tls13_conf_early_data(mbedtls_ssl_config *conf,
|
||||
int early_data_enabled);
|
||||
void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf,
|
||||
int early_data_enabled);
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/**
|
||||
@ -2026,8 +2039,12 @@ void mbedtls_ssl_tls13_conf_early_data(mbedtls_ssl_config *conf,
|
||||
*
|
||||
* \warning This interface is experimental and may change without notice.
|
||||
*
|
||||
* \warning This interface DOES NOT influence/limit the amount of early data
|
||||
* that can be received through previously created and issued tickets,
|
||||
* which clients may have stored.
|
||||
*
|
||||
*/
|
||||
void mbedtls_ssl_tls13_conf_max_early_data_size(
|
||||
void mbedtls_ssl_conf_max_early_data_size(
|
||||
mbedtls_ssl_config *conf, uint32_t max_early_data_size);
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
@ -3739,6 +3756,8 @@ void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf,
|
||||
* used for certificate signature are controlled by the
|
||||
* verification profile, see \c mbedtls_ssl_conf_cert_profile().
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_ssl_conf_sig_algs().
|
||||
*
|
||||
* \note This list should be ordered by decreasing preference
|
||||
* (preferred hash first).
|
||||
*
|
||||
@ -3763,13 +3782,16 @@ void MBEDTLS_DEPRECATED mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf,
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED && MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
/**
|
||||
* \brief Configure allowed signature algorithms for use in TLS 1.3
|
||||
* \brief Configure allowed signature algorithms for use in TLS
|
||||
*
|
||||
* \param conf The SSL configuration to use.
|
||||
* \param sig_algs List of allowed IANA values for TLS 1.3 signature algorithms,
|
||||
* terminated by \c MBEDTLS_TLS1_3_SIG_NONE. The list must remain
|
||||
* available throughout the lifetime of the conf object. Supported
|
||||
* values are available as \c MBEDTLS_TLS1_3_SIG_XXXX
|
||||
* terminated by #MBEDTLS_TLS1_3_SIG_NONE. The list must remain
|
||||
* available throughout the lifetime of the conf object.
|
||||
* - For TLS 1.3, values of \c MBEDTLS_TLS1_3_SIG_XXXX should be
|
||||
* used.
|
||||
* - For TLS 1.2, values should be given as
|
||||
* "(HashAlgorithm << 8) | SignatureAlgorithm".
|
||||
*/
|
||||
void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf,
|
||||
const uint16_t *sig_algs);
|
||||
@ -5001,6 +5023,10 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/**
|
||||
* \brief Read at most 'len' application data bytes while performing
|
||||
@ -5110,9 +5136,6 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
|
||||
int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf, size_t len);
|
||||
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1
|
||||
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2
|
||||
/**
|
||||
* \brief Get the status of the negotiation of the use of early data.
|
||||
*
|
||||
|
@ -28,10 +28,14 @@ extern "C" {
|
||||
#include <pthread.h>
|
||||
typedef struct mbedtls_threading_mutex_t {
|
||||
pthread_mutex_t MBEDTLS_PRIVATE(mutex);
|
||||
/* is_valid is 0 after a failed init or a free, and nonzero after a
|
||||
* successful init. This field is not considered part of the public
|
||||
* API of Mbed TLS and may change without notice. */
|
||||
char MBEDTLS_PRIVATE(is_valid);
|
||||
|
||||
/* WARNING - state should only be accessed when holding the mutex lock in
|
||||
* tests/src/threading_helpers.c, otherwise corruption can occur.
|
||||
* state will be 0 after a failed init or a free, and nonzero after a
|
||||
* successful init. This field is for testing only and thus not considered
|
||||
* part of the public API of Mbed TLS and may change without notice.*/
|
||||
char MBEDTLS_PRIVATE(state);
|
||||
|
||||
} mbedtls_threading_mutex_t;
|
||||
#endif
|
||||
|
||||
@ -96,6 +100,20 @@ extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
|
||||
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
/*
|
||||
* A mutex used to make the PSA subsystem thread safe.
|
||||
*
|
||||
* key_slot_mutex protects the registered_readers and
|
||||
* state variable for all key slots in &global_data.key_slots.
|
||||
*
|
||||
* This mutex must be held when any read from or write to a state or
|
||||
* registered_readers field is performed, i.e. when calling functions:
|
||||
* psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(),
|
||||
* psa_key_slot_has_readers() and psa_wipe_key_slot(). */
|
||||
extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex;
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -75,7 +75,9 @@ mbedtls_x509write_csr;
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR) in DER format
|
||||
*
|
||||
* \note CSR attributes (if any) are currently silently ignored.
|
||||
* \note Any unsupported requested extensions are silently
|
||||
* ignored, unless the critical flag is set, in which case
|
||||
* the CSR is rejected.
|
||||
*
|
||||
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
|
||||
* subsystem must have been initialized by calling
|
||||
@ -90,6 +92,67 @@ mbedtls_x509write_csr;
|
||||
int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr,
|
||||
const unsigned char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* \brief The type of certificate extension callbacks.
|
||||
*
|
||||
* Callbacks of this type are passed to and used by the
|
||||
* mbedtls_x509_csr_parse_der_with_ext_cb() routine when
|
||||
* it encounters either an unsupported extension.
|
||||
* Future versions of the library may invoke the callback
|
||||
* in other cases, if and when the need arises.
|
||||
*
|
||||
* \param p_ctx An opaque context passed to the callback.
|
||||
* \param csr The CSR being parsed.
|
||||
* \param oid The OID of the extension.
|
||||
* \param critical Whether the extension is critical.
|
||||
* \param p Pointer to the start of the extension value
|
||||
* (the content of the OCTET STRING).
|
||||
* \param end End of extension value.
|
||||
*
|
||||
* \note The callback must fail and return a negative error code
|
||||
* if it can not parse or does not support the extension.
|
||||
* When the callback fails to parse a critical extension
|
||||
* mbedtls_x509_csr_parse_der_with_ext_cb() also fails.
|
||||
* When the callback fails to parse a non critical extension
|
||||
* mbedtls_x509_csr_parse_der_with_ext_cb() simply skips
|
||||
* the extension and continues parsing.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
typedef int (*mbedtls_x509_csr_ext_cb_t)(void *p_ctx,
|
||||
mbedtls_x509_csr const *csr,
|
||||
mbedtls_x509_buf const *oid,
|
||||
int critical,
|
||||
const unsigned char *p,
|
||||
const unsigned char *end);
|
||||
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR) in DER format
|
||||
*
|
||||
* \note Any unsupported requested extensions are silently
|
||||
* ignored, unless the critical flag is set, in which case
|
||||
* the result of the callback function decides whether
|
||||
* CSR is rejected.
|
||||
*
|
||||
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
|
||||
* subsystem must have been initialized by calling
|
||||
* psa_crypto_init() before calling this function.
|
||||
*
|
||||
* \param csr CSR context to fill
|
||||
* \param buf buffer holding the CRL data
|
||||
* \param buflen size of the buffer
|
||||
* \param cb A callback invoked for every unsupported certificate
|
||||
* extension.
|
||||
* \param p_ctx An opaque context passed to the callback.
|
||||
*
|
||||
* \return 0 if successful, or a specific X509 error code
|
||||
*/
|
||||
int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
mbedtls_x509_csr_ext_cb_t cb,
|
||||
void *p_ctx);
|
||||
|
||||
/**
|
||||
* \brief Load a Certificate Signing Request (CSR), DER or PEM format
|
||||
*
|
||||
|
@ -24,12 +24,6 @@
|
||||
#define PSA_WANT_ALG_ECDSA_ANY PSA_WANT_ALG_ECDSA
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && !defined(PSA_WANT_ALG_CCM)
|
||||
#define PSA_WANT_ALG_CCM PSA_WANT_ALG_CCM_STAR_NO_TAG
|
||||
#elif !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && defined(PSA_WANT_ALG_CCM)
|
||||
#define PSA_WANT_ALG_CCM_STAR_NO_TAG PSA_WANT_ALG_CCM
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
|
||||
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW
|
||||
#elif !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
|
||||
|
@ -25,8 +25,12 @@
|
||||
#include <psa/crypto_driver_common.h>
|
||||
|
||||
#include "mbedtls/cmac.h"
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
#include "mbedtls/gcm.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
#include "mbedtls/ccm.h"
|
||||
#endif
|
||||
#include "mbedtls/chachapoly.h"
|
||||
|
||||
/*
|
||||
|
@ -428,6 +428,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
* of psa_set_key_type() when you need to specify domain parameters.
|
||||
*
|
||||
* The format for the required domain parameters varies based on the key type.
|
||||
* Mbed TLS supports the following key type with domain parameters:
|
||||
*
|
||||
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
|
||||
* the domain parameter data consists of the public exponent,
|
||||
@ -437,32 +438,6 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
* key data and the exponent recorded in the attribute structure is ignored.
|
||||
* As an exception, the public exponent 65537 is represented by an empty
|
||||
* byte string.
|
||||
* - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR),
|
||||
* the `Dss-Params` format as defined by RFC 3279 §2.3.2.
|
||||
* ```
|
||||
* Dss-Params ::= SEQUENCE {
|
||||
* p INTEGER,
|
||||
* q INTEGER,
|
||||
* g INTEGER
|
||||
* }
|
||||
* ```
|
||||
* - For Diffie-Hellman key exchange keys
|
||||
* (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM)), the
|
||||
* `DomainParameters` format as defined by RFC 3279 §2.3.3.
|
||||
* ```
|
||||
* DomainParameters ::= SEQUENCE {
|
||||
* p INTEGER, -- odd prime, p=jq +1
|
||||
* g INTEGER, -- generator, g
|
||||
* q INTEGER, -- factor of p-1
|
||||
* j INTEGER OPTIONAL, -- subgroup factor
|
||||
* validationParams ValidationParams OPTIONAL
|
||||
* }
|
||||
* ValidationParams ::= SEQUENCE {
|
||||
* seed BIT STRING,
|
||||
* pgenCounter INTEGER
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \note This function may allocate memory or other resources.
|
||||
* Once you have called this function on an attribute structure,
|
||||
@ -471,6 +446,9 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \note Due to an implementation limitation, domain parameters are ignored
|
||||
* for keys that are managed by a driver.
|
||||
*
|
||||
* \param[in,out] attributes Attribute structure where the specified domain
|
||||
* parameters will be stored.
|
||||
* If this function fails, the content of
|
||||
@ -486,10 +464,13 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
*/
|
||||
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
|
||||
#define PSA_SET_KEY_DOMAIN_PARAMETERS
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
|
||||
|
||||
/**
|
||||
* \brief Get domain parameters for a key.
|
||||
@ -501,6 +482,9 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \note Due to an implementation limitation, domain parameters are not
|
||||
* supported with keys that are managed by a driver.
|
||||
*
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
* \param[out] data On success, the key domain parameters.
|
||||
* \param data_size Size of the \p data buffer in bytes.
|
||||
@ -513,6 +497,8 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key is managed by a driver.
|
||||
*/
|
||||
psa_status_t psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
@ -557,53 +543,6 @@ psa_status_t psa_get_key_domain_parameters(
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup psa_tls_helpers TLS helper functions
|
||||
* @{
|
||||
*/
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#include <mbedtls/ecp.h>
|
||||
|
||||
/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA.
|
||||
*
|
||||
* \note This function is provided solely for the convenience of
|
||||
* Mbed TLS and may be removed at any time without notice.
|
||||
*
|
||||
* \param grpid An Mbed TLS elliptic curve identifier
|
||||
* (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \param[out] bits On success, the bit size of the curve.
|
||||
*
|
||||
* \return The corresponding PSA elliptic curve identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`).
|
||||
* \return \c 0 on failure (\p grpid is not recognized).
|
||||
*/
|
||||
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
|
||||
size_t *bits);
|
||||
|
||||
/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS.
|
||||
*
|
||||
* \note This function is provided solely for the convenience of
|
||||
* Mbed TLS and may be removed at any time without notice.
|
||||
*
|
||||
* \param curve A PSA elliptic curve identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`).
|
||||
* \param bits The bit-length of a private key on \p curve.
|
||||
* \param bits_is_sloppy If true, \p bits may be the bit-length rounded up
|
||||
* to the nearest multiple of 8. This allows the caller
|
||||
* to infer the exact curve from the length of a key
|
||||
* which is supplied as a byte string.
|
||||
*
|
||||
* \return The corresponding Mbed TLS elliptic curve identifier
|
||||
* (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \return #MBEDTLS_ECP_DP_NONE if \c curve is not recognized.
|
||||
* \return #MBEDTLS_ECP_DP_NONE if \p bits is not
|
||||
* correct for \p curve.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve,
|
||||
size_t bits,
|
||||
int bits_is_sloppy);
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup psa_external_rng External random generator
|
||||
* @{
|
||||
|
@ -23,10 +23,10 @@
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
/*
|
||||
* Include the build-time configuration information file. Here, we do not
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* PSA cryptography repository which has a different build system and
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
@ -29,10 +29,10 @@
|
||||
#define PSA_CRYPTO_SIZES_H
|
||||
|
||||
/*
|
||||
* Include the build-time configuration information file. Here, we do not
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* PSA cryptography repository which has a different build system and
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
@ -54,9 +54,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
|
||||
* in each of its header files. */
|
||||
#include "mbedtls/build_info.h"
|
||||
/*
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
||||
/* Include the context definition for the compiled-in drivers for the primitive
|
||||
* algorithms. */
|
||||
@ -249,6 +254,18 @@ struct psa_key_attributes_s {
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
/* Unlike normal buffers, there are three cases for domain_parameters
|
||||
* and domain_parameters_size:
|
||||
* - domain_parameters_size == SIZE_MAX && domain_parameters == NULL:
|
||||
* Access to domain parameters is not supported for this key.
|
||||
* This is a hack which should not exist, intended for keys managed
|
||||
* by a driver, because drivers don't support domain parameters.
|
||||
* - domain_parameters_size == 0 && domain_parameters == NULL:
|
||||
* The domain parameters are empty.
|
||||
* - domain_parameters_size > 0 &&
|
||||
* domain_parameters == valid pointer to domain_parameters_size bytes:
|
||||
* The domain parameters are non-empty.
|
||||
*/
|
||||
void *MBEDTLS_PRIVATE(domain_parameters);
|
||||
size_t MBEDTLS_PRIVATE(domain_parameters_size);
|
||||
};
|
||||
@ -351,10 +368,13 @@ static inline psa_algorithm_t psa_get_key_algorithm(
|
||||
|
||||
/* This function is declared in crypto_extra.h, which comes after this
|
||||
* header file, but we need the function here, so repeat the declaration. */
|
||||
#if !defined(PSA_SET_KEY_DOMAIN_PARAMETERS)
|
||||
#define PSA_SET_KEY_DOMAIN_PARAMETERS
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
#endif /* PSA_SET_KEY_DOMAIN_PARAMETERS */
|
||||
|
||||
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type)
|
||||
|
@ -21,8 +21,15 @@
|
||||
#ifndef PSA_CRYPTO_TYPES_H
|
||||
#define PSA_CRYPTO_TYPES_H
|
||||
|
||||
/* Make sure the Mbed TLS configuration is visible. */
|
||||
#include "mbedtls/build_info.h"
|
||||
/*
|
||||
* Include the build-time configuration information header. Here, we do not
|
||||
* include `"mbedtls/build_info.h"` directly but `"psa/build_info.h"`, which
|
||||
* is basically just an alias to it. This is to ease the maintenance of the
|
||||
* TF-PSA-Crypto repository which has a different build system and
|
||||
* configuration.
|
||||
*/
|
||||
#include "psa/build_info.h"
|
||||
|
||||
/* Define the MBEDTLS_PRIVATE macro. */
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
|
@ -279,6 +279,11 @@
|
||||
* to read from a resource. */
|
||||
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
|
||||
|
||||
/** This can be returned if a function can no longer operate correctly.
|
||||
* For example, if an essential initialization operation failed or
|
||||
* a mutex operation failed. */
|
||||
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
|
||||
|
||||
/** The key identifier is not valid. See also :ref:\`key-handles\`.
|
||||
*/
|
||||
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
|
||||
@ -594,19 +599,23 @@
|
||||
* They are defined in _Standards for Efficient Cryptography_,
|
||||
* _SEC 2: Recommended Elliptic Curve Domain Parameters_.
|
||||
* https://www.secg.org/sec2-v2.pdf
|
||||
*
|
||||
* \note For secp224k1, the bit-size is 225 (size of a private value).
|
||||
*
|
||||
* \note Mbed TLS only supports secp192k1 and secp256k1.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_SECP_K1 ((psa_ecc_family_t) 0x17)
|
||||
|
||||
/** SEC random curves over prime fields.
|
||||
*
|
||||
* This family comprises the following curves:
|
||||
* secp192k1, secp224r1, secp256r1, secp384r1, secp521r1.
|
||||
* secp192r1, secp224r1, secp256r1, secp384r1, secp521r1.
|
||||
* They are defined in _Standards for Efficient Cryptography_,
|
||||
* _SEC 2: Recommended Elliptic Curve Domain Parameters_.
|
||||
* https://www.secg.org/sec2-v2.pdf
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_SECP_R1 ((psa_ecc_family_t) 0x12)
|
||||
/* SECP160R2 (SEC2 v1, obsolete) */
|
||||
/* SECP160R2 (SEC2 v1, obsolete, not supported in Mbed TLS) */
|
||||
#define PSA_ECC_FAMILY_SECP_R2 ((psa_ecc_family_t) 0x1b)
|
||||
|
||||
/** SEC Koblitz curves over binary fields.
|
||||
@ -616,6 +625,8 @@
|
||||
* They are defined in _Standards for Efficient Cryptography_,
|
||||
* _SEC 2: Recommended Elliptic Curve Domain Parameters_.
|
||||
* https://www.secg.org/sec2-v2.pdf
|
||||
*
|
||||
* \note Mbed TLS does not support any curve in this family.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_SECT_K1 ((psa_ecc_family_t) 0x27)
|
||||
|
||||
@ -626,6 +637,8 @@
|
||||
* They are defined in _Standards for Efficient Cryptography_,
|
||||
* _SEC 2: Recommended Elliptic Curve Domain Parameters_.
|
||||
* https://www.secg.org/sec2-v2.pdf
|
||||
*
|
||||
* \note Mbed TLS does not support any curve in this family.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_SECT_R1 ((psa_ecc_family_t) 0x22)
|
||||
|
||||
@ -636,6 +649,8 @@
|
||||
* It is defined in _Standards for Efficient Cryptography_,
|
||||
* _SEC 2: Recommended Elliptic Curve Domain Parameters_.
|
||||
* https://www.secg.org/sec2-v2.pdf
|
||||
*
|
||||
* \note Mbed TLS does not support any curve in this family.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_SECT_R2 ((psa_ecc_family_t) 0x2b)
|
||||
|
||||
@ -645,6 +660,9 @@
|
||||
* brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1,
|
||||
* brainpoolP320r1, brainpoolP384r1, brainpoolP512r1.
|
||||
* It is defined in RFC 5639.
|
||||
*
|
||||
* \note Mbed TLS only supports the 256-bit, 384-bit and 512-bit curves
|
||||
* in this family.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30)
|
||||
|
||||
@ -673,6 +691,8 @@
|
||||
* - 448-bit: Edwards448, the twisted Edwards curve birationally equivalent
|
||||
* to Curve448.
|
||||
* Hamburg, _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
|
||||
*
|
||||
* \note Mbed TLS does not support Edwards curves yet.
|
||||
*/
|
||||
#define PSA_ECC_FAMILY_TWISTED_EDWARDS ((psa_ecc_family_t) 0x42)
|
||||
|
||||
|
14
library/.gitignore
vendored
14
library/.gitignore
vendored
@ -2,10 +2,10 @@ libmbed*
|
||||
*.sln
|
||||
*.vcxproj
|
||||
|
||||
# ###START_COMMENTED_GENERATED_FILES###
|
||||
# /error.c
|
||||
# /version_features.c
|
||||
# /ssl_debug_helpers_generated.c
|
||||
# /psa_crypto_driver_wrappers.h
|
||||
# /psa_crypto_driver_wrappers_no_static.c
|
||||
# ###END_COMMENTED_GENERATED_FILES###
|
||||
###START_GENERATED_FILES###
|
||||
/error.c
|
||||
/version_features.c
|
||||
/ssl_debug_helpers_generated.c
|
||||
/psa_crypto_driver_wrappers.h
|
||||
/psa_crypto_driver_wrappers_no_static.c
|
||||
###END_GENERATED_FILES###
|
||||
|
@ -22,6 +22,7 @@ set(src_crypto
|
||||
bignum_core.c
|
||||
bignum_mod.c
|
||||
bignum_mod_raw.c
|
||||
block_cipher.c
|
||||
camellia.c
|
||||
ccm.c
|
||||
chacha20.c
|
||||
|
@ -91,6 +91,7 @@ OBJS_CRYPTO= \
|
||||
bignum_core.o \
|
||||
bignum_mod.o \
|
||||
bignum_mod_raw.o \
|
||||
block_cipher.o \
|
||||
camellia.o \
|
||||
ccm.o \
|
||||
chacha20.o \
|
||||
@ -321,7 +322,7 @@ GENERATED_FILES = \
|
||||
generated_files: $(GENERATED_FILES)
|
||||
|
||||
# See root Makefile
|
||||
GEN_FILES ?=
|
||||
GEN_FILES ?= yes
|
||||
ifdef GEN_FILES
|
||||
gen_file_dep =
|
||||
else
|
||||
|
211
library/aes.c
211
library/aes.c
@ -22,23 +22,15 @@
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_X64)
|
||||
#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \
|
||||
(defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
|
||||
(defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
|
||||
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_X86)
|
||||
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
|
||||
#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C)
|
||||
#if !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
|
||||
@ -61,6 +53,17 @@
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "ctr.h"
|
||||
|
||||
/*
|
||||
* This is a convenience shorthand macro to check if we need reverse S-box and
|
||||
* reverse tables. It's private and only defined in this file.
|
||||
*/
|
||||
#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
|
||||
(!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
|
||||
!defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
#define MBEDTLS_AES_NEED_REVERSE_TABLES
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_ALT)
|
||||
|
||||
@ -72,9 +75,7 @@ static int aes_padlock_ace = -1;
|
||||
/*
|
||||
* Forward S-box
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
static const unsigned char FSb[256] =
|
||||
MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
|
||||
{
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
|
||||
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
@ -109,8 +110,6 @@ static const unsigned char FSb[256] =
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
||||
};
|
||||
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
|
||||
|
||||
/*
|
||||
* Forward tables
|
||||
@ -182,36 +181,28 @@ static const unsigned char FSb[256] =
|
||||
V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
|
||||
V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
|
||||
|
||||
#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
|
||||
#define V(a, b, c, d) 0x##a##b##c##d
|
||||
static const uint32_t FT0[256] = { FT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
|
||||
#undef V
|
||||
|
||||
#if !defined(MBEDTLS_AES_FEWER_TABLES)
|
||||
|
||||
#define V(a, b, c, d) 0x##b##c##d##a
|
||||
static const uint32_t FT1[256] = { FT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
|
||||
#undef V
|
||||
|
||||
#define V(a, b, c, d) 0x##c##d##a##b
|
||||
static const uint32_t FT2[256] = { FT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
|
||||
#undef V
|
||||
|
||||
#define V(a, b, c, d) 0x##d##a##b##c
|
||||
static const uint32_t FT3[256] = { FT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
|
||||
#undef V
|
||||
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
|
||||
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
|
||||
|
||||
#undef FT
|
||||
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT)
|
||||
/*
|
||||
* Reverse S-box
|
||||
*/
|
||||
static const unsigned char RSb[256] =
|
||||
MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
|
||||
{
|
||||
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
|
||||
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
||||
@ -246,7 +237,6 @@ static const unsigned char RSb[256] =
|
||||
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
|
||||
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
||||
};
|
||||
#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
|
||||
|
||||
/*
|
||||
* Reverse tables
|
||||
@ -318,84 +308,60 @@ static const unsigned char RSb[256] =
|
||||
V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
|
||||
V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
|
||||
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
|
||||
#define V(a, b, c, d) 0x##a##b##c##d
|
||||
static const uint32_t RT0[256] = { RT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
|
||||
#undef V
|
||||
|
||||
#if !defined(MBEDTLS_AES_FEWER_TABLES)
|
||||
|
||||
#define V(a, b, c, d) 0x##b##c##d##a
|
||||
static const uint32_t RT1[256] = { RT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
|
||||
#undef V
|
||||
|
||||
#define V(a, b, c, d) 0x##c##d##a##b
|
||||
static const uint32_t RT2[256] = { RT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
|
||||
#undef V
|
||||
|
||||
#define V(a, b, c, d) 0x##d##a##b##c
|
||||
static const uint32_t RT3[256] = { RT };
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
|
||||
#undef V
|
||||
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
|
||||
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
|
||||
|
||||
#undef RT
|
||||
|
||||
#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint32_t RCON[10] =
|
||||
MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
|
||||
{
|
||||
0x00000001, 0x00000002, 0x00000004, 0x00000008,
|
||||
0x00000010, 0x00000020, 0x00000040, 0x00000080,
|
||||
0x0000001B, 0x00000036
|
||||
};
|
||||
#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
|
||||
|
||||
#else /* MBEDTLS_AES_ROM_TABLES */
|
||||
|
||||
/*
|
||||
* Forward S-box & tables
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
static unsigned char FSb[256];
|
||||
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
|
||||
#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
|
||||
static uint32_t FT0[256];
|
||||
#if !defined(MBEDTLS_AES_FEWER_TABLES)
|
||||
static uint32_t FT1[256];
|
||||
static uint32_t FT2[256];
|
||||
static uint32_t FT3[256];
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
|
||||
MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
|
||||
|
||||
/*
|
||||
* Reverse S-box & tables
|
||||
*/
|
||||
#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
|
||||
static unsigned char RSb[256];
|
||||
#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
|
||||
MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
|
||||
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
static uint32_t RT0[256];
|
||||
#if !defined(MBEDTLS_AES_FEWER_TABLES)
|
||||
static uint32_t RT1[256];
|
||||
static uint32_t RT2[256];
|
||||
static uint32_t RT3[256];
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
|
||||
|
||||
#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static uint32_t RCON[10];
|
||||
MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
|
||||
|
||||
/*
|
||||
* Tables generation code
|
||||
@ -404,9 +370,9 @@ static uint32_t RCON[10];
|
||||
#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
|
||||
#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
|
||||
|
||||
static int aes_init_done = 0;
|
||||
MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
|
||||
|
||||
static void aes_gen_tables(void)
|
||||
MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t x, y, z;
|
||||
@ -426,7 +392,7 @@ static void aes_gen_tables(void)
|
||||
* calculate the round constants
|
||||
*/
|
||||
for (i = 0, x = 1; i < 10; i++) {
|
||||
RCON[i] = x;
|
||||
round_constants[i] = x;
|
||||
x = XTIME(x);
|
||||
}
|
||||
|
||||
@ -434,7 +400,9 @@ static void aes_gen_tables(void)
|
||||
* generate the forward and reverse S-boxes
|
||||
*/
|
||||
FSb[0x00] = 0x63;
|
||||
#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
|
||||
RSb[0x63] = 0x00;
|
||||
#endif
|
||||
|
||||
for (i = 1; i < 256; i++) {
|
||||
x = pow[255 - log[i]];
|
||||
@ -446,7 +414,9 @@ static void aes_gen_tables(void)
|
||||
x ^= y ^ 0x63;
|
||||
|
||||
FSb[i] = x;
|
||||
#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
|
||||
RSb[x] = (unsigned char) i;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -468,9 +438,9 @@ static void aes_gen_tables(void)
|
||||
FT3[i] = ROTL8(FT2[i]);
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
|
||||
#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
|
||||
x = RSb[i];
|
||||
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
|
||||
((uint32_t) MUL(0x09, x) << 8) ^
|
||||
((uint32_t) MUL(0x0D, x) << 16) ^
|
||||
@ -481,12 +451,10 @@ static void aes_gen_tables(void)
|
||||
RT2[i] = ROTL8(RT1[i]);
|
||||
RT3[i] = ROTL8(RT2[i]);
|
||||
#endif /* !MBEDTLS_AES_FEWER_TABLES */
|
||||
#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
|
||||
#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
|
||||
|
||||
#undef ROTL8
|
||||
|
||||
#endif /* MBEDTLS_AES_ROM_TABLES */
|
||||
@ -564,9 +532,7 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
|
||||
#define MAY_NEED_TO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_ENC_ALT)
|
||||
static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||
MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||
{
|
||||
#if defined(MAY_NEED_TO_ALIGN)
|
||||
int align_16_bytes = 0;
|
||||
@ -602,8 +568,6 @@ static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
|
||||
!defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
|
||||
|
||||
/*
|
||||
* AES key schedule (encryption)
|
||||
@ -654,7 +618,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
case 10:
|
||||
|
||||
for (unsigned int i = 0; i < 10; i++, RK += 4) {
|
||||
RK[4] = RK[0] ^ RCON[i] ^
|
||||
RK[4] = RK[0] ^ round_constants[i] ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
|
||||
@ -670,7 +634,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
case 12:
|
||||
|
||||
for (unsigned int i = 0; i < 8; i++, RK += 6) {
|
||||
RK[6] = RK[0] ^ RCON[i] ^
|
||||
RK[6] = RK[0] ^ round_constants[i] ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
|
||||
@ -687,7 +651,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
case 14:
|
||||
|
||||
for (unsigned int i = 0; i < 7; i++, RK += 8) {
|
||||
RK[8] = RK[0] ^ RCON[i] ^
|
||||
RK[8] = RK[0] ^ round_constants[i] ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
|
||||
((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
|
||||
@ -719,7 +683,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
/*
|
||||
* AES key schedule (decryption)
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
|
||||
#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
{
|
||||
@ -788,7 +752,7 @@ exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
|
||||
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
|
||||
@ -977,7 +941,7 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
||||
/*
|
||||
* AES-ECB block decryption
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT)
|
||||
#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16])
|
||||
@ -1034,9 +998,8 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !MBEDTLS_AES_DECRYPT_ALT */
|
||||
#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
#if defined(MAY_NEED_TO_ALIGN)
|
||||
/* VIA Padlock and our intrinsics-based implementation of AESNI require
|
||||
* the round keys to be aligned on a 16-byte boundary. We take care of this
|
||||
* before creating them, but the AES context may have moved (this can happen
|
||||
@ -1044,7 +1007,7 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
* calls it might have a different alignment with respect to 16-byte memory.
|
||||
* So we may need to realign.
|
||||
*/
|
||||
static void aes_maybe_realign(mbedtls_aes_context *ctx)
|
||||
MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
|
||||
{
|
||||
unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
|
||||
if (new_offset != ctx->rk_offset) {
|
||||
@ -1054,7 +1017,6 @@ static void aes_maybe_realign(mbedtls_aes_context *ctx)
|
||||
ctx->rk_offset = new_offset;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AES-ECB block encryption/decryption
|
||||
@ -1091,13 +1053,15 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
if (mode == MBEDTLS_AES_ENCRYPT) {
|
||||
return mbedtls_internal_aes_encrypt(ctx, input, output);
|
||||
} else {
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
return mbedtls_internal_aes_decrypt(ctx, input, output);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
||||
{
|
||||
return mbedtls_internal_aes_encrypt(ctx, input, output);
|
||||
}
|
||||
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
@ -1478,36 +1442,38 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output)
|
||||
{
|
||||
int c, i;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
|
||||
n = *nc_off;
|
||||
size_t offset = *nc_off;
|
||||
|
||||
if (n > 0x0F) {
|
||||
if (offset > 0x0F) {
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
while (length--) {
|
||||
if (n == 0) {
|
||||
for (size_t i = 0; i < length;) {
|
||||
size_t n = 16;
|
||||
if (offset == 0) {
|
||||
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
if (++nonce_counter[i - 1] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mbedtls_ctr_increment_counter(nonce_counter);
|
||||
} else {
|
||||
n -= offset;
|
||||
}
|
||||
c = *input++;
|
||||
*output++ = (unsigned char) (c ^ stream_block[n]);
|
||||
|
||||
n = (n + 1) & 0x0F;
|
||||
if (n > (length - i)) {
|
||||
n = (length - i);
|
||||
}
|
||||
mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
|
||||
// offset might be non-zero for the last block, but in that case, we don't use it again
|
||||
offset = 0;
|
||||
i += n;
|
||||
}
|
||||
|
||||
*nc_off = n;
|
||||
// capture offset for future resumption
|
||||
*nc_off = (*nc_off + length) % 16;
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
@ -1523,6 +1489,7 @@ exit:
|
||||
*
|
||||
* http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
static const unsigned char aes_test_ecb_dec[][16] =
|
||||
{
|
||||
{ 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
|
||||
@ -1534,6 +1501,7 @@ static const unsigned char aes_test_ecb_dec[][16] =
|
||||
0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
static const unsigned char aes_test_ecb_enc[][16] =
|
||||
{
|
||||
@ -1915,7 +1883,7 @@ int mbedtls_aes_self_test(int verbose)
|
||||
*/
|
||||
{
|
||||
static const int num_tests =
|
||||
sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
|
||||
sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
|
||||
|
||||
for (i = 0; i < num_tests << 1; i++) {
|
||||
u = i >> 1;
|
||||
@ -1926,13 +1894,24 @@ int mbedtls_aes_self_test(int verbose)
|
||||
mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
|
||||
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
|
||||
}
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("skipped\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(buf, 0, 16);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
|
||||
aes_tests = aes_test_ecb_dec[u];
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
|
||||
aes_tests = aes_test_ecb_enc[u];
|
||||
}
|
||||
|
179
library/aesce.c
179
library/aesce.c
@ -5,8 +5,17 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \
|
||||
defined(__clang__) && __clang_major__ >= 4
|
||||
#if defined(__clang__) && (__clang_major__ >= 4)
|
||||
|
||||
/* Ideally, we would simply use MBEDTLS_ARCH_IS_ARMV8_A in the following #if,
|
||||
* but that is defined by build_info.h, and we need this block to happen first. */
|
||||
#if defined(__ARM_ARCH)
|
||||
#if __ARM_ARCH >= 8
|
||||
#define MBEDTLS_AESCE_ARCH_IS_ARMV8_A
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESCE_ARCH_IS_ARMV8_A) && !defined(__ARM_FEATURE_CRYPTO)
|
||||
/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged.
|
||||
*
|
||||
* The intrinsic declaration are guarded by predefined ACLE macros in clang:
|
||||
@ -14,7 +23,7 @@
|
||||
* By defining the macros ourselves we gain access to those declarations without
|
||||
* requiring -march on the command line.
|
||||
*
|
||||
* `arm_neon.h` could be included by any header file, so we put these defines
|
||||
* `arm_neon.h` is included by common.h, so we put these defines
|
||||
* at the top of this file, before any includes.
|
||||
*/
|
||||
#define __ARM_FEATURE_CRYPTO 1
|
||||
@ -27,6 +36,8 @@
|
||||
#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG
|
||||
#endif
|
||||
|
||||
#endif /* defined(__clang__) && (__clang_major__ >= 4) */
|
||||
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
|
||||
@ -34,12 +45,14 @@
|
||||
|
||||
#include "aesce.h"
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
#if defined(MBEDTLS_AESCE_HAVE_CODE)
|
||||
|
||||
/* Compiler version checks. */
|
||||
#if defined(__clang__)
|
||||
# if __clang_major__ < 4
|
||||
# error "Minimum version of Clang for MBEDTLS_AESCE_C is 4.0."
|
||||
# if defined(MBEDTLS_ARCH_IS_ARM32) && (__clang_major__ < 11)
|
||||
# error "Minimum version of Clang for MBEDTLS_AESCE_C on 32-bit Arm or Thumb is 11.0."
|
||||
# elif defined(MBEDTLS_ARCH_IS_ARM64) && (__clang_major__ < 4)
|
||||
# error "Minimum version of Clang for MBEDTLS_AESCE_C on aarch64 is 4.0."
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if __GNUC__ < 6
|
||||
@ -52,12 +65,15 @@
|
||||
# if _MSC_VER < 1929
|
||||
# error "Minimum version of MSVC for MBEDTLS_AESCE_C is 2019 version 16.11.2."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
#include <arm_neon.h>
|
||||
#else
|
||||
#error "Target does not support NEON instructions"
|
||||
#elif defined(__ARMCC_VERSION)
|
||||
# if defined(MBEDTLS_ARCH_IS_ARM32) && (__ARMCC_VERSION < 6200002)
|
||||
/* TODO: We haven't verified armclang for 32-bit Arm/Thumb prior to 6.20.
|
||||
* If someone verified that, please update this and document of
|
||||
* `MBEDTLS_AESCE_C` in `mbedtls_config.h`. */
|
||||
# error "Minimum version of armclang for MBEDTLS_AESCE_C on 32-bit Arm is 6.20."
|
||||
# elif defined(MBEDTLS_ARCH_IS_ARM64) && (__ARMCC_VERSION < 6060000)
|
||||
# error "Minimum version of armclang for MBEDTLS_AESCE_C on aarch64 is 6.6."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !(defined(__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)) || \
|
||||
@ -84,8 +100,19 @@
|
||||
|
||||
#if defined(__linux__) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
|
||||
#include <asm/hwcap.h>
|
||||
#include <sys/auxv.h>
|
||||
#if !defined(HWCAP_NEON)
|
||||
#define HWCAP_NEON (1 << 12)
|
||||
#endif
|
||||
#if !defined(HWCAP2_AES)
|
||||
#define HWCAP2_AES (1 << 0)
|
||||
#endif
|
||||
#if !defined(HWCAP_AES)
|
||||
#define HWCAP_AES (1 << 3)
|
||||
#endif
|
||||
#if !defined(HWCAP_ASIMD)
|
||||
#define HWCAP_ASIMD (1 << 1)
|
||||
#endif
|
||||
|
||||
signed char mbedtls_aesce_has_support_result = -1;
|
||||
|
||||
@ -102,6 +129,16 @@ int mbedtls_aesce_has_support_impl(void)
|
||||
* once, but that is harmless.
|
||||
*/
|
||||
if (mbedtls_aesce_has_support_result == -1) {
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM32)
|
||||
unsigned long auxval = getauxval(AT_HWCAP);
|
||||
unsigned long auxval2 = getauxval(AT_HWCAP2);
|
||||
if (((auxval & HWCAP_NEON) == HWCAP_NEON) &&
|
||||
((auxval2 & HWCAP2_AES) == HWCAP2_AES)) {
|
||||
mbedtls_aesce_has_support_result = 1;
|
||||
} else {
|
||||
mbedtls_aesce_has_support_result = 0;
|
||||
}
|
||||
#else
|
||||
unsigned long auxval = getauxval(AT_HWCAP);
|
||||
if ((auxval & (HWCAP_ASIMD | HWCAP_AES)) ==
|
||||
(HWCAP_ASIMD | HWCAP_AES)) {
|
||||
@ -109,6 +146,7 @@ int mbedtls_aesce_has_support_impl(void)
|
||||
} else {
|
||||
mbedtls_aesce_has_support_result = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return mbedtls_aesce_has_support_result;
|
||||
}
|
||||
@ -187,6 +225,7 @@ rounds_10:
|
||||
/* Two rounds of AESCE decryption */
|
||||
#define AESCE_DECRYPT_ROUND_X2 AESCE_DECRYPT_ROUND; AESCE_DECRYPT_ROUND
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
static uint8x16_t aesce_decrypt_block(uint8x16_t block,
|
||||
unsigned char *keys,
|
||||
int rounds)
|
||||
@ -218,6 +257,7 @@ rounds_10:
|
||||
|
||||
return block;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AES-ECB block en(de)cryption
|
||||
@ -230,10 +270,15 @@ int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
uint8x16_t block = vld1q_u8(&input[0]);
|
||||
unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset);
|
||||
|
||||
if (mode == MBEDTLS_AES_ENCRYPT) {
|
||||
block = aesce_encrypt_block(block, keys, ctx->nr);
|
||||
} else {
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
block = aesce_decrypt_block(block, keys, ctx->nr);
|
||||
} else
|
||||
#else
|
||||
(void) mode;
|
||||
#endif
|
||||
{
|
||||
block = aesce_encrypt_block(block, keys, ctx->nr);
|
||||
}
|
||||
vst1q_u8(&output[0], block);
|
||||
|
||||
@ -243,6 +288,7 @@ int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
/*
|
||||
* Compute decryption round keys from encryption round keys
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
void mbedtls_aesce_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey,
|
||||
int nr)
|
||||
@ -257,6 +303,7 @@ void mbedtls_aesce_inverse_key(unsigned char *invkey,
|
||||
vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t aes_rot_word(uint32_t word)
|
||||
{
|
||||
@ -300,7 +347,7 @@ static void aesce_setkey_enc(unsigned char *rk,
|
||||
rki + key_len_in_words < rko_end;
|
||||
rki += key_len_in_words) {
|
||||
|
||||
size_t iteration = (rki - (uint32_t *) rk) / key_len_in_words;
|
||||
size_t iteration = (size_t) (rki - (uint32_t *) rk) / key_len_in_words;
|
||||
uint32_t *rko;
|
||||
rko = rki + key_len_in_words;
|
||||
rko[0] = aes_rot_word(aes_sub_word(rki[key_len_in_words - 1]));
|
||||
@ -353,24 +400,91 @@ int mbedtls_aesce_setkey_enc(unsigned char *rk,
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 5
|
||||
/* Some intrinsics are not available for GCC 5.X. */
|
||||
#define vreinterpretq_p64_u8(a) ((poly64x2_t) a)
|
||||
#define vreinterpretq_u8_p128(a) ((uint8x16_t) a)
|
||||
static inline poly64_t vget_low_p64(poly64x2_t __a)
|
||||
#if defined(MBEDTLS_ARCH_IS_ARM32)
|
||||
|
||||
#if defined(__clang__)
|
||||
/* On clang for A32/T32, work around some missing intrinsics and types which are listed in
|
||||
* [ACLE](https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#polynomial-1)
|
||||
* These are only required for GCM.
|
||||
*/
|
||||
#define vreinterpretq_u64_p64(a) ((uint64x2_t) a)
|
||||
|
||||
typedef uint8x16_t poly128_t;
|
||||
|
||||
static inline poly128_t vmull_p64(poly64_t a, poly64_t b)
|
||||
{
|
||||
uint64x2_t tmp = (uint64x2_t) (__a);
|
||||
uint64x1_t lo = vcreate_u64(vgetq_lane_u64(tmp, 0));
|
||||
return (poly64_t) (lo);
|
||||
poly128_t r;
|
||||
asm ("vmull.p64 %[r], %[a], %[b]" : [r] "=w" (r) : [a] "w" (a), [b] "w" (b) :);
|
||||
return r;
|
||||
}
|
||||
#endif /* !__clang__ && __GNUC__ && __GNUC__ == 5*/
|
||||
|
||||
/* This is set to cause some more missing intrinsics to be defined below */
|
||||
#define COMMON_MISSING_INTRINSICS
|
||||
|
||||
static inline poly128_t vmull_high_p64(poly64x2_t a, poly64x2_t b)
|
||||
{
|
||||
return vmull_p64((poly64_t) (vget_high_u64((uint64x2_t) a)),
|
||||
(poly64_t) (vget_high_u64((uint64x2_t) b)));
|
||||
}
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
|
||||
static inline uint8x16_t vrbitq_u8(uint8x16_t x)
|
||||
{
|
||||
/* There is no vrbitq_u8 instruction in A32/T32, so provide
|
||||
* an equivalent non-Neon implementation. Reverse bit order in each
|
||||
* byte with 4x rbit, rev. */
|
||||
asm ("ldm %[p], { r2-r5 } \n\t"
|
||||
"rbit r2, r2 \n\t"
|
||||
"rev r2, r2 \n\t"
|
||||
"rbit r3, r3 \n\t"
|
||||
"rev r3, r3 \n\t"
|
||||
"rbit r4, r4 \n\t"
|
||||
"rev r4, r4 \n\t"
|
||||
"rbit r5, r5 \n\t"
|
||||
"rev r5, r5 \n\t"
|
||||
"stm %[p], { r2-r5 } \n\t"
|
||||
:
|
||||
/* Output: 16 bytes of memory pointed to by &x */
|
||||
"+m" (*(uint8_t(*)[16]) &x)
|
||||
:
|
||||
[p] "r" (&x)
|
||||
:
|
||||
"r2", "r3", "r4", "r5"
|
||||
);
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_ARCH_IS_ARM32) */
|
||||
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && __GNUC__ == 5
|
||||
/* Some intrinsics are not available for GCC 5.X. */
|
||||
#define COMMON_MISSING_INTRINSICS
|
||||
#endif /* MBEDTLS_COMPILER_IS_GCC && __GNUC__ == 5 */
|
||||
|
||||
|
||||
#if defined(COMMON_MISSING_INTRINSICS)
|
||||
|
||||
/* Missing intrinsics common to both GCC 5, and Clang on 32-bit */
|
||||
|
||||
#define vreinterpretq_p64_u8(a) ((poly64x2_t) a)
|
||||
#define vreinterpretq_u8_p128(a) ((uint8x16_t) a)
|
||||
|
||||
static inline poly64x1_t vget_low_p64(poly64x2_t a)
|
||||
{
|
||||
uint64x1_t r = vget_low_u64(vreinterpretq_u64_p64(a));
|
||||
return (poly64x1_t) r;
|
||||
|
||||
}
|
||||
|
||||
#endif /* COMMON_MISSING_INTRINSICS */
|
||||
|
||||
/* vmull_p64/vmull_high_p64 wrappers.
|
||||
*
|
||||
* Older compilers miss some intrinsic functions for `poly*_t`. We use
|
||||
* uint8x16_t and uint8x16x3_t as input/output parameters.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC)
|
||||
/* GCC reports incompatible type error without cast. GCC think poly64_t and
|
||||
* poly64x1_t are different, that is different with MSVC and Clang. */
|
||||
#define MBEDTLS_VMULL_P64(a, b) vmull_p64((poly64_t) a, (poly64_t) b)
|
||||
@ -379,14 +493,15 @@ static inline poly64_t vget_low_p64(poly64x2_t __a)
|
||||
* error with/without cast. And I think poly64_t and poly64x1_t are same, no
|
||||
* cast for clang also. */
|
||||
#define MBEDTLS_VMULL_P64(a, b) vmull_p64(a, b)
|
||||
#endif
|
||||
#endif /* MBEDTLS_COMPILER_IS_GCC */
|
||||
|
||||
static inline uint8x16_t pmull_low(uint8x16_t a, uint8x16_t b)
|
||||
{
|
||||
|
||||
return vreinterpretq_u8_p128(
|
||||
MBEDTLS_VMULL_P64(
|
||||
vget_low_p64(vreinterpretq_p64_u8(a)),
|
||||
vget_low_p64(vreinterpretq_p64_u8(b))
|
||||
(poly64_t) vget_low_p64(vreinterpretq_p64_u8(a)),
|
||||
(poly64_t) vget_low_p64(vreinterpretq_p64_u8(b))
|
||||
));
|
||||
}
|
||||
|
||||
@ -455,7 +570,7 @@ static inline uint8x16_t poly_mult_reduce(uint8x16x3_t input)
|
||||
/* use 'asm' as an optimisation barrier to prevent loading MODULO from
|
||||
* memory. It is for GNUC compatible compilers.
|
||||
*/
|
||||
asm ("" : "+w" (r));
|
||||
asm volatile ("" : "+w" (r));
|
||||
#endif
|
||||
uint8x16_t const MODULO = vreinterpretq_u8_u64(vshrq_n_u64(r, 64 - 8));
|
||||
uint8x16_t h, m, l; /* input high/middle/low 128b */
|
||||
@ -498,6 +613,6 @@ void mbedtls_aesce_gcm_mult(unsigned char c[16],
|
||||
#undef MBEDTLS_POP_TARGET_PRAGMA
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ARCH_IS_ARM64 */
|
||||
#endif /* MBEDTLS_AESCE_HAVE_CODE */
|
||||
|
||||
#endif /* MBEDTLS_AESCE_C */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* \file aesce.h
|
||||
*
|
||||
* \brief Support hardware AES acceleration on Armv8-A processors with
|
||||
* the Armv8-A Cryptographic Extension in AArch64 execution state.
|
||||
* the Armv8-A Cryptographic Extension.
|
||||
*
|
||||
* \warning These functions are only for internal use by other library
|
||||
* functions; you must not call them directly.
|
||||
@ -15,12 +15,18 @@
|
||||
#define MBEDTLS_AESCE_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
|
||||
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
#if defined(MBEDTLS_AESCE_C) \
|
||||
&& defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_HAVE_NEON_INTRINSICS) \
|
||||
&& (defined(MBEDTLS_COMPILER_IS_GCC) || defined(__clang__) || defined(MSC_VER))
|
||||
|
||||
/* MBEDTLS_AESCE_HAVE_CODE is defined if we have a suitable target platform, and a
|
||||
* potentially suitable compiler (compiler version & flags are not checked when defining
|
||||
* this). */
|
||||
#define MBEDTLS_AESCE_HAVE_CODE
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -87,6 +93,7 @@ void mbedtls_aesce_gcm_mult(unsigned char c[16],
|
||||
const unsigned char b[16]);
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief Internal round key inversion. This function computes
|
||||
* decryption round keys from the encryption round keys.
|
||||
@ -98,6 +105,7 @@ void mbedtls_aesce_gcm_mult(unsigned char c[16],
|
||||
void mbedtls_aesce_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey,
|
||||
int nr);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief Internal key expansion for encryption
|
||||
@ -116,6 +124,13 @@ int mbedtls_aesce_setkey_enc(unsigned char *rk,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARM64 */
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && defined(MBEDTLS_ARCH_IS_ARMV8_A)
|
||||
#error "AES hardware acceleration not supported on this platform / compiler"
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARMV8_A && MBEDTLS_HAVE_NEON_INTRINSICS &&
|
||||
(MBEDTLS_COMPILER_IS_GCC || __clang__ || MSC_VER) */
|
||||
|
||||
#endif /* MBEDTLS_AESCE_H */
|
||||
|
@ -21,14 +21,27 @@
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
|
||||
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__GNUC__)
|
||||
#include <cpuid.h>
|
||||
#else
|
||||
#elif defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#error "`__cpuid` required by MBEDTLS_AESNI_C is not supported by the compiler"
|
||||
#endif
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ARCH_IS_X86)
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC)
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target ("pclmul,sse2,aes")
|
||||
#define MBEDTLS_POP_TARGET_PRAGMA
|
||||
#elif defined(__clang__) && (__clang_major__ >= 5)
|
||||
#pragma clang attribute push (__attribute__((target("pclmul,sse2,aes"))), apply_to=function)
|
||||
#define MBEDTLS_POP_TARGET_PRAGMA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
/*
|
||||
* AES-NI support detection routine
|
||||
@ -40,7 +53,7 @@ int mbedtls_aesni_has_support(unsigned int what)
|
||||
|
||||
if (!done) {
|
||||
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
static unsigned info[4] = { 0, 0, 0, 0 };
|
||||
static int info[4] = { 0, 0, 0, 0 };
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(info, 1);
|
||||
#else
|
||||
@ -81,14 +94,19 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
++rk;
|
||||
--nr;
|
||||
|
||||
if (mode == 0) {
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (mode == MBEDTLS_AES_DECRYPT) {
|
||||
while (nr != 0) {
|
||||
state = _mm_aesdec_si128(state, *rk);
|
||||
++rk;
|
||||
--nr;
|
||||
}
|
||||
state = _mm_aesdeclast_si128(state, *rk);
|
||||
} else {
|
||||
} else
|
||||
#else
|
||||
(void) mode;
|
||||
#endif
|
||||
{
|
||||
while (nr != 0) {
|
||||
state = _mm_aesenc_si128(state, *rk);
|
||||
++rk;
|
||||
@ -175,7 +193,7 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
const unsigned char a[16],
|
||||
const unsigned char b[16])
|
||||
{
|
||||
__m128i aa, bb, cc, dd;
|
||||
__m128i aa = { 0 }, bb = { 0 }, cc, dd;
|
||||
|
||||
/* The inputs are in big-endian order, so byte-reverse them */
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
@ -205,6 +223,7 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
/*
|
||||
* Compute decryption round keys from encryption round keys
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey, int nr)
|
||||
{
|
||||
@ -217,6 +236,7 @@ void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
}
|
||||
*ik = *fk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Key expansion, 128-bit case
|
||||
@ -384,6 +404,15 @@ static void aesni_setkey_enc_256(unsigned char *rk_bytes,
|
||||
}
|
||||
#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
|
||||
|
||||
#if defined(MBEDTLS_POP_TARGET_PRAGMA)
|
||||
#if defined(__clang__)
|
||||
#pragma clang attribute pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
#undef MBEDTLS_POP_TARGET_PRAGMA
|
||||
#endif
|
||||
|
||||
#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */
|
||||
|
||||
#if defined(__has_feature)
|
||||
@ -443,6 +472,7 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
"jnz 1b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESENCLAST(xmm1_xmm0) // last round
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
"jmp 3f \n\t"
|
||||
|
||||
"2: \n\t" // decryption loop
|
||||
@ -453,6 +483,7 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
"jnz 2b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESDECLAST(xmm1_xmm0) // last round
|
||||
#endif
|
||||
|
||||
"3: \n\t"
|
||||
"movdqu %%xmm0, (%4) \n\t" // export output
|
||||
@ -579,6 +610,7 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
/*
|
||||
* Compute decryption round keys from encryption round keys
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey, int nr)
|
||||
{
|
||||
@ -598,6 +630,7 @@ void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
|
||||
memcpy(ik, fk, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Key expansion, 128-bit case
|
||||
|
@ -27,7 +27,7 @@
|
||||
* (Only implemented with certain compilers, only for certain targets.)
|
||||
*/
|
||||
#undef MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
|
||||
* VS 2013 and up for other reasons anyway, so no need to check the version. */
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
@ -35,7 +35,11 @@
|
||||
/* GCC-like compilers: currently, we only support intrinsics if the requisite
|
||||
* target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2`
|
||||
* or `clang -maes -mpclmul`). */
|
||||
#if defined(__GNUC__) && defined(__AES__) && defined(__PCLMUL__)
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__)
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#endif
|
||||
/* For 32-bit, we only support intrinsics */
|
||||
#if defined(MBEDTLS_ARCH_IS_X86) && (defined(__GNUC__) || defined(__clang__))
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#endif
|
||||
|
||||
@ -48,13 +52,11 @@
|
||||
#if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
|
||||
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
|
||||
#elif defined(MBEDTLS_HAVE_ASM) && \
|
||||
defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X64)
|
||||
(defined(__GNUC__) || defined(__clang__)) && defined(MBEDTLS_ARCH_IS_X64)
|
||||
/* Can we do AESNI with inline assembly?
|
||||
* (Only implemented with gas syntax, only for 64-bit.)
|
||||
*/
|
||||
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
|
||||
#elif defined(__GNUC__)
|
||||
# error "Must use `-mpclmul -msse2 -maes` for MBEDTLS_AESNI_C"
|
||||
#else
|
||||
#error "MBEDTLS_AESNI_C defined, but neither intrinsics nor assembly available"
|
||||
#endif
|
||||
@ -117,6 +119,7 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
const unsigned char a[16],
|
||||
const unsigned char b[16]);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief Internal round key inversion. This function computes
|
||||
* decryption round keys from the encryption round keys.
|
||||
@ -131,6 +134,7 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey,
|
||||
int nr);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief Internal key expansion for encryption
|
||||
@ -153,6 +157,6 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk,
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
#endif /* MBEDTLS_AESNI_C */
|
||||
#endif /* MBEDTLS_AESNI_C && (MBEDTLS_ARCH_IS_X64 || MBEDTLS_ARCH_IS_X86) */
|
||||
|
||||
#endif /* MBEDTLS_AESNI_H */
|
||||
|
@ -23,11 +23,16 @@
|
||||
* efficient when this is not defined.
|
||||
*/
|
||||
#if defined(__ARM_FEATURE_UNALIGNED) \
|
||||
|| defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
|
||||
|| defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
|
||||
|| defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
/*
|
||||
* __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
|
||||
* (and later versions) for Arm v7 and later; all x86 platforms should have
|
||||
* efficient unaligned access.
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
|
||||
* specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached
|
||||
* device memory).
|
||||
*/
|
||||
#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
|
||||
#endif
|
||||
@ -175,6 +180,16 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#endif
|
||||
|
||||
/* Detect IAR built-in byteswap routine */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#if defined(__ARM_ACLE)
|
||||
#include <arm_acle.h>
|
||||
#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#define MBEDTLS_BSWAP64 __revll
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Where compiler built-ins are not present, fall back to C code that the
|
||||
* compiler may be able to detect and transform into the relevant bswap or
|
||||
@ -219,10 +234,25 @@ static inline uint64_t mbedtls_bswap64(uint64_t x)
|
||||
#endif /* !defined(MBEDTLS_BSWAP64) */
|
||||
|
||||
#if !defined(__BYTE_ORDER__)
|
||||
|
||||
#if defined(__LITTLE_ENDIAN__)
|
||||
/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
static const uint16_t mbedtls_byte_order_detector = { 0x100 };
|
||||
#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__))
|
||||
|
||||
#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__BYTE_ORDER__) */
|
||||
|
||||
/**
|
||||
|
@ -413,6 +413,7 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
|
||||
/*
|
||||
* Set decryption key
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key, unsigned int keybits)
|
||||
{
|
||||
@ -442,6 +443,7 @@ int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/*
|
||||
* Encrypt a block
|
||||
@ -872,12 +874,18 @@ int mbedtls_aria_self_test(int verbose)
|
||||
/* test ECB decryption */
|
||||
if (verbose) {
|
||||
mbedtls_printf(" ARIA-ECB-%d (dec): ", 128 + 64 * i);
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
mbedtls_printf("skipped\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
mbedtls_aria_setkey_dec(&ctx, aria_test1_ecb_key, 128 + 64 * i);
|
||||
mbedtls_aria_crypt_ecb(&ctx, aria_test1_ecb_ct[i], blk);
|
||||
ARIA_SELF_TEST_ASSERT(
|
||||
memcmp(blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE)
|
||||
!= 0);
|
||||
#endif
|
||||
}
|
||||
if (verbose) {
|
||||
mbedtls_printf("\n");
|
||||
|
@ -116,7 +116,7 @@ int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
*olen = p - dst;
|
||||
*olen = (size_t) (p - dst);
|
||||
*p = 0;
|
||||
|
||||
return 0;
|
||||
@ -225,7 +225,7 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
}
|
||||
}
|
||||
|
||||
*olen = p - dst;
|
||||
*olen = (size_t) (p - dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
|
||||
* 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)
|
||||
#if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_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
|
||||
@ -701,7 +702,7 @@ int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
|
||||
}
|
||||
|
||||
*p++ = '\0';
|
||||
*olen = p - buf;
|
||||
*olen = (size_t) (p - buf);
|
||||
|
||||
cleanup:
|
||||
|
||||
|
203
library/block_cipher.c
Normal file
203
library/block_cipher.c
Normal file
@ -0,0 +1,203 @@
|
||||
/**
|
||||
* \file block_cipher.c
|
||||
*
|
||||
* \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
|
||||
* for use by the GCM and CCM modules.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
|
||||
#include "block_cipher_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)
|
||||
{
|
||||
switch (cipher_id) {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return PSA_KEY_TYPE_AES;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return PSA_KEY_TYPE_ARIA;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return PSA_KEY_TYPE_CAMELLIA;
|
||||
#endif
|
||||
default:
|
||||
return PSA_KEY_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static int mbedtls_cipher_error_from_psa(psa_status_t status)
|
||||
{
|
||||
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors,
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_destroy_key(ctx->psa_key_id);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_free(&ctx->ctx.aes);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_free(&ctx->ctx.aria);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_free(&ctx->ctx.camellia);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id)
|
||||
{
|
||||
ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA :
|
||||
MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id);
|
||||
if (psa_key_type != PSA_KEY_TYPE_NONE &&
|
||||
psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) {
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA;
|
||||
return 0;
|
||||
}
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY;
|
||||
#endif
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_init(&ctx->ctx.aes);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_init(&ctx->ctx.aria);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_init(&ctx->ctx.camellia);
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen)
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id));
|
||||
psa_set_key_bits(&key_attr, key_bitlen);
|
||||
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
|
||||
|
||||
status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16])
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_status_t status;
|
||||
size_t olen;
|
||||
|
||||
status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
input, 16, output, 16, &olen);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia,
|
||||
MBEDTLS_CAMELLIA_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_C */
|
99
library/block_cipher_internal.h
Normal file
99
library/block_cipher_internal.h
Normal file
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* \file block_cipher_internal.h
|
||||
*
|
||||
* \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
|
||||
* for use by the GCM and CCM modules.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BLOCK_CIPHER_INTERNAL_H
|
||||
#define MBEDTLS_BLOCK_CIPHER_INTERNAL_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#include "mbedtls/block_cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize the context.
|
||||
* This must be the first API call before using the context.
|
||||
*
|
||||
* \param ctx The context to initialize.
|
||||
*/
|
||||
static inline void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the block cipher to use with this context.
|
||||
* This must be called after mbedtls_block_cipher_init().
|
||||
*
|
||||
* \param ctx The context to set up.
|
||||
* \param cipher_id The identifier of the cipher to use.
|
||||
* This must be either AES, ARIA or Camellia.
|
||||
* Warning: this is a ::mbedtls_cipher_id_t,
|
||||
* not a ::mbedtls_block_cipher_id_t!
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if \p cipher_id was
|
||||
* invalid.
|
||||
*/
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id);
|
||||
|
||||
/**
|
||||
* \brief Set the key into the context.
|
||||
*
|
||||
* \param ctx The context to configure.
|
||||
* \param key The buffer holding the key material.
|
||||
* \param key_bitlen The size of the key in bits.
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not
|
||||
* properly set up before calling this function.
|
||||
* \retval One of #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH,
|
||||
* #MBEDTLS_ERR_ARIA_BAD_INPUT_DATA,
|
||||
* #MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA if \p key_bitlen is
|
||||
* invalid.
|
||||
*/
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen);
|
||||
|
||||
/**
|
||||
* \brief Encrypt one block (16 bytes) with the configured key.
|
||||
*
|
||||
* \param ctx The context holding the key.
|
||||
* \param input The buffer holding the input block. Must be 16 bytes.
|
||||
* \param output The buffer to which the output block will be written.
|
||||
* Must be writable and 16 bytes long.
|
||||
* This must either not overlap with \p input, or be equal.
|
||||
*
|
||||
* \retval \c 0 on success.
|
||||
* \retval #MBEDTLS_ERR_CIPHER_INVALID_CONTEXT if the context was not
|
||||
* properly set up before calling this function.
|
||||
* \retval Another negative value if encryption failed.
|
||||
*/
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
/**
|
||||
* \brief Clear the context.
|
||||
*
|
||||
* \param ctx The context to clear.
|
||||
*/
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_INTERNAL_H */
|
@ -399,6 +399,7 @@ int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
|
||||
/*
|
||||
* Camellia key schedule (decryption)
|
||||
*/
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits)
|
||||
@ -444,6 +445,7 @@ exit:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/*
|
||||
* Camellia-ECB block encryption/decryption
|
||||
@ -888,14 +890,26 @@ int mbedtls_camellia_self_test(int verbose)
|
||||
(v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (v == MBEDTLS_CAMELLIA_DECRYPT) {
|
||||
if (verbose != 0) {
|
||||
mbedtls_printf("skipped\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CAMELLIA_TESTS_ECB; i++) {
|
||||
memcpy(key, camellia_test_ecb_key[u][i], 16 + 8 * u);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
if (v == MBEDTLS_CAMELLIA_DECRYPT) {
|
||||
mbedtls_camellia_setkey_dec(&ctx, key, 128 + u * 64);
|
||||
memcpy(src, camellia_test_ecb_cipher[u][i], 16);
|
||||
memcpy(dst, camellia_test_ecb_plain[i], 16);
|
||||
} else { /* MBEDTLS_CAMELLIA_ENCRYPT */
|
||||
} else
|
||||
#endif
|
||||
{ /* MBEDTLS_CAMELLIA_ENCRYPT */
|
||||
mbedtls_camellia_setkey_enc(&ctx, key, 128 + u * 64);
|
||||
memcpy(src, camellia_test_ecb_plain[i], 16);
|
||||
memcpy(dst, camellia_test_ecb_cipher[u][i], 16);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user