update mbedtls form 3.4.1 to 3.6

Signed-off-by: liuxiyao223 <liuxiyao223@huawei.com>
Change-Id: If15c64caa51d9b004315f27563c98ea7f585bd17
This commit is contained in:
liuxiyao223
2024-05-22 19:58:50 +08:00
parent 82962ecaa4
commit 709079c421
866 changed files with 225817 additions and 43185 deletions
+9 -1
View File
@@ -4,7 +4,9 @@ Please write a few sentences describing the overall goals of the pull request's
## Gatekeeper checklist
## PR checklist
Please tick as appropriate and edit the reasons (e.g.: "backport: not needed because this is a new feature")
- [ ] **changelog** provided, or not required
- [ ] **backport** done, or not required
@@ -17,3 +19,9 @@ Please write a few sentences describing the overall goals of the pull request's
Please refer to the [contributing guidelines](https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md), especially the
checklist for PR contributors.
Help make review efficient:
* Multiple simple commits
- please structure your PR into a series of small commits, each of which does one thing
* Avoid force-push
- please do not force-push to update your PR - just add new commit(s)
* See our [Guidelines for Contributors](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/) for more details about the review process.
+10
View File
@@ -1,5 +1,7 @@
# Random seed file created by test scripts and sample programs
seedfile
# MBEDTLS_PSA_INJECT_ENTROPY seed file created by the test framework
00000000ffffff52.psa_its
# CMake build artifacts:
CMakeCache.txt
@@ -28,6 +30,9 @@ massif-*
.project
/.settings
# Unix-like build artifacts:
*.o
# MSVC build artifacts:
*.exe
*.pdb
@@ -57,3 +62,8 @@ massif-*
/TAGS
/cscope*.out
/tags
# clangd compilation database
compile_commands.json
# clangd index files
/.cache/clangd/index/
+3
View File
@@ -0,0 +1,3 @@
[submodule "framework"]
path = framework
url = https://github.com/Mbed-TLS/mbedtls-framework
+13 -2
View File
@@ -5,6 +5,11 @@
# Required
version: 2
# Include the framework submodule in the build
submodules:
include:
- framework
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
@@ -12,8 +17,14 @@ build:
python: "3.9"
jobs:
pre_build:
- make apidoc
- breathe-apidoc -o docs/api apidoc/xml
- ./scripts/apidoc_full.sh
- breathe-apidoc -o docs/api apidoc/xml
post_build:
- |
# Work around Readthedocs bug: Command parsing fails if the 'if' statement is on the first line
if [ "$READTHEDOCS_VERSION" = "development" ]; then
"$READTHEDOCS_VIRTUALENV_PATH/bin/rtd" projects "Mbed TLS API" redirects sync --wet-run -f docs/redirects.yaml
fi
# Build documentation in the docs/ directory with Sphinx
sphinx:
+11 -136
View File
@@ -1,149 +1,24 @@
# Declare python as our language. This way we get our chosen Python version,
# and pip is available. Gcc and clang are available anyway.
dist: jammy
os: linux
language: python
python: 3.5
sudo: false
python: 3.10
cache: ccache
jobs:
include:
- name: basic checks and reference configurations
addons:
apt:
packages:
- gnutls-bin
- doxygen
- graphviz
- gcc-arm-none-eabi
- libnewlib-arm-none-eabi
- gcc-arm-linux-gnueabi
- libc6-dev-armel-cross
script:
- tests/scripts/all.sh -k 'check_*'
- tests/scripts/all.sh -k test_default_out_of_box
- tests/scripts/all.sh -k test_ref_configs
- tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
- name: full configuration
os: linux
dist: focal
addons:
apt:
packages:
- clang-10
- gnutls-bin
script:
# Do a manual build+test sequence rather than using all.sh,
# because there's no all.sh component that does what we want,
# which is a build with Clang >= 10 and ASan, running all the SSL
# testing.
# - The clang executable in the default PATH is Clang 7 on
# Travis's focal instances, but we want Clang >= 10.
# - Running all the SSL testing requires a specific set of
# OpenSSL and GnuTLS versions and we don't want to bother
# with those on Travis.
# So we explicitly select clang-10 as the compiler, and we
# have ad hoc restrictions on SSL testing based on what is
# passing at the time of writing. We will remove these limitations
# gradually.
- make generated_files
- make CC=clang-10 CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all -O2' LDFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
- make test
- programs/test/selftest
- tests/scripts/test_psa_constant_names.py
- tests/ssl-opt.sh
# Modern OpenSSL does not support null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL'
- tests/scripts/travis-log-failure.sh
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
- name: Windows
os: windows
# The language 'python' is currently unsupported on the
# Windows Build Environment. And 'generic' causes the job to get stuck
# on "Booting virtual machine".
language: c
before_install:
- choco install python --version=3.5.4
env:
# Add the directory where the Choco packages go
- PATH=/c/Python35:/c/Python35/Scripts:$PATH
- PYTHON=python.exe
script:
- type perl; perl --version
- type python; python --version
- scripts/make_generated_files.bat
# Logs appear out of sequence on Windows. Give time to catch up.
- sleep 5
- scripts/windows_msbuild.bat v141 # Visual Studio 2017
- visualc/VS2013/x64/Release/selftest.exe
- name: full configuration on arm64
os: linux
dist: focal
arch: arm64
addons:
apt:
packages:
- gcc
script:
# Do a manual build+test sequence rather than using all.sh.
#
# On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
# limitation of Travis CI. Base on `test_full_cmake_*`, we removed
# `ssl-opt.sh` and GnuTLS compat.sh here to meet the time limitation.
- scripts/config.py full
- make generated_files
- make CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
- make test
- programs/test/selftest
- tests/scripts/test_psa_constant_names.py
# Modern OpenSSL does not support fixed ECDH or null ciphers.
- tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
- name: full configuration(GnuTLS compat tests) on arm64
os: linux
dist: focal
arch: arm64
addons:
apt:
packages:
- clang
- gnutls-bin
script:
# Do a manual build+test sequence rather than using all.sh.
#
# On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
# limitation of Travis CI. Base on `test_full_cmake_*`, we removed
# `ssl-opt.sh` and OpenSSl compat.sh here to meet the time limitation.
- scripts/config.py full
- make generated_files
- make CC=clang CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
- tests/scripts/travis-log-failure.sh
- tests/context-info.sh
after_failure:
- tests/scripts/travis-log-failure.sh
env:
global:
- SEED=1
- secure: "JECCru6HASpKZ0OLfHh8f/KXhKkdrCwjquZghd/qbA4ksxsWImjR7KEPERcaPndXEilzhDbKwuFvJiQX2duVgTGoq745YGhLZIjzo1i8tySkceCVd48P8WceYGz+F/bmY7r+m6fFNuxDSoGGSVeA4Lnjvmm8PFUP45YodDV9no4="
branches:
only:
coverity_scan
install:
- $PYTHON scripts/min_requirements.py
env:
global:
- SEED=1
- secure: "GF/Fde5fkm15T/RNykrjrPV5Uh1KJ70cP308igL6Xkk3eJmqkkmWCe9JqRH12J3TeWw2fu9PYPHt6iFSg6jasgqysfUyg+W03knRT5QNn3h5eHgt36cQJiJr6t3whPrRaiM6U9omE0evm+c0cAwlkA3GGSMw8Z+na4EnKI6OFCo="
addons:
apt:
packages:
- gnutls-bin
coverity_scan:
project:
name: "ARMmbed/mbedtls"
+1 -13
View File
@@ -4,19 +4,7 @@
# to Mbed TLS.
#
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
# Wrap lines at 100 characters
+2 -5
View File
@@ -1,5 +1,2 @@
execute_process(COMMAND ${MBEDTLS_PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../include/mbedtls/mbedtls_config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
if(${result} EQUAL 0)
add_subdirectory(everest)
endif()
add_subdirectory(everest)
add_subdirectory(p256-m)
+2 -1
View File
@@ -1,2 +1,3 @@
THIRDPARTY_DIR = $(dir $(lastword $(MAKEFILE_LIST)))
THIRDPARTY_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(THIRDPARTY_DIR)/everest/Makefile.inc
include $(THIRDPARTY_DIR)/p256-m/Makefile.inc
+18 -3
View File
@@ -1,9 +1,11 @@
add_library(everest
set(everest_target "${MBEDTLS_TARGET_PREFIX}everest")
add_library(${everest_target}
library/everest.c
library/x25519.c
library/Hacl_Curve25519_joined.c)
target_include_directories(everest
target_include_directories(${everest_target}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
$<INSTALL_INTERFACE:include>
@@ -11,6 +13,19 @@ target_include_directories(everest
include/everest/kremlib
${MBEDTLS_DIR}/library/)
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
# This must be duplicated from library/CMakeLists.txt because
# everest is not directly linked against any mbedtls targets
# so does not inherit the compile definitions.
if(MBEDTLS_CONFIG_FILE)
target_compile_definitions(${everest_target}
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
endif()
if(MBEDTLS_USER_CONFIG_FILE)
target_compile_definitions(${everest_target}
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
endif()
if(INSTALL_MBEDTLS_HEADERS)
install(DIRECTORY include/everest
@@ -21,7 +36,7 @@ if(INSTALL_MBEDTLS_HEADERS)
endif(INSTALL_MBEDTLS_HEADERS)
install(TARGETS everest
install(TARGETS ${everest_target}
EXPORT MbedTLSTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+4 -4
View File
@@ -1,6 +1,6 @@
THIRDPARTY_INCLUDES+=-I../3rdparty/everest/include -I../3rdparty/everest/include/everest -I../3rdparty/everest/include/everest/kremlib
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/everest/include -I$(THIRDPARTY_DIR)/everest/include/everest -I$(THIRDPARTY_DIR)/everest/include/everest/kremlib
THIRDPARTY_CRYPTO_OBJECTS+= \
../3rdparty/everest/library/everest.o \
../3rdparty/everest/library/x25519.o \
../3rdparty/everest/library/Hacl_Curve25519_joined.o
$(THIRDPARTY_DIR)/everest/library/everest.o \
$(THIRDPARTY_DIR)/everest/library/x25519.o \
$(THIRDPARTY_DIR)/everest/library/Hacl_Curve25519_joined.o
+40
View File
@@ -0,0 +1,40 @@
set(p256m_target ${MBEDTLS_TARGET_PREFIX}p256m)
add_library(${p256m_target}
p256-m_driver_entrypoints.c
p256-m/p256-m.c)
target_include_directories(${p256m_target}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/p256-m>
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${MBEDTLS_DIR}/library/)
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
# This must be duplicated from library/CMakeLists.txt because
# p256m is not directly linked against any mbedtls targets
# so does not inherit the compile definitions.
if(MBEDTLS_CONFIG_FILE)
target_compile_definitions(${p256m_target}
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
endif()
if(MBEDTLS_USER_CONFIG_FILE)
target_compile_definitions(${p256m_target}
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
endif()
if(INSTALL_MBEDTLS_HEADERS)
install(DIRECTORY :${CMAKE_CURRENT_SOURCE_DIR}
DESTINATION include
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
FILES_MATCHING PATTERN "*.h")
endif(INSTALL_MBEDTLS_HEADERS)
install(TARGETS ${p256m_target}
EXPORT MbedTLSTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+5
View File
@@ -0,0 +1,5 @@
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/p256-m/p256-m/include -I$(THIRDPARTY_DIR)/p256-m/p256-m/include/p256-m -I$(THIRDPARTY_DIR)/p256-m/p256-m_driver_interface
THIRDPARTY_CRYPTO_OBJECTS+= \
$(THIRDPARTY_DIR)/p256-m//p256-m_driver_entrypoints.o \
$(THIRDPARTY_DIR)/p256-m//p256-m/p256-m.o
+4
View File
@@ -0,0 +1,4 @@
The files within the `p256-m/` subdirectory originate from the [p256-m GitHub repository](https://github.com/mpg/p256-m). They are distributed here under a dual Apache-2.0 OR GPL-2.0-or-later license. They are authored by Manuel Pégourié-Gonnard. p256-m is a minimalistic implementation of ECDH and ECDSA on NIST P-256, especially suited to constrained 32-bit environments. Mbed TLS documentation for integrating drivers uses p256-m as an example of a software accelerator, and describes how it can be integrated alongside Mbed TLS. It should be noted that p256-m files in the Mbed TLS repo will not be updated regularly, so they may not have fixes and improvements present in the upstream project.
The files `p256-m.c`, `p256-m.h` and `README.md` have been taken from the `p256-m` repository.
It should be noted that p256-m deliberately does not supply its own cryptographically secure RNG function. As a result, the PSA RNG is used, with `p256_generate_random()` wrapping `psa_generate_random()`.
+544
View File
@@ -0,0 +1,544 @@
*This is the original README for the p256-m repository. Please note that as
only a subset of p256-m's files are present in Mbed TLS, this README may refer
to files that are not present/relevant here.*
p256-m is a minimalistic implementation of ECDH and ECDSA on NIST P-256,
especially suited to constrained 32-bit environments. It's written in standard
C, with optional bits of assembly for Arm Cortex-M and Cortex-A CPUs.
Its design is guided by the following goals in this order:
1. correctness & security;
2. low code size & RAM usage;
3. runtime performance.
Most cryptographic implementations care more about speed than footprint, and
some might even risk weakening security for more speed. p256-m was written
because I wanted to see what happened when reversing the usual emphasis.
The result is a full implementation of ECDH and ECDSA in **less than 3KiB of
code**, using **less than 768 bytes of RAM**, with comparable performance
to existing implementations (see below) - in less than 700 LOC.
_Contents of this Readme:_
- [Correctness](#correctness)
- [Security](#security)
- [Code size](#code-size)
- [RAM usage](#ram-usage)
- [Runtime performance](#runtime-performance)
- [Comparison with other implementations](#comparison-with-other-implementations)
- [Design overview](#design-overview)
- [Notes about other curves](#notes-about-other-curves)
- [Notes about other platforms](#notes-about-other-platforms)
## Correctness
**API design:**
- The API is minimal: only 4 public functions.
- Each public function fully validates its inputs and returns specific errors.
- The API uses arrays of octets for all input and output.
**Testing:**
- p256-m is validated against multiple test vectors from various RFCs and
NIST.
- In addition, crafted inputs are used for negative testing and to reach
corner cases.
- Two test suites are provided: one for closed-box testing (using only the
public API), one for open-box testing (for unit-testing internal functions,
and reaching more error cases by exploiting knowledge of how the RNG is used).
- The resulting branch coverage is maximal: closed-box testing reaches all
branches except four; three of them are reached by open-box testing using a
rigged RNG; the last branch could only be reached by computing a discrete log
on P-256... See `coverage.sh`.
- Testing also uses dynamic analysis: valgrind, ASan, MemSan, UBSan.
**Code quality:**
- The code is standard C99; it builds without warnings with `clang
-Weverything` and `gcc -Wall -Wextra -pedantic`.
- The code is small and well documented, including internal APIs: with the
header file, it's less than 700 lines of code, and more lines of comments
than of code.
- However it _has not been reviewed_ independently so far, as this is a
personal project.
**Short Weierstrass pitfalls:**
Its has been [pointed out](https://safecurves.cr.yp.to/) that the NIST curves,
and indeed all Short Weierstrass curves, have a number of pitfalls including
risk for the implementation to:
- "produce incorrect results for some rare curve points" - this is avoided by
carefully checking the validity domain of formulas used throughout the code;
- "leak secret data when the input isn't a curve point" - this is avoided by
validating that points lie on the curve every time a point is deserialized.
## Security
In addition to the above correctness claims, p256-m has the following
properties:
- it has no branch depending (even indirectly) on secret data;
- it has no memory access depending (even indirectly) on secret data.
These properties are checked using valgrind and MemSan with the ideas
behind [ctgrind](https://github.com/agl/ctgrind), see `consttime.sh`.
In addition to avoiding branches and memory accesses depending on secret data,
p256-m also avoid instructions (or library functions) whose execution time
depends on the value of operands on cores of interest. Namely, it never uses
integer division, and for multiplication by default it only uses 16x16->32 bit
unsigned multiplication. On cores which have a constant-time 32x32->64 bit
unsigned multiplication instruction, the symbol `MUL64_IS_CONSTANT_TIME` can
be defined by the user at compile-time to take advantage of it in order to
improve performance and code size. (On Cortex-M and Cortex-A cores wtih GCC or
Clang this is not necessary, since inline assembly is used instead.)
As a result, p256-m should be secure against the following classes of attackers:
1. attackers who can only manipulate the input and observe the output;
2. attackers who can also measure the total computation time of the operation;
3. attackers who can also observe and manipulate micro-architectural features
such as the cache or branch predictor with arbitrary precision.
However, p256-m makes no attempt to protect against:
4. passive physical attackers who can record traces of physical emissions
(power, EM, sound) of the CPU while it manipulates secrets;
5. active physical attackers who can also inject faults in the computation.
(Note: p256-m should actually be secure against SPA, by virtue of being fully
constant-flow, but is not expected to resist any other physical attack.)
**Warning:** p256-m requires an externally-provided RNG function. If that
function is not cryptographically secure, then neither is p256-m's key
generation or ECDSA signature generation.
_Note:_ p256-m also follows best practices such as securely erasing secret
data on the stack before returning.
## Code size
Compiled with
[ARM-GCC 9](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads),
with `-mthumb -Os`, here are samples of code sizes reached on selected cores:
- Cortex-M0: 2988 bytes
- Cortex-M4: 2900 bytes
- Cortex-A7: 2924 bytes
Clang was also tried but tends to generate larger code (by about 10%). For
details, see `sizes.sh`.
**What's included:**
- Full input validation and (de)serialisation of input/outputs to/from bytes.
- Cleaning up secret values from the stack before returning from a function.
- The code has no dependency on libc functions or the toolchain's runtime
library (such as helpers for long multiply); this can be checked for the
Arm-GCC toolchain with the `deps.sh` script.
**What's excluded:**
- A secure RNG function needs to be provided externally, see
`p256_generate_random()` in `p256-m.h`.
## RAM usage
p256-m doesn't use any dynamic memory (on the heap), only the stack. Here's
how much stack is used by each of its 4 public functions on selected cores:
| Function | Cortex-M0 | Cortex-M4 | Cortex-A7 |
| ------------------------- | --------: | --------: | --------: |
| `p256_gen_keypair` | 608 | 564 | 564 |
| `p256_ecdh_shared_secret` | 640 | 596 | 596 |
| `p256_ecdsa_sign` | 664 | 604 | 604 |
| `p256_ecdsa_verify` | 752 | 700 | 700 |
For details, see `stack.sh`, `wcs.py` and `libc.msu` (the above figures assume
that the externally-provided RNG function uses at most 384 bytes of stack).
## Runtime performance
Here are the timings of each public function in milliseconds measured on
platforms based on a selection of cores:
- Cortex-M0 at 48 MHz: STM32F091 board running Mbed OS 6
- Cortex-M4 at 100 MHz: STM32F411 board running Mbed OS 6
- Cortex-A7 at 900 MHz: Raspberry Pi 2B running Raspbian Buster
| Function | Cortex-M0 | Cortex-M4 | Cortex-A7 |
| ------------------------- | --------: | --------: | --------: |
| `p256_gen_keypair` | 921 | 145 | 11 |
| `p256_ecdh_shared_secret` | 922 | 144 | 11 |
| `p256_ecdsa_sign` | 990 | 155 | 12 |
| `p256_ecdsa_verify` | 1976 | 309 | 24 |
| Sum of the above | 4809 | 753 | 59 |
The sum of these operations corresponds to a TLS handshake using ECDHE-ECDSA
with mutual authentication based on raw public keys or directly-trusted
certificates (otherwise, add one 'verify' for each link in the peer's
certificate chain).
_Note_: the above figures where obtained by compiling with GCC, which is able
to use inline assembly. Without that inline assembly (22 lines for Cortex-M0,
1 line for Cortex-M4), the code would be roughly 2 times slower on those
platforms. (The effect is much less important on the Cortex-A7 core.)
For details, see `bench.sh`, `benchmark.c` and `on-target-benchmark/`.
## Comparison with other implementations
The most relevant/convenient implementation for comparisons is
[TinyCrypt](https://github.com/intel/tinycrypt), as it's also a standalone
implementation of ECDH and ECDSA on P-256 only, that also targets constrained
devices. Other implementations tend to implement many curves and build on a
shared bignum/MPI module (possibly also supporting RSA), which makes fair
comparisons less convenient.
The scripts used for TinyCrypt measurements are available in [this
branch](https://github.com/mpg/tinycrypt/tree/measurements), based on version
0.2.8.
**Code size**
| Core | p256-m | TinyCrypt |
| --------- | -----: | --------: |
| Cortex-M0 | 2988 | 6134 |
| Cortex-M4 | 2900 | 5934 |
| Cortex-A7 | 2924 | 5934 |
**RAM usage**
TinyCrypto also uses no heap, only the stack. Here's the RAM used by each
operation on a Cortex-M0 core:
| operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| key generation | 608 | 824 |
| ECDH shared secret | 640 | 728 |
| ECDSA sign | 664 | 880 |
| ECDSA verify | 752 | 824 |
On a Cortex-M4 or Cortex-A7 core (identical numbers):
| operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| key generation | 564 | 796 |
| ECDH shared secret | 596 | 700 |
| ECDSA sign | 604 | 844 |
| ECDSA verify | 700 | 808 |
**Runtime performance**
Here are the timings of each operation in milliseconds measured on
platforms based on a selection of cores:
_Cortex-M0_ at 48 MHz: STM32F091 board running Mbed OS 6
| Operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| Key generation | 921 | 979 |
| ECDH shared secret | 922 | 975 |
| ECDSA sign | 990 | 1009 |
| ECDSA verify | 1976 | 1130 |
| Sum of those 4 | 4809 | 4093 |
_Cortex-M4_ at 100 MHz: STM32F411 board running Mbed OS 6
| Operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| Key generation | 145 | 178 |
| ECDH shared secret | 144 | 177 |
| ECDSA sign | 155 | 188 |
| ECDSA verify | 309 | 210 |
| Sum of those 4 | 753 | 753 |
_Cortex-A7_ at 900 MHz: Raspberry Pi 2B running Raspbian Buster
| Operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| Key generation | 11 | 13 |
| ECDH shared secret | 11 | 13 |
| ECDSA sign | 12 | 14 |
| ECDSA verify | 24 | 15 |
| Sum of those 4 | 59 | 55 |
_64-bit Intel_ (i7-6500U at 2.50GHz) laptop running Ubuntu 20.04
Note: results in microseconds (previous benchmarks in milliseconds)
| Operation | p256-m | TinyCrypt |
| ------------------ | -----: | --------: |
| Key generation | 1060 | 1627 |
| ECDH shared secret | 1060 | 1611 |
| ECDSA sign | 1136 | 1712 |
| ECDSA verify | 2279 | 1888 |
| Sum of those 4 | 5535 | 6838 |
**Other differences**
- While p256-m fully validates all inputs, Tinycrypt's ECDH shared secret
function doesn't include validation of the peer's public key, which should be
done separately by the user for static ECDH (there are attacks [when users
forget](https://link.springer.com/chapter/10.1007/978-3-319-24174-6_21)).
- The two implementations have slightly different security characteristics:
p256-m is fully constant-time from the ground up so should be more robust
than TinyCrypt against powerful local attackers (such as an untrusted OS
attacking a secure enclave); on the other hand TinyCrypt includes coordinate
randomisation which protects against some passive physical attacks (such as
DPA, see Table 3, column C9 of [this
paper](https://www.esat.kuleuven.be/cosic/publications/article-2293.pdf#page=12)),
which p256-m completely ignores.
- TinyCrypt's code looks like it could easily be expanded to support other
curves, while p256-m has much more hard-coded to minimize code size (see
"Notes about other curves" below).
- TinyCrypt uses a specialised routine for reduction modulo the curve prime,
exploiting its structure as a Solinas prime, which should be faster than the
generic Montgomery reduction used by p256-m, but other factors appear to
compensate for that.
- TinyCrypt uses Co-Z Jacobian formulas for point operation, which should be
faster (though a bit larger) than the mixed affine-Jacobian formulas
used by p256-m, but again other factors appear to compensate for that.
- p256-m uses bits of inline assembly for 64-bit multiplication on the
platforms used for benchmarking, while TinyCrypt uses only C (and the
compiler's runtime library).
- TinyCrypt uses a specialised routine based on Shamir's trick for
ECDSA verification, which gives much better performance than the generic
code that p256-m uses in order to minimize code size.
## Design overview
The implementation is contained in a single file to keep most functions static
and allow for more optimisations. It is organized in multiple layers:
- Fixed-width multi-precision arithmetic
- Fixed-width modular arithmetic
- Operations on curve points
- Operations with scalars
- The public API
**Multi-precision arithmetic.**
Large integers are represented as arrays of `uint32_t` limbs. When carries may
occur, casts to `uint64_t` are used to nudge the compiler towards using the
CPU's carry flag. When overflow may occur, functions return a carry flag.
This layer contains optional assembly for Cortex-M and Cortex-A cores, for the
internal `u32_muladd64()` function, as well as two pure C versions of this
function, depending on whether `MUL64_IS_CONSTANT_TIME`.
This layer's API consists of:
- addition, subtraction;
- multiply-and-add, shift by one limb (for Montgomery multiplication);
- conditional assignment, assignment of a small value;
- comparison of two values for equality, comparison to 0 for equality;
- (de)serialization as big-endian arrays of bytes.
**Modular arithmetic.**
All modular operations are done in the Montgomery domain, that is x is
represented by `x * 2^256 mod m`; integers need to be converted to that domain
before computations, and back from it afterwards. Montgomery constants
associated to the curve's p and n are pre-computed and stored in static
structures.
Modular inversion is computed using Fermat's little theorem to get
constant-time behaviour with respect to the value being inverted.
This layer's API consists of:
- the curve's constants p and n (and associated Montgomery constants);
- modular addition, subtraction, multiplication, and inversion;
- assignment of a small value;
- conversion to/from Montgomery domain;
- (de)serialization to/from bytes with integrated range checking and
Montgomery domain conversion.
**Operations on curve points.**
Curve points are represented using either affine or Jacobian coordinates;
affine coordinates are extended to represent 0 as (0,0). Individual
coordinates are always in the Montgomery domain.
Not all formulas associated with affine or Jacobian coordinates are complete;
great care is taken to document and satisfy each function's pre-conditions.
This layer's API consists of:
- curve constants: b from the equation, the base point's coordinates;
- point validity check (on the curve and not 0);
- Jacobian to affine coordinate conversion;
- point doubling in Jacobian coordinates (complete formulas);
- point addition in mixed affine-Jacobian coordinates (P not in {0, Q, -Q});
- point addition-or-doubling in affine coordinates (leaky version, only used
for ECDSA verify where all data is public);
- (de)serialization to/from bytes with integrated validity checking
**Scalar operations.**
The crucial function here is scalar multiplication. It uses a signed binary
ladder, which is a variant of the good old double-and-add algorithm where an
addition/subtraction is performed at each step. Again, care is taken to make
sure the pre-conditions for the addition formulas are always satisfied. The
signed binary ladder only works if the scalar is odd; this is ensured by
negating both the scalar (mod n) and the input point if necessary.
This layer's API consists of:
- scalar multiplication
- de-serialization from bytes with integrated range checking
- generation of a scalar and its associated public key
**Public API.**
This layer builds on the others, but unlike them, all inputs and outputs are
byte arrays. Key generation and ECDH shared secret computation are thin
wrappers around internal functions, just taking care of format conversions and
errors. The ECDSA functions have more non-trivial logic.
This layer's API consists of:
- key-pair generation
- ECDH shared secret computation
- ECDSA signature creation
- ECDSA signature verification
**Testing.**
A self-contained, straightforward, pure-Python implementation was first
produced as a warm-up and to help check intermediate values. Test vectors from
various sources are embedded and used to validate the implementation.
This implementation, `p256.py`, is used by a second Python script,
`gen-test-data.py`, to generate additional data for both positive and negative
testing, available from a C header file, that is then used by the closed-box
and open-box test programs.
p256-m can be compiled with extra instrumentation to mark secret data and
allow either valgrind or MemSan to check that no branch or memory access
depends on it (even indirectly). Macros are defined for this purpose near the
top of the file.
**Tested platforms.**
There are 4 versions of the internal function `u32_muladd64`: two assembly
versions, for Cortex-M/A cores with or without the DSP extension, and two
pure-C versions, depending on whether `MUL64_IS_CONSTANT_TIME`.
Tests are run on the following platforms:
- `make` on x64 tests the pure-C version without `MUL64_IS_CONSTANT_TIME`
(with Clang).
- `./consttime.sh` on x64 tests both pure-C versions (with Clang).
- `make` on Arm v7-A (Raspberry Pi 2) tests the Arm-DSP assembly version (with
Clang).
- `on-target-*box` on boards based on Cortex-M0 and M4 cores test both
assembly versions (with GCC).
In addition:
- `sizes.sh` builds the code for three Arm cores with GCC and Clang.
- `deps.sh` checks for external dependencies with GCC.
## Notes about other curves
It should be clear that minimal code size can only be reached by specializing
the implementation to the curve at hand. Here's a list of things in the
implementation that are specific to the NIST P-256 curve, and how the
implementation could be changed to expand to other curves, layer by layer (see
"Design Overview" above).
**Fixed-width multi-precision arithmetic:**
- The number of limbs is hard-coded to 8. For other 256-bit curves, nothing to
change. For a curve of another size, hard-code to another value. For multiple
curves of various sizes, add a parameter to each function specifying the
number of limbs; when declaring arrays, always use the maximum number of
limbs.
**Fixed-width modular arithmetic:**
- The values of the curve's constant p and n, and their associated Montgomery
constants, are hard-coded. For another curve, just hard-code the new constants.
For multiple other curves, define all the constants, and from this layer's API
only keep the functions that already accept a `mod` parameter (that is, remove
convenience functions `m256_xxx_p()`).
- The number of limbs is again hard-coded to 8. See above, but it order to
support multiple sizes there is no need to add a new parameter to functions
in this layer: the existing `mod` parameter can include the number of limbs as
well.
**Operations on curve points:**
- The values of the curve's constants b (constant term from the equation) and
gx, gy (coordinates of the base point) are hard-coded. For another curve,
hard-code the other values. For multiple curves, define each curve's value and
add a "curve id" parameter to all functions in this layer.
- The value of the curve's constant a is implicitly hard-coded to `-3` by using
a standard optimisation to save one multiplication in the first step of
`point_double()`. For curves that don't have a == -3, replace that with the
normal computation.
- The fact that b != 0 in the curve equation is used indirectly, to ensure
that (0, 0) is not a point on the curve and re-use that value to represent
the point 0. As far as I know, all Short Weierstrass curves standardized so
far have b != 0.
- The shape of the curve is assumed to be Short Weierstrass. For other curve
shapes (Montgomery, (twisted) Edwards), this layer would probably look very
different (both implementation and API).
**Scalar operations:**
- If multiple curves are to be supported, all function in this layer need to
gain a new "curve id" parameter.
- This layer assumes that the bit size of the curve's order n is the same as
that of the modulus p. This is true of most curves standardized so far, the
only exception being secp224k1. If that curve were to be supported, the
representation of `n` and scalars would need adapting to allow for an extra
limb.
- The bit size of the curve's order is hard-coded in `scalar_mult()`. For
multiple curves, this should be deduced from the "curve id" parameter.
- The `scalar_mult()` function exploits the fact that the second least
significant bit of the curve's order n is set in order to avoid a special
case. For curve orders that don't meet this criterion, we can just handle that
special case (multiplication by +-2) separately (always compute that and
conditionally assign it to the result).
- The shape of the curve is again assumed to be Short Weierstrass. For other curve
shapes (Montgomery, (twisted) Edwards), this layer would probably have a
very different implementation.
**Public API:**
- For multiple curves, all functions in this layer would need to gain a "curve
id" parameter and handle variable-sized input/output.
- The shape of the curve is again assumed to be Short Weierstrass. For other curve
shapes (Montgomery, (twisted) Edwards), the ECDH API would probably look
quite similar (with differences in the size of public keys), but the ECDSA API
wouldn't apply and an EdDSA API would look pretty different.
## Notes about other platforms
While p256-m is standard C99, it is written with constrained 32-bit platforms
in mind and makes a few assumptions about the platform:
- The types `uint8_t`, `uint16_t`, `uint32_t` and `uint64_t` exist.
- 32-bit unsigned addition and subtraction with carry are constant time.
- 16x16->32-bit unsigned multiplication is available and constant time.
Also, on platforms on which 64-bit addition and subtraction with carry, or
even 64x64->128-bit multiplication, are available, p256-m makes no use of
them, though they could significantly improve performance.
This could be improved by replacing uses of arrays of `uint32_t` with a
defined type throughout the internal APIs, and then on 64-bit platforms define
that type to be an array of `uint64_t` instead, and making the obvious
adaptations in the multi-precision arithmetic layer.
Finally, the optional assembly code (which boosts performance by a factor 2 on
tested Cortex-M CPUs, while slightly reducing code size and stack usage) is
currently only available with compilers that support GCC's extended asm
syntax (which includes GCC and Clang).
+1514
View File
File diff suppressed because it is too large Load Diff
+135
View File
@@ -0,0 +1,135 @@
/*
* Interface of curve P-256 (ECDH and ECDSA)
*
* Copyright The Mbed TLS Contributors
* Author: Manuel Pégourié-Gonnard.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef P256_M_H
#define P256_M_H
#include <stdint.h>
#include <stddef.h>
/* Status codes */
#define P256_SUCCESS 0
#define P256_RANDOM_FAILED -1
#define P256_INVALID_PUBKEY -2
#define P256_INVALID_PRIVKEY -3
#define P256_INVALID_SIGNATURE -4
#ifdef __cplusplus
extern "C" {
#endif
/*
* RNG function - must be provided externally and be cryptographically secure.
*
* in: output - must point to a writable buffer of at least output_size bytes.
* output_size - the number of random bytes to write to output.
* out: output is filled with output_size random bytes.
* return 0 on success, non-zero on errors.
*/
extern int p256_generate_random(uint8_t * output, unsigned output_size);
/*
* ECDH/ECDSA generate key pair
*
* [in] draws from p256_generate_random()
* [out] priv: on success, holds the private key, as a big-endian integer
* [out] pub: on success, holds the public key, as two big-endian integers
*
* return: P256_SUCCESS on success
* P256_RANDOM_FAILED on failure
*/
int p256_gen_keypair(uint8_t priv[32], uint8_t pub[64]);
/*
* ECDH compute shared secret
*
* [out] secret: on success, holds the shared secret, as a big-endian integer
* [in] priv: our private key as a big-endian integer
* [in] pub: the peer's public key, as two big-endian integers
*
* return: P256_SUCCESS on success
* P256_INVALID_PRIVKEY if priv is invalid
* P256_INVALID_PUBKEY if pub is invalid
*/
int p256_ecdh_shared_secret(uint8_t secret[32],
const uint8_t priv[32], const uint8_t pub[64]);
/*
* ECDSA sign
*
* [in] draws from p256_generate_random()
* [out] sig: on success, holds the signature, as two big-endian integers
* [in] priv: our private key as a big-endian integer
* [in] hash: the hash of the message to be signed
* [in] hlen: the size of hash in bytes
*
* return: P256_SUCCESS on success
* P256_RANDOM_FAILED on failure
* P256_INVALID_PRIVKEY if priv is invalid
*/
int p256_ecdsa_sign(uint8_t sig[64], const uint8_t priv[32],
const uint8_t *hash, size_t hlen);
/*
* ECDSA verify
*
* [in] sig: the signature to be verified, as two big-endian integers
* [in] pub: the associated public key, as two big-endian integers
* [in] hash: the hash of the message that was signed
* [in] hlen: the size of hash in bytes
*
* return: P256_SUCCESS on success - the signature was verified as valid
* P256_INVALID_PUBKEY if pub is invalid
* P256_INVALID_SIGNATURE if the signature was found to be invalid
*/
int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
const uint8_t *hash, size_t hlen);
/*
* Public key validation
*
* Note: you never need to call this function, as all other functions always
* validate their input; however it's availabe if you want to validate the key
* without performing an operation.
*
* [in] pub: the public key, as two big-endian integers
*
* return: P256_SUCCESS if the key is valid
* P256_INVALID_PUBKEY if pub is invalid
*/
int p256_validate_pubkey(const uint8_t pub[64]);
/*
* Private key validation
*
* Note: you never need to call this function, as all other functions always
* validate their input; however it's availabe if you want to validate the key
* without performing an operation.
*
* [in] priv: the private key, as a big-endian integer
*
* return: P256_SUCCESS if the key is valid
* P256_INVALID_PRIVKEY if priv is invalid
*/
int p256_validate_privkey(const uint8_t priv[32]);
/*
* Compute public key from private key
*
* [out] pub: the associated public key, as two big-endian integers
* [in] priv: the private key, as a big-endian integer
*
* return: P256_SUCCESS on success
* P256_INVALID_PRIVKEY if priv is invalid
*/
int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32]);
#ifdef __cplusplus
}
#endif
#endif /* P256_M_H */
+312
View File
@@ -0,0 +1,312 @@
/*
* Driver entry points for p256-m
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#include "mbedtls/platform.h"
#include "p256-m_driver_entrypoints.h"
#include "p256-m/p256-m.h"
#include "psa/crypto.h"
#include <stddef.h>
#include <string.h>
#include "psa_crypto_driver_wrappers_no_static.h"
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
/* INFORMATION ON PSA KEY EXPORT FORMATS:
*
* PSA exports SECP256R1 keys in two formats:
* 1. Keypair format: 32 byte string which is just the private key (public key
* can be calculated from the private key)
* 2. Public Key format: A leading byte 0x04 (indicating uncompressed format),
* followed by the 64 byte public key. This results in a
* total of 65 bytes.
*
* p256-m's internal format for private keys matches PSA. Its format for public
* keys is only 64 bytes: the same as PSA but without the leading byte (0x04).
* Hence, when passing public keys from PSA to p256-m, the leading byte is
* removed.
*
* Shared secret and signature have the same format between PSA and p256-m.
*/
#define PSA_PUBKEY_SIZE 65
#define PSA_PUBKEY_HEADER_BYTE 0x04
#define P256_PUBKEY_SIZE 64
#define PRIVKEY_SIZE 32
#define SHARED_SECRET_SIZE 32
#define SIGNATURE_SIZE 64
#define CURVE_BITS 256
/* Convert between p256-m and PSA error codes */
static psa_status_t p256_to_psa_error(int ret)
{
switch (ret) {
case P256_SUCCESS:
return PSA_SUCCESS;
case P256_INVALID_PUBKEY:
case P256_INVALID_PRIVKEY:
return PSA_ERROR_INVALID_ARGUMENT;
case P256_INVALID_SIGNATURE:
return PSA_ERROR_INVALID_SIGNATURE;
case P256_RANDOM_FAILED:
default:
return PSA_ERROR_GENERIC_ERROR;
}
}
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits)
{
/* Check the key size */
if (*bits != 0 && *bits != CURVE_BITS) {
return PSA_ERROR_NOT_SUPPORTED;
}
/* Validate the key (and its type and size) */
psa_key_type_t type = psa_get_key_type(attributes);
if (type == PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
if (data_length != PSA_PUBKEY_SIZE) {
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
}
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
if (p256_validate_pubkey(data + 1) != P256_SUCCESS) {
return PSA_ERROR_INVALID_ARGUMENT;
}
} else if (type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
if (data_length != PRIVKEY_SIZE) {
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
}
if (p256_validate_privkey(data) != P256_SUCCESS) {
return PSA_ERROR_INVALID_ARGUMENT;
}
} else {
return PSA_ERROR_NOT_SUPPORTED;
}
*bits = CURVE_BITS;
/* We only support the export format for input, so just copy. */
if (key_buffer_size < data_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(key_buffer, data, data_length);
*key_buffer_length = data_length;
return PSA_SUCCESS;
}
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
uint8_t *data,
size_t data_size,
size_t *data_length)
{
/* Is this the right curve? */
size_t bits = psa_get_key_bits(attributes);
psa_key_type_t type = psa_get_key_type(attributes);
if (bits != CURVE_BITS || type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
return PSA_ERROR_NOT_SUPPORTED;
}
/* Validate sizes, as p256-m expects fixed-size buffers */
if (key_buffer_size != PRIVKEY_SIZE) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (data_size < PSA_PUBKEY_SIZE) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
data[0] = PSA_PUBKEY_HEADER_BYTE;
int ret = p256_public_from_private(data + 1, key_buffer);
if (ret == P256_SUCCESS) {
*data_length = PSA_PUBKEY_SIZE;
}
return p256_to_psa_error(ret);
}
psa_status_t p256_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length)
{
/* We don't use this argument, but the specification mandates the signature
* of driver entry-points. (void) used to avoid compiler warning. */
(void) attributes;
/* Validate sizes, as p256-m expects fixed-size buffers */
if (key_buffer_size != PRIVKEY_SIZE) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
/*
* p256-m's keypair generation function outputs both public and private
* keys. Allocate a buffer to which the public key will be written. The
* private key will be written to key_buffer, which is passed to this
* function as an argument. */
uint8_t public_key_buffer[P256_PUBKEY_SIZE];
int ret = p256_gen_keypair(key_buffer, public_key_buffer);
if (ret == P256_SUCCESS) {
*key_buffer_length = PRIVKEY_SIZE;
}
return p256_to_psa_error(ret);
}
psa_status_t p256_transparent_key_agreement(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length)
{
/* We don't use these arguments, but the specification mandates the
* sginature of driver entry-points. (void) used to avoid compiler
* warning. */
(void) attributes;
(void) alg;
/* Validate sizes, as p256-m expects fixed-size buffers */
if (key_buffer_size != PRIVKEY_SIZE || peer_key_length != PSA_PUBKEY_SIZE) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (shared_secret_size < SHARED_SECRET_SIZE) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
const uint8_t *peer_key_p256m = peer_key + 1;
int ret = p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key_p256m);
if (ret == P256_SUCCESS) {
*shared_secret_length = SHARED_SECRET_SIZE;
}
return p256_to_psa_error(ret);
}
psa_status_t p256_transparent_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length)
{
/* We don't use these arguments, but the specification mandates the
* sginature of driver entry-points. (void) used to avoid compiler
* warning. */
(void) attributes;
(void) alg;
/* Validate sizes, as p256-m expects fixed-size buffers */
if (key_buffer_size != PRIVKEY_SIZE) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (signature_size < SIGNATURE_SIZE) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
int ret = p256_ecdsa_sign(signature, key_buffer, hash, hash_length);
if (ret == P256_SUCCESS) {
*signature_length = SIGNATURE_SIZE;
}
return p256_to_psa_error(ret);
}
/* This function expects the key buffer to contain a PSA public key,
* as exported by psa_export_public_key() */
static psa_status_t p256_verify_hash_with_public_key(
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length)
{
/* Validate sizes, as p256-m expects fixed-size buffers */
if (key_buffer_size != PSA_PUBKEY_SIZE || *key_buffer != PSA_PUBKEY_HEADER_BYTE) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (signature_length != SIGNATURE_SIZE) {
return PSA_ERROR_INVALID_SIGNATURE;
}
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
const uint8_t *public_key_p256m = key_buffer + 1;
int ret = p256_ecdsa_verify(signature, public_key_p256m, hash, hash_length);
return p256_to_psa_error(ret);
}
psa_status_t p256_transparent_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length)
{
/* We don't use this argument, but the specification mandates the signature
* of driver entry-points. (void) used to avoid compiler warning. */
(void) alg;
psa_status_t status;
uint8_t public_key_buffer[PSA_PUBKEY_SIZE];
size_t public_key_buffer_size = PSA_PUBKEY_SIZE;
size_t public_key_length = PSA_PUBKEY_SIZE;
/* As p256-m doesn't require dynamic allocation, we want to avoid it in
* the entrypoint functions as well. psa_driver_wrapper_export_public_key()
* requires size_t*, so we use a pointer to a stack variable. */
size_t *public_key_length_ptr = &public_key_length;
/* The contents of key_buffer may either be the 32 byte private key
* (keypair format), or 0x04 followed by the 64 byte public key (public
* key format). To ensure the key is in the latter format, the public key
* is exported. */
status = psa_driver_wrapper_export_public_key(
attributes,
key_buffer,
key_buffer_size,
public_key_buffer,
public_key_buffer_size,
public_key_length_ptr);
if (status != PSA_SUCCESS) {
goto exit;
}
status = p256_verify_hash_with_public_key(
public_key_buffer,
public_key_buffer_size,
hash,
hash_length,
signature,
signature_length);
exit:
return status;
}
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
+219
View File
@@ -0,0 +1,219 @@
/*
* Driver entry points for p256-m
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef P256M_DRIVER_ENTRYPOINTS_H
#define P256M_DRIVER_ENTRYPOINTS_H
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
#include "psa/crypto_types.h"
/** Import SECP256R1 key.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] data The raw key material. For private keys
* this must be a big-endian integer of 32
* bytes; for public key this must be an
* uncompressed ECPoint (65 bytes).
* \param[in] data_length The size of the raw key material.
* \param[out] key_buffer The buffer to contain the key data in
* output format upon successful return.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[out] key_buffer_length The length of the data written in \p
* key_buffer in bytes.
* \param[out] bits The bitsize of the key.
*
* \retval #PSA_SUCCESS
* Success. Keypair generated and stored in buffer.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The input is not supported by this driver (not SECP256R1).
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input is invalid.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p key_buffer_size is too small.
*/
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
/** Export SECP256R1 public key, from the private key.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The private key in the export format.
* \param[in] key_buffer_size The size of the private key in bytes.
* \param[out] data The buffer to contain the public key in
* the export format upon successful return.
* \param[in] data_size The size of the \p data buffer in bytes.
* \param[out] data_length The length written to \p data in bytes.
*
* \retval #PSA_SUCCESS
* Success. Keypair generated and stored in buffer.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The input is not supported by this driver (not SECP256R1).
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input is invalid.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p key_buffer_size is too small.
*/
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
uint8_t *data,
size_t data_size,
size_t *data_length);
/** Generate SECP256R1 ECC Key Pair.
* Interface function which calls the p256-m key generation function and
* places it in the key buffer provided by the caller (Mbed TLS) in the
* correct format. For a SECP256R1 curve this is the 32 bit private key.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[out] key_buffer The buffer to contain the key data in
* output format upon successful return.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[out] key_buffer_length The length of the data written in \p
* key_buffer in bytes.
*
* \retval #PSA_SUCCESS
* Success. Keypair generated and stored in buffer.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p key_buffer_size is too small.
* \retval #PSA_ERROR_GENERIC_ERROR
* The internal RNG failed.
*/
psa_status_t p256_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length);
/** Perform raw key agreement using p256-m's ECDH implementation
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the private key
* in the format specified by PSA.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[in] alg A key agreement algorithm that is
* compatible with the type of the key.
* \param[in] peer_key The buffer containing the peer's public
* key in format specified by PSA.
* \param[in] peer_key_length Size of the \p peer_key buffer in
* bytes.
* \param[out] shared_secret The buffer to which the shared secret
* is to be written.
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
* bytes.
* \param[out] shared_secret_length On success, the number of bytes that
* make up the returned shared secret.
* \retval #PSA_SUCCESS
* Success. Shared secret successfully calculated.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input is invalid.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p shared_secret_size is too small.
*/
psa_status_t p256_transparent_key_agreement(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *shared_secret,
size_t shared_secret_size,
size_t *shared_secret_length);
/** Sign an already-calculated hash with a private key using p256-m's ECDSA
* implementation
* \param[in] attributes The attributes of the key to use for the
* operation.
* \param[in] key_buffer The buffer containing the private key
* in the format specified by PSA.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[in] alg A signature algorithm that is compatible
* with the type of the key.
* \param[in] hash The hash to sign.
* \param[in] hash_length Size of the \p hash buffer in bytes.
* \param[out] signature Buffer where signature is to be written.
* \param[in] signature_size Size of the \p signature buffer in bytes.
* \param[out] signature_length On success, the number of bytes
* that make up the returned signature value.
*
* \retval #PSA_SUCCESS
* Success. Hash was signed successfully.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input is invalid.
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* \p signature_size is too small.
* \retval #PSA_ERROR_GENERIC_ERROR
* The internal RNG failed.
*/
psa_status_t p256_transparent_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
/** Verify the signature of a hash using a SECP256R1 public key using p256-m's
* ECDSA implementation.
*
* \note p256-m expects a 64 byte public key, but the contents of the key
buffer may be the 32 byte keypair representation or the 65 byte
public key representation. As a result, this function calls
psa_driver_wrapper_export_public_key() to ensure the public key
can be passed to p256-m.
*
* \param[in] attributes The attributes of the key to use for the
* operation.
*
* \param[in] key_buffer The buffer containing the key
* in the format specified by PSA.
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
* \param[in] alg A signature algorithm that is compatible with
* the type of the key.
* \param[in] hash The hash whose signature is to be
* verified.
* \param[in] hash_length Size of the \p hash buffer in bytes.
* \param[in] signature Buffer containing the signature to verify.
* \param[in] signature_length Size of the \p signature buffer in bytes.
*
* \retval #PSA_SUCCESS
* The signature is valid.
* \retval #PSA_ERROR_INVALID_SIGNATURE
* The calculation was performed successfully, but the passed
* signature is not a valid signature.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input is invalid.
*/
psa_status_t p256_transparent_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length);
#endif /* P256M_DRIVER_ENTRYPOINTS_H */
+18 -9
View File
@@ -2,27 +2,33 @@
At any point in time, we have a number of maintained branches, currently consisting of:
- The [`master`](https://github.com/Mbed-TLS/mbedtls/tree/master) branch:
- The [`main`](https://github.com/Mbed-TLS/mbedtls/tree/main) branch:
this always contains the latest release, including all publicly available
security fixes.
- The [`development`](https://github.com/Mbed-TLS/mbedtls/tree/development) branch:
this is where the current major version of Mbed TLS (version 3.x) is being
prepared. It has API changes that make it incompatible with Mbed TLS 2.x,
this is where the next major version of Mbed TLS (version 4.0) is being
prepared. It has API changes that make it incompatible with Mbed TLS 3.x,
as well as all the new features and bug fixes and security fixes.
- One or more long-time support (LTS) branches: these only get bug fixes and
security fixes. Currently, the only supported LTS branch is:
[`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28).
security fixes. Currently, the supported LTS branches are:
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28).
- [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6).
We retain a number of historical branches, whose names are prefixed by `archive/`,
such as [`archive/mbedtls-2.7`](https://github.com/Mbed-TLS/mbedtls/tree/archive/mbedtls-2.7).
These branches will not receive any changes or updates.
We use [Semantic Versioning](https://semver.org/). In particular, we maintain
API compatibility in the `master` branch across minor version changes (e.g.
API compatibility in the `main` branch across minor version changes (e.g.
the API of 3.(x+1) is backward compatible with 3.x). We only break API
compatibility on major version changes (e.g. from 3.x to 4.0). We also maintain
ABI compatibility within LTS branches; see the next section for details.
We will make regular LTS releases on an 18-month cycle, each of which will have
a 3 year support lifetime. On this basis, 3.6 LTS (released March 2024) will be
supported until March 2027. The next LTS release will be a 4.x release, which is
planned for September 2025.
## Backwards Compatibility for application code
We maintain API compatibility in released versions of Mbed TLS. If you have
@@ -97,10 +103,13 @@ CONTRIBUTING](CONTRIBUTING.md#backwards-compatibility).
The following branches are currently maintained:
- [master](https://github.com/Mbed-TLS/mbedtls/tree/master)
- [main](https://github.com/Mbed-TLS/mbedtls/tree/main)
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
- [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6)
maintained until March 2027, see
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v3.6.0>.
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
maintained until at least the end of 2024, see
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.3>.
maintained until the end of 2024, see
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.8>.
Users are urged to always use the latest version of a maintained branch.
+1 -1
View File
@@ -7,7 +7,7 @@ Known issues in Mbed TLS are [tracked on GitHub](https://github.com/Mbed-TLS/mbe
If you think you've found a bug in Mbed TLS, please follow these steps:
1. Make sure you're using the latest version of a
[maintained branch](BRANCHES.md): `master`, `development`,
[maintained branch](BRANCHES.md): `main`, `development`,
or a long-time support branch.
2. Check [GitHub](https://github.com/Mbed-TLS/mbedtls/issues) to see if
your issue has already been reported. If not, …
+58 -11
View File
@@ -34,14 +34,20 @@ cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0012 NEW)
if(TEST_CPP)
project("mbed TLS" C CXX)
project("Mbed TLS"
LANGUAGES C CXX
VERSION 3.6.0
)
else()
project("mbed TLS" C)
project("Mbed TLS"
LANGUAGES C
VERSION 3.6.0
)
endif()
include(GNUInstallDirs)
# Determine if mbed TLS is being built as a subproject using add_subdirectory()
# Determine if Mbed TLS is being built as a subproject using add_subdirectory()
if(NOT DEFINED MBEDTLS_AS_SUBPROJECT)
set(MBEDTLS_AS_SUBPROJECT ON)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
@@ -52,12 +58,15 @@ endif()
# Set the project root directory.
set(MBEDTLS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(ENABLE_PROGRAMS "Build Mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
option(MBEDTLS_FATAL_WARNINGS "Compiler warnings treated as errors" ON)
if(CMAKE_HOST_WIN32)
option(GEN_FILES "Generate the auto-generated files as needed" OFF)
# N.B. The comment on the next line is significant! If you change it,
# edit the sed command in prepare_release.sh that modifies
# 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)
endif()
@@ -71,9 +80,9 @@ string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${CMAKE_C_COMPILER_ID}")
# the test suites currently have compile errors with MSVC
if(CMAKE_COMPILER_IS_MSVC)
option(ENABLE_TESTING "Build mbed TLS tests." OFF)
option(ENABLE_TESTING "Build Mbed TLS tests." OFF)
else()
option(ENABLE_TESTING "Build mbed TLS tests." ON)
option(ENABLE_TESTING "Build Mbed TLS tests." ON)
endif()
# Warning string - created as a list for compatibility with CMake 2.8
@@ -111,13 +120,22 @@ if(MBEDTLS_PYTHON_EXECUTABLE)
endif()
# We now potentially need to link all executables against PThreads, if available
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads)
# 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()
# Make MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE into PATHs
set(MBEDTLS_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS config file (overrides default).")
set(MBEDTLS_USER_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS user config file (appended to default).")
# Create a symbolic link from ${base_name} in the binary directory
# to the corresponding path in the source directory.
# Note: Copies the file(s) on Windows.
@@ -205,6 +223,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)
@@ -218,11 +238,15 @@ 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)
if(CMAKE_COMPILER_IS_IAR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts -Ohz")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts")
set(CMAKE_C_FLAGS_RELEASE "-Ohz")
set(CMAKE_C_FLAGS_DEBUG "--debug -On")
endif(CMAKE_COMPILER_IS_IAR)
if(CMAKE_COMPILER_IS_MSVC)
@@ -245,7 +269,7 @@ if(MBEDTLS_FATAL_WARNINGS)
endif(CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNU)
if (CMAKE_COMPILER_IS_IAR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warning_are_errors")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warnings_are_errors")
endif(CMAKE_COMPILER_IS_IAR)
endif(MBEDTLS_FATAL_WARNINGS)
@@ -259,12 +283,19 @@ if(LIB_INSTALL_DIR)
set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
endif()
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt")
message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.")
endif()
add_subdirectory(framework)
add_subdirectory(include)
add_subdirectory(3rdparty)
add_subdirectory(library)
add_subdirectory(pkgconfig)
#
# The C files in tests/src directory contain test code shared among test suites
# and programs. This shared test code is compiled and linked to test suites and
@@ -288,6 +319,8 @@ if(ENABLE_TESTING OR ENABLE_PROGRAMS)
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library)
# Request C11, needed for memory poisoning tests
set_target_properties(mbedtls_test PROPERTIES C_STANDARD 11)
file(GLOB MBEDTLS_TEST_HELPER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tests/src/test_helpers/*.c)
@@ -297,6 +330,20 @@ if(ENABLE_TESTING OR ENABLE_PROGRAMS)
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/everest/include)
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
if(MBEDTLS_CONFIG_FILE)
target_compile_definitions(mbedtls_test
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
target_compile_definitions(mbedtls_test_helpers
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
endif()
if(MBEDTLS_USER_CONFIG_FILE)
target_compile_definitions(mbedtls_test
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
target_compile_definitions(mbedtls_test_helpers
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
endif()
endif()
if(ENABLE_PROGRAMS)
@@ -354,7 +401,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
VERSION 3.4.1)
VERSION 3.6.0)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
+9 -3
View File
@@ -24,7 +24,7 @@ Making a Contribution
1. [Check for open issues](https://github.com/Mbed-TLS/mbedtls/issues) or [start a discussion](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org) around a feature idea or a bug.
1. Fork the [Mbed TLS repository on GitHub](https://github.com/Mbed-TLS/mbedtls) to start making your changes. As a general rule, you should use the ["development" branch](https://github.com/Mbed-TLS/mbedtls/tree/development) as a basis.
1. Write a test which shows that the bug was fixed or that the feature works as expected.
1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. We will include your name in the ChangeLog :)
1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. See our [review process guidelines](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/).
1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
Backwards Compatibility
@@ -84,8 +84,14 @@ Mbed TLS is well documented, but if you think documentation is needed, speak out
License and Copyright
---------------------
All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible. For licensing details, please see the [License section of the README](README.md#License).
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under 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.
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".
The copyright on contributions is retained by the original authors of the code. Where possible for new files, this should be noted in a comment at the top of the file in the form: "Copyright The Mbed TLS Contributors".
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and be subject to the same Apache 2.0 license. This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and is submitted under both the Apache-2.0 AND GPL-2.0-or-later licenses.
This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.
+573
View File
@@ -1,5 +1,578 @@
Mbed TLS ChangeLog (Sorted per branch, date)
= Mbed TLS 3.6.0 branch released 2024-03-28
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.
Default behavior changes
* psa_import_key() now only accepts RSA keys in the PSA standard formats.
The undocumented ability to import other formats (PKCS#8, SubjectPublicKey,
PEM) accepted by the pkparse module has been removed. Applications that
need these formats can call mbedtls_pk_parse_{public,}key() followed by
mbedtls_pk_import_into_psa().
Requirement changes
* Drop support for Visual Studio 2013 and 2015, and Arm Compiler 5.
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.
* In the PSA API, domain parameters are no longer used for anything.
They are deprecated and will be removed in a future version of the
library.
* mbedtls_ecp_write_key() is deprecated in favor of
mbedtls_ecp_write_key_ext().
Removals
* In the PSA API, the experimental way to encode the public exponent of
an RSA key as a domain parameter is no longer supported. Use
psa_generate_key_ext() instead.
* Temporary function mbedtls_pk_wrap_as_opaque() is removed. To mimic the
same behavior mbedtls_pk_get_psa_attributes() and
mbedtls_pk_import_into_psa() can be used to import a PK key into PSA,
while mbedtls_pk_setup_opaque() can be used to wrap a PSA key into a opaque
PK context.
Features
* Added an example program showing how to hash with the PSA API.
* Support Armv8-A Crypto Extension acceleration for SHA-256
when compiling for Thumb (T32) or 32-bit Arm (A32).
* AES-NI is now supported in Windows builds with clang and clang-cl.
Resolves #8372.
* Add new mbedtls_x509_csr_parse_der_with_ext_cb() routine which allows
parsing unsupported certificate extensions via user provided callback.
* 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.
* Support use of Armv8-A Cryptographic Extensions for hardware acclerated
AES when compiling for Thumb (T32) or 32-bit Arm (A32).
* 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.
* 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.
* 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.
* Improve performance of AES-GCM, AES-CTR and CTR-DRBG when
hardware accelerated AES is not present (around 13-23% on 64-bit Arm).
* Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa()
to convert between Mbed TLS and PSA curve identifiers.
* 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.
* 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.
* Add partial platform support for z/OS.
* Improve performance for gcc (versions older than 9.3.0) and IAR.
* Add functions mbedtls_ecdsa_raw_to_der() and mbedtls_ecdsa_der_to_raw() to
convert ECDSA signatures between raw and DER (ASN.1) formats.
* Add support for using AES-CBC 128, 192, and 256 bit schemes
with PKCS#5 PBES2. Keys encrypted this way can now be parsed by PK parse.
* The new function mbedtls_rsa_get_bitlen() returns the length of the modulus
in bits, i.e. the key size for an RSA key.
* Add pc files for pkg-config, e.g.:
pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509)
* Add getter (mbedtls_ssl_session_get_ticket_creation_time()) to access
`mbedtls_ssl_session.ticket_creation_time`.
* The new functions mbedtls_pk_get_psa_attributes() and
mbedtls_pk_import_into_psa() provide a uniform way to create a PSA
key from a PK key.
* The benchmark program now reports times for both ephemeral and static
ECDH in all ECDH configurations.
* Add support for 8-bit GCM tables for Shoup's algorithm to speedup GCM
operations when hardware accelerated AES is not present. Improves
performance by around 30% on 64-bit Intel; 125% on Armv7-M.
* The new function psa_generate_key_ext() allows generating an RSA
key pair with a custom public exponent.
* The new function mbedtls_ecp_write_key_ext() is similar to
mbedtls_ecp_write_key(), but can be used without separately calculating
the output length.
* Add new accessor to expose the private group id member of
`mbedtls_ecdh_context` structure.
* Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of
`mbedtls_x509_crt` structure. This requires setting
the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's
ext_types field.
* mbedtls_psa_get_random() is always available as soon as
MBEDTLS_PSA_CRYPTO_CLIENT is enabled at build time and psa_crypto_init() is
called at runtime. This together with MBEDTLS_PSA_RANDOM_STATE can be
used as random number generator function (f_rng) and context (p_rng) in
legacy functions.
* The new functions mbedtls_pk_copy_from_psa() and
mbedtls_pk_copy_public_from_psa() provide ways to set up a PK context
with the same content as a PSA key.
* Add new accessors to expose the private session-id,
session-id length, and ciphersuite-id members of
`mbedtls_ssl_session` structure.
Add new accessor to expose the ciphersuite-id of
`mbedtls_ssl_ciphersuite_t` structure.Design ref: #8529
* Mbed TLS now supports the writing and reading of TLS 1.3 early data (see
docs/tls13-early-data.md). The support enablement is controlled at build
time by the MBEDTLS_SSL_EARLY_DATA configuration option and at runtime by
the mbedtls_ssl_conf_early_data() API (by default disabled in both cases).
* Add protection for multithreaded access to the PSA keystore and protection
for multithreaded access to the the PSA global state, including
concurrently calling psa_crypto_init() when MBEDTLS_THREADING_C and
MBEDTLS_THREADING_PTHREAD are defined. See
docs/architecture/psa-thread-safety/psa-thread-safety.md for more details.
Resolves issues #3263 and #7945.
Security
* Fix a stack buffer overread (less than 256 bytes) when parsing a TLS 1.3
ClientHello in a TLS 1.3 server supporting some PSK key exchange mode. A
malicious client could cause information disclosure or a denial of service.
* Passing buffers that are stored in untrusted memory as arguments
to PSA functions is now secure by default.
The PSA core now protects against modification of inputs or exposure
of intermediate outputs during operations. This is currently implemented
by copying buffers.
This feature increases code size and memory usage. If buffers passed to
PSA functions are owned exclusively by the PSA core for the duration of
the function call (i.e. no buffer parameters are in shared memory),
copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS.
Note that setting this option will cause input-output buffer overlap to
be only partially supported (#3266).
Fixes CVE-2024-28960.
* Restore the maximum TLS version to be negotiated to the configured one
when an SSL context is reset with the mbedtls_ssl_session_reset() API.
An attacker was able to prevent an Mbed TLS server from establishing any
TLS 1.3 connection potentially resulting in a Denial of Service or forced
version downgrade from TLS 1.3 to TLS 1.2. Fixes #8654 reported by hey3e.
Fixes CVE-2024-28755.
* When negotiating TLS version on server side, do not fall back to the
TLS 1.2 implementation of the protocol if it is disabled.
- If the TLS 1.2 implementation was disabled at build time, a TLS 1.2
client could put the TLS 1.3-only server in an infinite loop processing
a TLS 1.2 ClientHello, resulting in a denial of service. Reported by
Matthias Mucha and Thomas Blattmann, SICK AG.
- If the TLS 1.2 implementation was disabled at runtime, a TLS 1.2 client
was able to successfully establish a TLS 1.2 connection with the server.
Reported by alluettiv on GitHub.
Fixes CVE-2024-28836.
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.
* Fix compilation error in C++ programs when MBEDTLS_ASN1_PARSE_C is
disabled.
* Fix possible NULL dereference issue in X509 cert_req program if an entry
in the san parameter is not separated by a colon.
* Fix possible NULL dereference issue in X509 cert_write program if an entry
in the san parameter is not separated by a colon.
* Fix an inconsistency between implementations and usages of `__cpuid`,
which mainly causes failures when building Windows target using
mingw or clang. Fixes #8334 & #8332.
* Fix build failure in conda-forge. Fixes #8422.
* Fix parsing of CSRs with critical extensions.
* 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.
* Fix TLS server accepting TLS 1.2 handshake while TLS 1.2
is disabled at runtime. Fixes #8593.
* Remove accidental introduction of RSA signature algorithms
in TLS Suite B Profile. Fixes #8221.
* Fix unsupported PSA asymmetric encryption and decryption
(psa_asymmetric_[en|de]crypt) with opaque keys.
Resolves #8461.
* On Linux on ARMv8, fix a build error with SHA-256 and SHA-512
acceleration detection when the libc headers do not define the
corresponding constant. Reported by valord577.
* Correct initial capacities for key derivation algorithms:TLS12_PRF,
TLS12_PSK_TO_MS, PBKDF2-HMAC, PBKDF2-CMAC
* Fix mbedtls_pk_get_bitlen() for RSA keys whose size is not a
multiple of 8. Fixes #868.
* Avoid segmentation fault caused by releasing not initialized
entropy resource in gen_key example. Fixes #8809.
* mbedtls_pem_read_buffer() now performs a check on the padding data of
decrypted keys and it rejects invalid ones.
* Fix mbedtls_pk_sign(), mbedtls_pk_verify(), mbedtls_pk_decrypt() and
mbedtls_pk_encrypt() on non-opaque RSA keys to honor the padding mode in
the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled and the
RSA context was configured for PKCS#1 v2.1 (PSS/OAEP), the sign/verify
functions performed a PKCS#1 v1.5 signature instead and the
encrypt/decrypt functions returned an error. Fixes #8824.
* Fix missing bitflags in SSL session serialization headers. Their absence
allowed SSL sessions saved in one configuration to be loaded in a
different, incompatible configuration.
* In TLS 1.3 clients, fix an interoperability problem due to the client
generating a new random after a HelloRetryRequest. Fixes #8669.
* Fix the restoration of the ALPN when loading serialized connection with
the mbedtls_ssl_context_load() API.
* Fix NULL pointer dereference in mbedtls_pk_verify_ext() when called using
an opaque RSA context and specifying MBEDTLS_PK_RSASSA_PSS as key type.
* Fix RSA opaque keys always using PKCS1 v1.5 algorithms instead of the
primary algorithm of the wrapped PSA key.
* Fully support arbitrary overlap between inputs and outputs of PSA
functions. Note that overlap is still only partially supported when
MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set (#3266).
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.
* 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.
* 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
* mbedtls_pk_sign_ext() is now always available, not just when
PSA (MBEDTLS_PSA_CRYPTO_C) is enabled.
* Extended PSA Crypto configurations options for FFDH by making it possible
to select only some of the parameters / groups, with the macros
PSA_WANT_DH_RFC7919_XXXX. You now need to defined the corresponding macro
for each size you want to support. Also, if you have an FFDH accelerator,
you'll need to define the appropriate MBEDTLS_PSA_ACCEL macros to signal
support for these domain parameters.
* RSA support in PSA no longer auto-enables the pkparse and pkwrite modules,
saving code size when those are not otherwise enabled.
* mbedtls_mpi_exp_mod and code that uses it, notably RSA and DHM operations,
have changed their speed/memory compromise as part of a proactive security
improvement. The new default value of MBEDTLS_MPI_WINDOW_SIZE roughly
preserves the current speed, at the expense of increasing memory
consumption.
* Rename directory containing Visual Studio files from visualc/VS2013 to
visualc/VS2017.
* The TLS 1.3 protocol is now enabled in the default configuration.
= Mbed TLS 3.5.2 branch released 2024-01-26
Security
* Fix a timing side channel in private key RSA operations. This side channel
could be sufficient for an attacker to recover the plaintext. A local
attacker or a remote attacker who is close to the victim on the network
might have precise enough timing measurements to exploit this. It requires
the attacker to send a large number of messages for decryption. For
details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported
by Hubert Kario, Red Hat.
* Fix a failure to validate input when writing x509 extensions lengths which
could result in an integer overflow, causing a zero-length buffer to be
allocated to hold the extension. The extension would then be copied into
the buffer, causing a heap buffer overflow.
= Mbed TLS 3.5.1 branch released 2023-11-06
Changes
* Mbed TLS is now released under a dual Apache-2.0 OR GPL-2.0-or-later
license. Users may choose which license they take the code under.
Bugfix
* Fix accidental omission of MBEDTLS_TARGET_PREFIX in 3rdparty modules
in CMake.
= Mbed TLS 3.5.0 branch released 2023-10-05
API changes
* Mbed TLS 3.4 introduced support for omitting the built-in implementation
of ECDSA and/or EC J-PAKE when those are provided by a driver. However,
there was a flaw in the logic checking if the built-in implementation, in
that it failed to check if all the relevant curves were supported by the
accelerator. As a result, it was possible to declare no curves as
accelerated and still have the built-in implementation compiled out.
Starting with this release, it is necessary to declare which curves are
accelerated (using MBEDTLS_PSA_ACCEL_ECC_xxx macros), or they will be
considered not accelerated, and the built-in implementation of the curves
and any algorithm possible using them will be included in the build.
* Add new millisecond time type `mbedtls_ms_time_t` and `mbedtls_ms_time()`
function, needed for TLS 1.3 ticket lifetimes. Alternative implementations
can be created using an ALT interface.
Requirement changes
* Officially require Python 3.8 now that earlier versions are out of support.
* Minimum required Windows version is now Windows Vista, or
Windows Server 2008.
New deprecations
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR, where xxx is either ECC or RSA,
are now being deprecated in favor of PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy. Here yyy can be: BASIC,
IMPORT, EXPORT, GENERATE, DERIVE. The goal is to have a finer detail about
the capabilities of the PSA side for either key.
* MBEDTLS_CIPHER_BLKSIZE_MAX is deprecated in favor of
MBEDTLS_MAX_BLOCK_LENGTH (if you intended what the name suggests:
maximum size of any supported block cipher) or the new name
MBEDTLS_CMAC_MAX_BLOCK_SIZE (if you intended the actual semantics:
maximum size of a block cipher supported by the CMAC module).
* mbedtls_pkcs5_pbes2() and mbedtls_pkcs12_pbe() functions are now
deprecated in favor of mbedtls_pkcs5_pbes2_ext() and
mbedtls_pkcs12_pbe_ext() as they offer more security by checking
for overflow of the output buffer and reporting the actual length
of the output.
Features
* All modules that use hashes or HMAC can now take advantage of PSA Crypto
drivers when MBEDTLS_PSA_CRYPTO_C is enabled and psa_crypto_init() has
been called. Previously (in 3.3), this was restricted to a few modules,
and only in builds where MBEDTLS_MD_C was disabled; in particular the
entropy module was not covered which meant an external RNG had to be
provided - these limitations are lifted in this version. A new set of
feature macros, MBEDTLS_MD_CAN_xxx, has been introduced that can be used
to check for availability of hash algorithms, regardless of whether
they're provided by a built-in implementation, a driver or both. See
docs/driver-only-builds.md.
* When a PSA driver for ECDH is present, it is now possible to disable
MBEDTLS_ECDH_C in the build in order to save code size. For TLS 1.2
key exchanges based on ECDH(E) to work, this requires
MBEDTLS_USE_PSA_CRYPTO. Restartable/interruptible ECDHE operations in
TLS 1.2 (ECDHE-ECDSA key exchange) are not supported in those builds yet,
as PSA does not have an API for restartable ECDH yet.
* When all of ECDH, ECDSA and EC J-PAKE are either disabled or provided by
a driver, it is possible to disable MBEDTLS_ECP_C (and MBEDTLS_BIGNUM_C
if not required by another module) and still get support for ECC keys and
algorithms in PSA, with some limitations. See docs/driver-only-builds.txt
for details.
* Add parsing of directoryName subtype for subjectAltName extension in
x509 certificates.
* Add support for server-side TLS version negotiation. If both TLS 1.2 and
TLS 1.3 protocols are enabled, the TLS server now selects TLS 1.2 or
TLS 1.3 depending on the capabilities and preferences of TLS clients.
Fixes #6867.
* X.509 hostname verification now supports IPAddress Subject Alternate Names.
* Add support for reading and writing X25519 and X448
public and private keys in RFC 8410 format using the existing PK APIs.
* When parsing X.509 certificates, support the extensions
SignatureKeyIdentifier and AuthorityKeyIdentifier.
* Don't include the PSA dispatch functions for PAKEs (psa_pake_setup() etc)
if no PAKE algorithms are requested
* Add support for the FFDH algorithm and DH key types in PSA, with
parameters from RFC 7919. This includes a built-in implementation based
on MBEDTLS_BIGNUM_C, and a driver dispatch layer enabling alternative
implementations of FFDH through the driver entry points.
* It is now possible to generate certificates with SubjectAltNames.
Currently supported subtypes: DnsName, UniformResourceIdentifier,
IP address, OtherName, and DirectoryName, as defined in RFC 5280.
See mbedtls_x509write_crt_set_subject_alternative_name for
more information.
* X.509 hostname verification now partially supports URI Subject Alternate
Names. Only exact matching, without any normalization procedures
described in 7.4 of RFC5280, will result in a positive URI verification.
* Add function mbedtls_oid_from_numeric_string() to parse an OID from a
string to a DER-encoded mbedtls_asn1_buf.
* Add SHA-3 family hash functions.
* Add support to restrict AES to 128-bit keys in order to save code size.
A new configuration option, MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH, can be
used to enable this feature.
* AES performance improvements. Uplift varies by platform,
toolchain, optimisation flags and mode.
Aarch64, gcc -Os and CCM, GCM and XTS benefit the most.
On Aarch64, uplift is typically around 20 - 110%.
When compiling with gcc -Os on Aarch64, AES-XTS improves
by 4.5x.
* Add support for PBKDF2-HMAC through the PSA API.
* New symbols PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy and
MBEDTLS_PSA_ACCEL_KEY_TYPE_xxx_KEY_PAIR_yyy (where xxx is either ECC, RSA
or DH) were introduced in order to have finer accuracy in defining the
PSA capabilities for each key. These capabilities, named yyy above, can be
any of: BASIC, IMPORT, EXPORT, GENERATE, DERIVE.
- DERIVE is only available for ECC keys, not for RSA or DH ones.
- implementations are free to enable more than what it was strictly
requested. For example BASIC internally enables IMPORT and EXPORT
(useful for testing purposes), but this might change in the future.
* Add support for FFDH key exchange in TLS 1.3.
This is automatically enabled as soon as PSA_WANT_ALG_FFDH
and the ephemeral or psk-ephemeral key exchange mode are enabled.
By default, all groups are offered; the list of groups can be
configured using the existing API function mbedtls_ssl_conf_groups().
* Improve mbedtls_x509_time performance and reduce memory use.
* Reduce syscalls to time() during certificate verification.
* Allow MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE to be set by
setting the CMake variable of the same name at configuration time.
* Add getter (mbedtls_ssl_cache_get_timeout()) to access
`mbedtls_ssl_cache_context.timeout`.
* Add getter (mbedtls_ssl_get_hostname()) to access
`mbedtls_ssl_context.hostname`.
* Add getter (mbedtls_ssl_conf_get_endpoint()) to access
`mbedtls_ssl_config.endpoint`.
* Support for "opaque" (PSA-held) ECC keys in the PK module has been
extended: it is now possible to use mbedtls_pk_write_key_der(),
mbedtls_pk_write_key_pem(), mbedtls_pk_check_pair(), and
mbedtls_pk_verify() with opaque ECC keys (provided the PSA attributes
allow it).
* The documentation of mbedtls_ecp_group now describes the optimized
representation of A for some curves. Fixes #8045.
* Add a possibility to generate CSR's with RCF822 and directoryName subtype
of subjectAltName extension in x509 certificates.
* Add support for PBKDF2-CMAC through the PSA API.
* New configuration option MBEDTLS_AES_USE_HARDWARE_ONLY introduced. When
using CPU-accelerated AES (e.g., Arm Crypto Extensions), this option
disables the plain C implementation and the run-time detection for the
CPU feature, which reduces code size and avoids the vulnerability of the
plain C implementation.
* Accept arbitrary AttributeType and AttributeValue in certificate
Distinguished Names using RFC 4514 syntax.
* Applications using ECC over secp256r1 through the PSA API can use a
new implementation with a much smaller footprint, but some minor
usage restrictions. See the documentation of the new configuration
option MBEDTLS_PSA_P256M_DRIVER_ENABLED for details.
Security
* Fix a case where potentially sensitive information held in memory would not
be completely zeroized during TLS 1.2 handshake, in both server and client
configurations.
* In configurations with ARIA or Camellia but not AES, the value of
MBEDTLS_CIPHER_BLKSIZE_MAX was 8, rather than 16 as the name might
suggest. This did not affect any library code, because this macro was
only used in relation with CMAC which does not support these ciphers.
This may affect application code that uses this macro.
* Developers using mbedtls_pkcs5_pbes2() or mbedtls_pkcs12_pbe() should
review the size of the output buffer passed to this function, and note
that the output after decryption may include CBC padding. Consider moving
to the new functions mbedtls_pkcs5_pbes2_ext() or mbedtls_pkcs12_pbe_ext()
which checks for overflow of the output buffer and reports the actual
length of the output.
* Improve padding calculations in CBC decryption, NIST key unwrapping and
RSA OAEP decryption. With the previous implementation, some compilers
(notably recent versions of Clang and IAR) could produce non-constant
time code, which could allow a padding oracle attack if the attacker
has access to precise timing measurements.
* Updates to constant-time C code so that compilers are less likely to use
conditional instructions, which can have an observable difference in
timing. (Clang has been seen to do this.) Also introduce assembly
implementations for 32- and 64-bit Arm and for x86 and x86-64, which are
guaranteed not to use conditional instructions.
* Fix definition of MBEDTLS_MD_MAX_BLOCK_SIZE, which was too
small when MBEDTLS_SHA384_C was defined and MBEDTLS_SHA512_C was
undefined. Mbed TLS itself was unaffected by this, but user code
which used MBEDTLS_MD_MAX_BLOCK_SIZE could be affected. The only
release containing this bug was Mbed TLS 3.4.0.
* Fix a buffer overread when parsing short TLS application data records in
null-cipher cipher suites. Credit to OSS-Fuzz.
* Fix a remotely exploitable heap buffer overflow in TLS handshake parsing.
In TLS 1.3, all configurations are affected except PSK-only ones, and
both clients and servers are affected.
In TLS 1.2, the affected configurations are those with
MBEDTLS_USE_PSA_CRYPTO and ECDH enabled but DHM and RSA disabled,
and only servers are affected, not clients.
Credit to OSS-Fuzz.
Bugfix
* Fix proper sizing for PSA_EXPORT_[KEY_PAIR/PUBLIC_KEY]_MAX_SIZE and
PSA_SIGNATURE_MAX_SIZE buffers when at least one accelerated EC is bigger
than all built-in ones and RSA is disabled.
Resolves #6622.
* Add missing md.h includes to some of the external programs from
the programs directory. Without this, even though the configuration
was sufficient for a particular program to work, it would only print
a message that one of the required defines is missing.
* Fix declaration of mbedtls_ecdsa_sign_det_restartable() function
in the ecdsa.h header file. There was a build warning when the
configuration macro MBEDTLS_ECDSA_SIGN_ALT was defined.
Resolves #7407.
* Fix an error when MBEDTLS_ECDSA_SIGN_ALT is defined but not
MBEDTLS_ECDSA_VERIFY_ALT, causing ecdsa verify to fail. Fixes #7498.
* Fix missing PSA initialization in sample programs when
MBEDTLS_USE_PSA_CRYPTO is enabled.
* Fix the J-PAKE driver interface for user and peer to accept any values
(previously accepted values were limited to "client" or "server").
* Fix clang and armclang compilation error when targeting certain Arm
M-class CPUs (Cortex-M0, Cortex-M0+, Cortex-M1, Cortex-M23,
SecurCore SC000). Fixes #1077.
* Fix "unterminated '#pragma clang attribute push'" in sha256/sha512.c when
built with MBEDTLS_SHAxxx_USE_A64_CRYPTO_IF_PRESENT but don't have a
way to detect the crypto extensions required. A warning is still issued.
* Fixed an issue that caused compile errors when using CMake and the IAR
toolchain.
* Fix very high stack usage in SSL debug code. Reported by Maximilian
Gerhardt in #7804.
* Fix a compilation failure in the constant_time module when
building for arm64_32 (e.g., for watchos). Reported by Paulo
Coutinho in #7787.
* Fix crypt_and_hash decryption fail when used with a stream cipher
mode of operation due to the input not being multiple of block size.
Resolves #7417.
* Fix a bug in which mbedtls_x509_string_to_names() would return success
when given a invalid name string if it did not contain '=' or ','.
* Fix compilation warnings in aes.c, which prevented the
example TF-M configuration in configs/ from building cleanly:
tfm_mbedcrypto_config_profile_medium.h with
crypto_config_profile_medium.h.
* In TLS 1.3, fix handshake failure when a client in its ClientHello
proposes an handshake based on PSK only key exchange mode or at least
one of the key exchange modes using ephemeral keys to a server that
supports only the PSK key exchange mode.
* Fix CCM* with no tag being not supported in a build with CCM as the only
symmetric encryption algorithm and the PSA configuration enabled.
* Fix the build with MBEDTLS_PSA_INJECT_ENTROPY. Fixes #7516.
* Fix a compilation error on some platforms when including mbedtls/ssl.h
with all TLS support disabled. Fixes #6628.
* Fix x509 certificate generation to conform to RFC 5480 / RFC 5758 when
using ECC key. The certificate was rejected by some crypto frameworks.
Fixes #2924.
* Fix a potential corruption of the passed-in IV when mbedtls_aes_crypt_cbc()
is called with zero length and padlock is not enabled.
* Fix compile failure due to empty enum in cipher_wrap.c, when building
with a very minimal configuration. Fixes #7625.
* Fix some cases where mbedtls_mpi_mod_exp, RSA key construction or ECDSA
signature can silently return an incorrect result in low memory conditions.
* Don't try to include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE when
MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
* Fix IAR compiler warnings.
* Fix an issue when parsing an otherName subject alternative name into a
mbedtls_x509_san_other_name struct. The type-id of the otherName was not
copied to the struct. This meant that the struct had incomplete
information about the otherName SAN and contained uninitialized memory.
* Fix the detection of HardwareModuleName otherName SANs. These were being
detected by comparing the wrong field and the check was erroneously
inverted.
* Fix a build error in some configurations with MBEDTLS_PSA_CRYPTO_CONFIG
enabled, where some low-level modules required by requested PSA crypto
features were not getting automatically enabled. Fixes #7420.
* Fix undefined symbols in some builds using TLS 1.3 with a custom
configuration file.
* Fix log level for the got supported group message. Fixes #6765
* Functions in the ssl_cache module now return a negative MBEDTLS_ERR_xxx
error code on failure. Before, they returned 1 to indicate failure in
some cases involving a missing entry or a full cache.
* mbedtls_pk_parse_key() now rejects trailing garbage in encrypted keys.
* Fix the build with CMake when Everest or P256-m is enabled through
a user configuration file or the compiler command line. Fixes #8165.
Changes
* Enable Arm / Thumb bignum assembly for most Arm platforms when
compiling with gcc, clang or armclang and -O0.
* Enforce minimum RSA key size when generating a key
to avoid accidental misuse.
* Use heap memory to allocate DER encoded RSA private key.
This reduces stack usage significantly for RSA signature
operations when MBEDTLS_PSA_CRYPTO_C is defined.
* Update Windows code to use BCryptGenRandom and wcslen, and
ensure that conversions between size_t, ULONG, and int are
always done safely. Original contribution by Kevin Kane #635, #730
followed by Simon Butcher #1453.
* Users integrating their own PSA drivers should be aware that
the file library/psa_crypto_driver_wrappers.c has been renamed
to psa_crypto_driver_wrappers_no_static.c.
* When using CBC with the cipher module, the requirement to call
mbedtls_cipher_set_padding_mode() is now enforced. Previously, omitting
this call accidentally applied a default padding mode chosen at compile
time.
= Mbed TLS 3.4.1 branch released 2023-08-04
Bugfix
+3
View File
@@ -21,6 +21,9 @@ We generally don't include changelog entries for:
* Performance improvements, unless they are particularly significant.
* Changes to parts of the code base that users don't interact with directly,
such as test code and test data.
* Fixes for compiler warnings. Releases typically contain a number of fixes
of this kind, so we will only mention them in the Changelog if they are
particularly significant.
Until Mbed TLS 2.24.0, we required changelog entries in more cases.
Looking at older changelog entries is good practice for how to write a
+531 -29
View File
@@ -1,51 +1,553 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
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.
This means that users may choose which of these licenses they take the code
under.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The full text of each of these licenses is given below.
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
1. Definitions.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
END OF TERMS AND CONDITIONS
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
===============================================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+45 -8
View File
@@ -2,6 +2,20 @@ DESTDIR=/usr/local
PREFIX=mbedtls_
PERL ?= perl
ifneq (,$(filter-out lib library/%,$(or $(MAKECMDGOALS),all)))
ifeq (,$(wildcard framework/exported.make))
# Use the define keyword to get a multi-line message.
# GNU make appends ". Stop.", so tweak the ending of our message accordingly.
define error_message
$(MBEDTLS_PATH)/framework/exported.make not found.
Run `git submodule update --init` to fetch the submodule contents.
This is a fatal error
endef
$(error $(error_message))
endif
include framework/exported.make
endif
.SILENT:
.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
@@ -36,8 +50,31 @@ generated_files: programs/generated_files
generated_files: tests/generated_files
generated_files: visualc_files
# Set GEN_FILES to the empty string to disable dependencies on generated
# source files. Then `make generated_files` will only build files that
# are missing, it will not rebuilt files that are present but out of date.
# This is useful, for example, if you have a source tree where
# `make generated_files` has already run and file timestamps reflect the
# time the files were copied or extracted, and you are now in an environment
# 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 ?=
# In dependencies where the target is a configuration-independent generated
# file, use `TARGET: $(gen_file_dep) DEPENDENCY1 DEPENDENCY2 ...`
# rather than directly `TARGET: DEPENDENCY1 DEPENDENCY2 ...`. This
# enables the re-generation to be turned off when GEN_FILES is disabled.
ifdef GEN_FILES
gen_file_dep =
else
# Order-only dependency: generate the target if it's absent, but don't
# re-generate it if it's present but older than its dependencies.
gen_file_dep = |
endif
.PHONY: visualc_files
VISUALC_FILES = visualc/VS2013/mbedTLS.sln visualc/VS2013/mbedTLS.vcxproj
VISUALC_FILES = visualc/VS2017/mbedTLS.sln visualc/VS2017/mbedTLS.vcxproj
# TODO: $(app).vcxproj for each $(app) in programs/
visualc_files: $(VISUALC_FILES)
@@ -45,10 +82,10 @@ visualc_files: $(VISUALC_FILES)
# present before it runs. It doesn't matter if the files aren't up-to-date,
# they just need to be present.
$(VISUALC_FILES): | library/generated_files
$(VISUALC_FILES): scripts/generate_visualc_files.pl
$(VISUALC_FILES): scripts/data_files/vs2013-app-template.vcxproj
$(VISUALC_FILES): scripts/data_files/vs2013-main-template.vcxproj
$(VISUALC_FILES): scripts/data_files/vs2013-sln-template.sln
$(VISUALC_FILES): $(gen_file_dep) scripts/generate_visualc_files.pl
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-app-template.vcxproj
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-main-template.vcxproj
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-sln-template.sln
# TODO: also the list of .c and .h source files, but not their content
$(VISUALC_FILES):
echo " Gen $@ ..."
@@ -124,10 +161,10 @@ neat: clean_more_on_top
$(MAKE) -C programs neat
$(MAKE) -C tests neat
ifndef WINDOWS
rm -f visualc/VS2013/*.vcxproj visualc/VS2013/mbedTLS.sln
rm -f visualc/VS2017/*.vcxproj visualc/VS2017/mbedTLS.sln
else
if exist visualc\VS2013\*.vcxproj del /Q /F visualc\VS2013\*.vcxproj
if exist visualc\VS2013\mbedTLS.sln del /Q /F visualc\VS2013\mbedTLS.sln
if exist visualc\VS2017\*.vcxproj del /Q /F visualc\VS2017\*.vcxproj
if exist visualc\VS2017\mbedTLS.sln del /Q /F visualc\VS2017\mbedTLS.sln
endif
check: lib tests
+1 -1
View File
@@ -3,7 +3,7 @@
"Name": "mbed TLS",
"License": "Apache License V2.0",
"License File": "LICENSE",
"Version Number": "3.4.1",
"Version Number": "3.6.0",
"Owner": "hanjin5@huawei.com",
"Upstream URL": "https://www.trustedfirmware.org/projects/mbed-tls/",
"Description": "An open source, portable, easy to use, readable and flexible SSL library."
+26 -13
View File
@@ -47,13 +47,17 @@ The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx
You need the following tools to build the library with the provided makefiles:
* GNU Make 3.82 or a build tool that CMake supports.
* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, IAR 8 and Visual Studio 2013. More recent versions should work. Slightly older versions may work.
* Python 3.6 to generate the test code, and to generate sample programs in the development branch.
* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, Arm Compiler 6, IAR 8 and Visual Studio 2017. More recent versions should work. Slightly older versions may work.
* Python 3.8 to generate the test code. Python is also needed to integrate PSA drivers and to build the development branch (see next section).
* Perl to run the tests, and to generate some source files in the development branch.
* CMake 3.10.2 or later (if using CMake).
* Microsoft Visual Studio 2013 or later (if using Visual Studio).
* Microsoft Visual Studio 2017 or later (if using Visual Studio).
* Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work).
### Git usage
The `development` branch and the `mbedtls-3.6` long-term support branch of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar).
### Generated source files in the development branch
The source code of Mbed TLS includes some files that are automatically generated by scripts and whose content depends only on the Mbed TLS source, not on the platform or on the library configuration. These files are not included in the development branch of Mbed TLS, but the generated files are included in official releases. This section explains how to generate the missing files in the development branch.
@@ -61,7 +65,7 @@ The source code of Mbed TLS includes some files that are automatically generated
The following tools are required:
* Perl, for some library source files and for Visual Studio build files.
* Python 3 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
* Python 3.8 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
```
python3 -m pip install --user -r scripts/basic.requirements.txt
```
@@ -221,7 +225,7 @@ subproject.
### Microsoft Visual Studio
The build files for Microsoft Visual Studio are generated for Visual Studio 2013.
The build files for Microsoft Visual Studio are generated for Visual Studio 2017.
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need Python and perl environments as well. However, the selftest program in `programs/test/` is still available.
@@ -246,7 +250,7 @@ For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, ad
- `tests/scripts/depends.py` test builds in configurations with a single curve, key exchange, hash, cipher, or pkalg on.
- `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `mbedtls_config.h`, etc).
Instead of manually installing the required versions of all tools required for testing, it is possible to use the Docker images from our CI systems, as explained in [our testing infrastructure repository](https://github.com/Mbed-TLS/mbedtls-test/blob/master/README.md#quick-start).
Instead of manually installing the required versions of all tools required for testing, it is possible to use the Docker images from our CI systems, as explained in [our testing infrastructure repository](https://github.com/Mbed-TLS/mbedtls-test/blob/main/README.md#quick-start).
Porting Mbed TLS
----------------
@@ -293,19 +297,28 @@ However, it does not aim to implement the whole specification; in particular it
The X.509 and TLS code can use PSA cryptography for most operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `mbedtls_config.h`. Note that TLS 1.3 uses PSA cryptography for most operations regardless of this option. See `docs/use-psa-crypto.md` for details.
### Upcoming features
### PSA drivers
Future releases of this library will include:
Mbed TLS supports drivers for cryptographic accelerators, secure elements and random generators. This is work in progress. Please note that the driver interfaces are not fully stable yet and may change without notice. We intend to preserve backward compatibility for application code (using the PSA Crypto API), but the code of the drivers may have to change in future minor releases of Mbed TLS.
* A driver programming interface, which makes it possible to use hardware accelerators instead of the default software implementation for chosen algorithms.
* Support for external keys to be stored and manipulated exclusively in a separate cryptoprocessor.
* A configuration mechanism to compile only the algorithms you need for your application.
* A wider set of cryptographic algorithms.
Please see the [PSA driver example and guide](docs/psa-driver-example-and-guide.md) for information on writing a driver.
When using drivers, you will generally want to enable two compilation options (see the reference manual for more information):
* `MBEDTLS_USE_PSA_CRYPTO` is necessary so that the X.509 and TLS code calls the PSA drivers rather than the built-in software implementation.
* `MBEDTLS_PSA_CRYPTO_CONFIG` allows you to enable PSA cryptographic mechanisms without including the code of the corresponding software implementation. This is not yet supported for all mechanisms.
License
-------
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license. See the [LICENSE](LICENSE) file for the full text of this license. Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses. This enables LTS (Long Term Support) branches of the software to be provided under either the Apache-2.0 OR GPL-2.0-or-later licenses.
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under 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, and [the 'License and Copyright' section in the contributing guidelines](CONTRIBUTING.md#License-and-Copyright) for more information.
### Third-party code included in Mbed TLS
This project contains code from other projects. This code is located within the `3rdparty/` directory. The original license text is included within project subdirectories, where it differs from the normal Mbed TLS license, and/or in source files. The projects are listed below:
* `3rdparty/everest/`: Files stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is distributed in Mbed TLS under a dual Apache-2.0 OR GPL-2.0-or-later license with permission from the author.
Contributing
------------
+9
View File
@@ -135,3 +135,12 @@ Guide](docs/architecture/alternative-implementations.md) for more information.
- Use cryptographic mechanisms that are not based on block ciphers. In
particular, for authenticated encryption, use ChaCha20/Poly1305 instead of
block cipher modes. For random generation, use HMAC\_DRBG instead of CTR\_DRBG.
#### Everest
The HACL* implementation of X25519 taken from the Everest project only protects
against remote timing attacks. (See their [Security
Policy](https://github.com/hacl-star/hacl-star/blob/main/SECURITY.md).)
The Everest variant is only used when `MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED`
configuration option is defined. This option is off by default.
+68
View 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
View File
@@ -0,0 +1,25 @@
/**
* \file configs/crypto-config-ccm-aes-sha256.h
*
* \brief PSA crypto configuration with only symmetric cryptography: CCM-AES,
* SHA-256, HMAC and key derivation
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef PSA_CRYPTO_CONFIG_H
#define PSA_CRYPTO_CONFIG_H
#define PSA_WANT_ALG_CCM 1
#define PSA_WANT_ALG_HMAC 1
#define PSA_WANT_ALG_SHA_256 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_HMAC 1
#define PSA_WANT_KEY_TYPE_AES 1
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
#endif /* PSA_CRYPTO_CONFIG_H */
+25
View 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
View 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.
*/
+132
View File
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2018-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/**
* \file psa/crypto_config.h
* \brief PSA crypto configuration options (set of defines)
*
*/
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
/**
* When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h,
* this file determines which cryptographic mechanisms are enabled
* through the PSA Cryptography API (\c psa_xxx() functions).
*
* To enable a cryptographic mechanism, uncomment the definition of
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
* To disable a cryptographic mechanism, comment out the definition of
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
* The names of cryptographic mechanisms correspond to values
* defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead
* of \c PSA_.
*
* Note that many cryptographic mechanisms involve two symbols: one for
* the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm
* (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve
* additional symbols.
*/
#else
/**
* When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h,
* this file is not used, and cryptographic mechanisms are supported
* through the PSA API if and only if they are supported through the
* mbedtls_xxx API.
*/
#endif
#ifndef PROFILE_M_PSA_CRYPTO_CONFIG_H
#define PROFILE_M_PSA_CRYPTO_CONFIG_H
/*
* CBC-MAC is not yet supported via the PSA API in Mbed TLS.
*/
//#define PSA_WANT_ALG_CBC_MAC 1
//#define PSA_WANT_ALG_CBC_NO_PADDING 1
//#define PSA_WANT_ALG_CBC_PKCS7 1
#define PSA_WANT_ALG_CCM 1
//#define PSA_WANT_ALG_CMAC 1
//#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_ECB_NO_PADDING 1
#define PSA_WANT_ALG_ECDH 1
#define PSA_WANT_ALG_ECDSA 1
//#define PSA_WANT_ALG_GCM 1
#define PSA_WANT_ALG_HKDF 1
#define PSA_WANT_ALG_HMAC 1
//#define PSA_WANT_ALG_MD5 1
//#define PSA_WANT_ALG_OFB 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_PBKDF2_HMAC 1
//#define PSA_WANT_ALG_RIPEMD160 1
//#define PSA_WANT_ALG_RSA_OAEP 1
//#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
//#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
//#define PSA_WANT_ALG_RSA_PSS 1
//#define PSA_WANT_ALG_SHA_1 1
#define PSA_WANT_ALG_SHA_224 1
#define PSA_WANT_ALG_SHA_256 1
//#define PSA_WANT_ALG_SHA_384 1
//#define PSA_WANT_ALG_SHA_512 1
//#define PSA_WANT_ALG_STREAM_CIPHER 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
//#define PSA_WANT_ALG_XTS 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
//#define PSA_WANT_ECC_MONTGOMERY_255 1
//#define PSA_WANT_ECC_MONTGOMERY_448 1
//#define PSA_WANT_ECC_SECP_K1_192 1
/*
* SECP224K1 is buggy via the PSA API in Mbed TLS
* (https://github.com/Mbed-TLS/mbedtls/issues/3541). Thus, do not enable it by
* default.
*/
//#define PSA_WANT_ECC_SECP_K1_224 1
//#define PSA_WANT_ECC_SECP_K1_256 1
//#define PSA_WANT_ECC_SECP_R1_192 1
//#define PSA_WANT_ECC_SECP_R1_224 1
#define PSA_WANT_ECC_SECP_R1_256 1
//#define PSA_WANT_ECC_SECP_R1_384 1
//#define PSA_WANT_ECC_SECP_R1_521 1
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_HMAC 1
#define PSA_WANT_KEY_TYPE_AES 1
//#define PSA_WANT_KEY_TYPE_ARIA 1
//#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 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
#ifdef CRYPTO_HW_ACCELERATOR
#include "crypto_accelerator_config.h"
#endif
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */
@@ -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.
*/
@@ -0,0 +1,573 @@
/**
* \file config.h
*
* \brief Configuration options (set of defines)
*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*/
/*
* 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
/**
* \name SECTION: System support
*
* This section sets system specific settings.
* \{
*/
/**
* \def MBEDTLS_HAVE_ASM
*
* The compiler has support for asm().
*
* Requires support for asm() in compiler.
*
* Used in:
* library/aria.c
* library/timing.c
* include/mbedtls/bn_mul.h
*
* Required by:
* MBEDTLS_AESNI_C
* MBEDTLS_PADLOCK_C
*
* Comment to disable the use of assembly code.
*/
#define MBEDTLS_HAVE_ASM
/**
* \def MBEDTLS_PLATFORM_MEMORY
*
* Enable the memory allocation layer.
*
* By default mbed TLS uses the system-provided calloc() and free().
* This allows different allocators (self-implemented or provided) to be
* provided to the platform abstraction layer.
*
* Enabling MBEDTLS_PLATFORM_MEMORY without the
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
* free() function pointer at runtime.
*
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
* alternate function at compile time.
*
* Requires: MBEDTLS_PLATFORM_C
*
* Enable this layer to allow use of alternative memory allocators.
*/
#define MBEDTLS_PLATFORM_MEMORY
/* \} name SECTION: System support */
/**
* \name SECTION: mbed TLS feature support
*
* This section sets support for features that are or are not needed
* within the modules that are enabled.
* \{
*/
/**
* \def MBEDTLS_AES_ROM_TABLES
*
* Use precomputed AES tables stored in ROM.
*
* Uncomment this macro to use precomputed AES tables stored in ROM.
* Comment this macro to generate AES tables in RAM at runtime.
*
* Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
* (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
* initialization time before the first AES operation can be performed.
* It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
* MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
* performance if ROM access is slower than RAM access.
*
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
*
*/
#define MBEDTLS_AES_ROM_TABLES
/**
* \def MBEDTLS_AES_FEWER_TABLES
*
* Use less ROM/RAM for AES tables.
*
* Uncommenting this macro omits 75% of the AES tables from
* ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
* by computing their values on the fly during operations
* (the tables are entry-wise rotations of one another).
*
* Tradeoff: Uncommenting this reduces the RAM / ROM footprint
* by ~6kb but at the cost of more arithmetic operations during
* runtime. Specifically, one has to compare 4 accesses within
* different tables to 4 accesses with additional arithmetic
* operations within the same table. The performance gain/loss
* depends on the system and memory details.
*
* This option is independent of \c MBEDTLS_AES_ROM_TABLES.
*
*/
#define MBEDTLS_AES_FEWER_TABLES
/**
* \def MBEDTLS_ECP_NIST_OPTIM
*
* Enable specific 'modulo p' routines for each NIST prime.
* Depending on the prime and architecture, makes operations 4 to 8 times
* faster on the corresponding curve.
*
* Comment this macro to disable NIST curves optimisation.
*/
#define MBEDTLS_ECP_NIST_OPTIM
/**
* \def MBEDTLS_NO_PLATFORM_ENTROPY
*
* Do not use built-in platform entropy functions.
* This is useful if your platform does not support
* standards like the /dev/urandom or Windows CryptoAPI.
*
* Uncomment this macro to disable the built-in platform entropy functions.
*/
#define MBEDTLS_NO_PLATFORM_ENTROPY
/**
* \def MBEDTLS_ENTROPY_NV_SEED
*
* Enable the non-volatile (NV) seed file-based entropy source.
* (Also enables the NV seed read/write functions in the platform layer)
*
* This is crucial (if not required) on systems that do not have a
* cryptographic entropy source (in hardware or kernel) available.
*
* Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
*
* \note The read/write functions that are used by the entropy source are
* determined in the platform layer, and can be modified at runtime and/or
* compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
*
* \note If you use the default implementation functions that read a seedfile
* with regular fopen(), please make sure you make a seedfile with the
* proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
* least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
* and written to or you will get an entropy source error! The default
* implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
* bytes from the file.
*
* \note The entropy collector will write to the seed file before entropy is
* given to an external source, to update it.
*/
#define MBEDTLS_ENTROPY_NV_SEED
/**
* \def MBEDTLS_PSA_CRYPTO_SPM
*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
* Partition Manager) integration which separates the code into two parts: a
* NSPE (Non-Secure Process Environment) and an SPE (Secure Process
* Environment).
*
* Module: library/psa_crypto.c
* Requires: MBEDTLS_PSA_CRYPTO_C
*
*/
#define MBEDTLS_PSA_CRYPTO_SPM
/**
* \def MBEDTLS_SHA256_SMALLER
*
* Enable an implementation of SHA-256 that has lower ROM footprint but also
* lower performance.
*
* The default implementation is meant to be a reasonnable compromise between
* performance and size. This version optimizes more aggressively for size at
* the expense of performance. Eg on Cortex-M4 it reduces the size of
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
* 30%.
*
* Uncomment to enable the smaller implementation of SHA256.
*/
#define MBEDTLS_SHA256_SMALLER
/**
* \def MBEDTLS_PSA_CRYPTO_CONFIG
*
* This setting allows support for cryptographic mechanisms through the PSA
* API to be configured separately from support through the mbedtls API.
*
* When this option is disabled, the PSA API exposes the cryptographic
* mechanisms that can be implemented on top of the `mbedtls_xxx` API
* configured with `MBEDTLS_XXX` symbols.
*
* When this option is enabled, the PSA API exposes the cryptographic
* mechanisms requested by the `PSA_WANT_XXX` symbols defined in
* include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are
* automatically enabled if required (i.e. if no PSA driver provides the
* mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols
* in mbedtls_config.h.
*
* If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
* an alternative header to include instead of include/psa/crypto_config.h.
*
* This feature is still experimental and is not ready for production since
* it is not completed.
*/
#define MBEDTLS_PSA_CRYPTO_CONFIG
/* \} name SECTION: mbed TLS feature support */
/**
* \name SECTION: mbed TLS modules
*
* This section enables or disables entire modules in mbed TLS
* \{
*/
/**
* \def MBEDTLS_AES_C
*
* Enable the AES block cipher.
*
* Module: library/aes.c
* Caller: library/cipher.c
* library/pem.c
* library/ctr_drbg.c
*
* This module is required to support the TLS ciphersuites that use the AES
* cipher.
*
* PEM_PARSE uses AES for decrypting encrypted keys.
*/
#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
*
* Enable the generic cipher layer.
*
* Module: library/cipher.c
*
* Uncomment to enable generic cipher wrappers.
*/
#define MBEDTLS_CIPHER_C
/**
* \def MBEDTLS_CTR_DRBG_C
*
* Enable the CTR_DRBG AES-based random generator.
* The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
*
* Module: library/ctr_drbg.c
* Caller:
*
* Requires: MBEDTLS_AES_C
*
* This module provides the CTR_DRBG AES random number generator.
*/
#define MBEDTLS_CTR_DRBG_C
/**
* \def MBEDTLS_ENTROPY_C
*
* Enable the platform-specific entropy code.
*
* Module: library/entropy.c
* Caller:
*
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
*
* This module provides a generic entropy pool
*/
#define MBEDTLS_ENTROPY_C
/**
* \def MBEDTLS_HKDF_C
*
* Enable the HKDF algorithm (RFC 5869).
*
* Module: library/hkdf.c
* Caller:
*
* Requires: MBEDTLS_MD_C
*
* 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_MEMORY_BUFFER_ALLOC_C
*
* Enable the buffer allocator implementation that makes use of a (stack)
* based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
* calls)
*
* Module: library/memory_buffer_alloc.c
*
* Requires: MBEDTLS_PLATFORM_C
* MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
*
* Enable this module to enable the buffer memory allocator.
*/
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
/**
* \def MBEDTLS_PLATFORM_C
*
* Enable the platform abstraction layer that allows you to re-assign
* functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
*
* Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
* or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
* above to be specified at runtime or compile time respectively.
*
* \note This abstraction layer must be enabled on Windows (including MSYS2)
* as other module rely on it for a fixed snprintf implementation.
*
* Module: library/platform.c
* Caller: Most other .c files
*
* This module enables abstraction of common (libc) functions.
*/
#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
*
* Enable the Platform Security Architecture cryptography API.
*
* Module: library/psa_crypto.c
*
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
*
*/
#define MBEDTLS_PSA_CRYPTO_C
/**
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
*
* Enable the Platform Security Architecture persistent key storage.
*
* Module: library/psa_crypto_storage.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C,
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
* the PSA ITS interface
*/
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
/* \} name SECTION: mbed TLS modules */
/**
* \name SECTION: General configuration options
*
* This section contains Mbed TLS build settings that are not associated
* with a particular module.
*
* \{
*/
/**
* \def MBEDTLS_CONFIG_FILE
*
* If defined, this is a header which will be included instead of
* `"mbedtls/mbedtls_config.h"`.
* This header file specifies the compile-time configuration of Mbed TLS.
* Unlike other configuration options, this one must be defined on the
* compiler command line: a definition in `mbedtls_config.h` would have
* no effect.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h"
/**
* \def MBEDTLS_USER_CONFIG_FILE
*
* If defined, this is a header which will be included after
* `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE.
* This allows you to modify the default configuration, including the ability
* to undefine options that are enabled by default.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_USER_CONFIG_FILE "/dev/null"
/**
* \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE
*
* If defined, this is a header which will be included instead of
* `"psa/crypto_config.h"`.
* This header file specifies which cryptographic mechanisms are available
* through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and
* is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h"
/**
* \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
*
* If defined, this is a header which will be included after
* `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE.
* This allows you to modify the default configuration, including the ability
* to undefine options that are enabled by default.
*
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
* non-standard feature of the C language, so this feature is only available
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
*
* The value of this symbol is typically a path in double quotes, either
* absolute or relative to a directory on the include search path.
*/
//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
/** \} name SECTION: General configuration options */
/**
* \name SECTION: Module configuration options
*
* This section allows for the setting of module specific sizes and
* configuration options. The default values are already present in the
* relevant header files and should suffice for the regular use cases.
*
* Our advice is to enable options and change their values here
* only if you have a good reason and know the consequences.
*
* Please check the respective header file for documentation on these
* parameters (to prevent duplicate documentation).
* \{
*/
/* 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
#include "tfm_mbedcrypto_config_extra_nv_seed.h"
#endif /* CRYPTO_NV_SEED */
#if !defined(CRYPTO_HW_ACCELERATOR) && defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls_entropy_nv_seed_config.h"
#endif
#ifdef CRYPTO_HW_ACCELERATOR
#include "mbedtls_accelerator_config.h"
#endif
#endif /* PROFILE_M_MBEDTLS_CONFIG_H */
+1 -6
View File
@@ -2,12 +2,7 @@ PANDOC = pandoc
default: all
all_markdown = \
mbed-crypto-storage-specification.md \
testing/driver-interface-test-strategy.md \
testing/invasive-testing.md \
testing/test-framework.md \
# This line is intentionally left blank
all_markdown = $(wildcard *.md */*.md)
html: $(all_markdown:.md=.html)
pdf: $(all_markdown:.md=.pdf)
@@ -1,7 +1,9 @@
Mbed Crypto storage specification
Mbed TLS storage specification
=================================
This document specifies how Mbed Crypto uses storage.
This document specifies how Mbed TLS uses storage.
Key storage was originally introduced in a product called Mbed Crypto, which was re-distributed via Mbed TLS and has since been merged into Mbed TLS.
This document contains historical information both from before and after this merge.
Mbed Crypto may be upgraded on an existing device with the storage preserved. Therefore:
@@ -354,7 +356,7 @@ Supported features:
* [Persistent keys](#key-file-format-for-mbed-tls-2.25.0) designated by a [key identifier and owner](#key-names-for-mbed-tls-2.25.0). Keys can be:
* Transparent, stored in the export format.
* Opaque, using the unified driver interface with statically registered drivers (`MBEDTLS_PSA_CRYPTO_DRIVERS`). The driver determines the content of the opaque key blob.
* Opaque, using the PSA driver interface with statically registered drivers. The driver determines the content of the opaque key blob.
* Opaque, using the deprecated secure element interface with dynamically registered drivers (`MBEDTLS_PSA_CRYPTO_SE_C`). The driver picks a slot number which is stored in the place of the key material.
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0) on ITS only.
@@ -49,7 +49,7 @@ psa_status_t psa_api( ... )
```
The code of most PSA APIs is expected to match precisely the above layout. However, it is likely that the code structure of some APIs will be more complicated with several calls to the driver interface, mainly to encompass a larger variety of hardware designs. For example, to encompass hardware accelerators that are capable of verifying a MAC and those that are only capable of computing a MAC, the psa_mac_verify() API could call first psa_driver_wrapper_mac_verify() and then fallback to psa_driver_wrapper_mac_compute().
The implementations of `psa_driver_wrapper_<entry_point>` functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are generated in a psa_crypto_driver_wrappers.c C file and the function prototypes declared in a psa_crypto_driver_wrappers.h header file.
The implementations of `psa_driver_wrapper_<entry_point>` functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are splited into two parts. The static ones are generated in a psa_crypto_driver_wrappers.h header file, the non-static ones are generated in a psa_crypto_driver_wrappers_no_static.c C file and the function prototypes declared in a psa_crypto_driver_wrappers_no_static.h header file.
The psa_driver_wrapper_<entry_point>() functions dispatch cryptographic operations to accelerator drivers, secure element drivers as well as to the software implementations of cryptographic operations.
@@ -71,3 +71,105 @@ In case of any error occurring at step 3 or 4, psa_fail_key_creation() is called
A driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software.
An Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa_<driver name>_<entry point>(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the "import_key" entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key().
## How to implement a new cryptographic mechanism
Summary of files to modify when adding a new algorithm or key type:
* [ ] PSA Crypto API draft, if not already done ¡ª [PSA standardization](#psa-standardization)
* [ ] `include/psa/crypto_values.h` or `include/psa/crypto_extra.h` ¡ª [New functions and macros](#new-functions-and-macros)
* [ ] `include/psa/crypto_config.h`, `tests/include/test/drivers/crypto_config_test_driver_extension.h` ¡ª [Preprocessor symbols](#preprocessor-symbols)
* Occasionally `library/check_crypto_config.h` ¡ª [Preprocessor symbols](#preprocessor-symbols)
* [ ] `include/mbedtls/config_psa.h` ¡ª [Preprocessor symbols](#preprocessor-symbols)
* [ ] `library/psa_crypto.c`, `library/psa_crypto_*.[hc]` ¡ª [Implementation of the mechanisms](#implementation-of-the-mechanisms)
* [ ] `include/psa/crypto_builtin_*.h` ¡ª [Translucent data structures](#translucent-data-structures)
* [ ] `tests/suites/test_suite_psa_crypto_metadata.data` ¡ª [New functions and macros](#new-functions-and-macros)
* (If adding `PSA_IS_xxx`) `tests/suites/test_suite_psa_crypto_metadata.function` ¡ª [New functions and macros](#new-functions-and-macros)
* [ ] `tests/suites/test_suite_psa_crypto*.data`, `tests/suites/test_suite_psa_crypto*.function` ¡ª [Unit tests](#unit-tests)
* [ ] `scripts/mbedtls_dev/crypto_knowledge.py`, `scripts/mbedtls_dev/asymmetric_key_data.py` ¡ª [Unit tests](#unit-tests)
* [ ] `ChangeLog.d/*.txt` ¡ª changelog entry
Summary of files to modify when adding new API functions:
* [ ] `include/psa/crypto.h` and `include/psa/crypto_sizes.h`, or `include/psa/crypto_extra.h` ¡ª [New functions and macros](#new-functions-and-macros)
* [ ] `library/psa_crypto.c`, `scripts/data_files/driver_templates/*.jinja` ¡ª [Implementation of the mechanisms](#implementation-of-the-mechanisms)
* [ ] If adding stateful functions: `include/psa/crypto_struct.h`, `include/psa/crypto_builtin_*.h`, `include/psa/crypto_driver_contexts_*.h` ¡ª [Translucent data structures](#translucent-data-structures)
* [ ] `tests/suites/test_suite_psa_crypto.data`, `tests/suites/test_suite_psa_crypto.function`, `tests/suites/test_suite_psa_crypto_driver_wrappers.*` ¡ª [Unit tests](#unit-tests)
Note that this is just a basic guide. In some cases, you won't need to change all the files listed here. In some cases, you may need to change other files.
### PSA standardization
Typically, if there's enough demand for a cryptographic mechanism in Mbed TLS, there's enough demand for it to be part of the official PSA Cryptography specification. Therefore the first step before implementing a new mechanism should be to approach the PSA Cryptography working group in Arm for standardization.
At the time of writing, all cryptographic mechanisms that are accessible through `psa_xxx` APIs in in Mbed TLS are current or upcoming PSA standards. Mbed TLS implements some extensions to the PSA API that offer extra integration customization or extra key policies.
Mbed TLS routinely implements cryptographic mechanisms that are not yet part of a published PSA standard, but that are scheduled to be part of a future version of the standard. The Mbed TLS implementation validates the feasibility of the upcoming PSA standard. The PSA Cryptography working group and the Mbed TLS development team communicate during the elaboration of the new interfaces.
### New functions and macros
If a mechanism requires new functions, they should follow the design guidelines in the PSA Cryptography API specification.
Functions that are part of the current or upcoming API are declared in `include/psa/crypto.h`, apart from structure accessors defined in `include/psa/crypto_struct.h`. Functions that have output buffers have associated sufficient-output-size macros in `include/psa/crypto_sizes.h`.
Constants (algorithm identifiers, key type identifiers, etc.) and associated destructor macros (e.g. `PSA_IS_xxx()`) are defined in `include/psa/crypto_values.h`.
Functions and macros that are not intended for standardization, or that are at a stage where the draft standard might still evolve significantly, are declared in `include/psa/crypto_extra.h`.
The PSA Cryptography API specification defines both names and values for certain kinds of constants: algorithms (`PSA_ALG_xxx`), key types (`PSA_KEY_TYPE_xxx`), ECC curve families (`PSA_ECC_FAMILY_xxx`), DH group families (`PSA_DH_FAMILY_xxx`). If Mbed TLS defines an algorithm or a key type that is not part of a current or upcoming PSA standard, pick a value with the `VENDOR` flag set. If Mbed TLS defines an ECC curve or DH group family that is not part of a current or upcoming PSA standard, define a vendor key type and use the family identifier only with this vendor key type.
New constants must have a test case in `tests/suites/test_suite_psa_crypto_metadata.data` that verifies that `PSA_IS_xxx` macros behave properly with the new constant. New `PSA_IS_xxx` macros must be declared in `tests/suites/test_suite_psa_crypto_metadata.function`.
### Preprocessor symbols
Each cryptographic mechanism is optional and can be selected by the application at build time. For each feature `PSA_ttt_xxx`:
* The feature is available to applications when the preprocessor symbol `PSA_WANT_ttt_xxx` is defined. These symbols are set:
* If `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled: based on the available mechanisms in Mbed TLS, deduced from `mbedtls/mbedtls_config.h` by code in `include/mbedtls/config_psa.h`.
* if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled: in the application configuration file `include/psa/crypto_config.h` (or `MBEDTLS_PSA_CRYPTO_CONFIG_FILE`, plus `MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`), with code in `include/mbedtls/config_psa.h` deducing the necessary underlying `MBEDTLS_xxx` symbols.
* For transparent keys (keys that are not in a secure element), the feature is implemented by Mbed TLS if `MBEDTLS_PSA_BUILTIN_ttt_xxx` is defined, and by an accelerator driver if `MBEDTLS_PSA_ACCEL_ttt_xxx` is defined. `MBEDTLS_PSA_BUILTIN_ttt_xxx` constants are set in `include/mbedtls/config_psa.h` based on the application requests `PSA_WANT_ttt_xxx` and the accelerator driver declarations `MBEDTLS_PSA_ACCEL_ttt_xxx`.
* For the testing of the driver dispatch code, `tests/include/test/drivers/crypto_config_test_driver_extension.h` sets additional `MBEDTLS_PSA_ACCEL_xxx` symbols.
For more details, see *[Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](../proposed/psa-conditional-inclusion-c.html)*.
Some mechanisms require other mechanisms. For example, you can't do GCM without a block cipher, or RSA-PSS without RSA keys. When mechanism A requires mechanism B, `include/mbedtls/config_psa.h` ensures that B is enabled whenever A is enabled. When mechanism A requires at least one of a set {B1, B2, B3, ...} but there is no particular reason why enabling A would enable any of the specific Bi's, it's up to the application to choose Bi's and the file `library/check_crypto_config.h` contains compile-time constraints to ensure that at least one Bi is enabled.
### Implementation of the mechanisms
The general structure of a cryptographic operation function is:
1. API function defined in `library/psa_crypto.c`. The entry point performs generic checks that don't depend on whether the mechanism is implemented in software or in a driver and looks up keys in the key store.
2. Driver dispatch code in `scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja`, `scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja` or files included from there.
3. Built-in implementation in `library/psa_crypto_*.c` (with function declarations in the corresponding `.h` file). These files typically contain the implementation of modes of operation over basic building blocks that are defined elsewhere. For example, HMAC is implemented in `library/psa_crypto_mac.c` but the underlying hash functions are implemented in `library/sha*.c` and `library/md*.c`.
4. Basic cryptographic building blocks in `library/*.c`.
When implementing a new algorithm or key type, there are typically things to change in `library/crypto.c` (e.g. buffer size calculations, algorithm/key-type compatibility) and in the built-in implementation, but not in the driver dispatch code.
### Translucent data structures
Some mechanisms require state to be kept between function calls. Keys and key-like data is kept in the key store, which PSA manages internally. Other state, for example the state of multipart operations, is kept in structures allocated by the caller.
The size of operation structures needs to be known at compile time, since callers may allocate them on the stack. Therefore these structures are defined in a public header: `include/psa/crypto_struct.h` for the parts that are independent of the underlying implementation, `include/psa/crypto_builtin_*` for parts that are specific to the Mbed TLS built-in implementation, `include/psa/crypto_driver_*.h` for structures implemented by drivers.
### Unit tests
A number of unit tests are automatically generated by `tests/scripts/generate_psa_tests.py` based on the algorithms and key types declared in `include/psa/crypto_values.h` and `include/psa/crypto_extra.h`:
* Attempt to create a key with a key type that is not supported.
* Attempt to perform an operation with a combination of key type and algorithm that is not valid or not supported.
* Storage and retrieval of a persistent key.
When adding a new key type or algorithm:
* `scripts/mbedtls_dev/crypto_knowledge.py` contains knowledge about the compatibility of key types, key sizes and algorithms.
* `scripts/mbedtls_dev/asymmetric_key_data.py` contains valid key data for asymmetric key types.
Other things need to be tested manually, either in `tests/suites/test_sutie_psa_crypto.data` or in another file. For example (this is not an exhaustive list):
* Known answer tests.
* Potential edge cases (e.g. data less/equal/more than the block size, number equal to zero in asymmetric cryptography).
* Tests with invalid keys (e.g. wrong size or format).
* Tests with invalid data (e.g. wrong size or format, output buffer too small, invalid padding).
* For new functions: incorrect function call sequence, driver dispatch (in `tests/suites/test_suite_psa_crypto_driver_wrappers.*`).
* For key derivation algorithms: variation on the sequence of input steps, variation on the output size.
@@ -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.
@@ -43,8 +43,11 @@ record() {
fi
}
# save current HEAD
HEAD=$(git branch --show-current)
# save current HEAD.
# Note: this can optionally be updated to
# HEAD=$(git branch --show-current)
# when using a Git version above 2.22
HEAD=$(git rev-parse --abbrev-ref HEAD)
# get the numbers before this PR for default and full
cleanup
@@ -0,0 +1,344 @@
Bridges between legacy and PSA crypto APIs
==========================================
## Introduction
### Goal of this document
This document explores the needs of applications that use both Mbed TLS legacy crypto interfaces and PSA crypto interfaces. Based on [requirements](#requirements), we [analyze gaps](#gap-analysis) and [API design](#api-design).
This is a design document. The target audience is library maintainers. See the companion document [“Transitioning to the PSA API”](../../psa-transition.md) for a user focus on the same topic.
### Keywords
* [TODO] A part of the analysis that isn't finished.
* [OPEN] Open question: a specific aspect of the design where there are several plausible decisions.
* [ACTION] A finalized part of the design that will need to be carried out.
### Context
Mbed TLS 3.x supports two cryptographic APIs:
* The legacy API `mbedtls_xxx` is inherited from PolarSSL.
* The PSA API `psa_xxx` was introduced in Mbed TLS 2.17.
Mbed TLS is gradually shifting from the legacy API to the PSA API. Mbed TLS 4.0 will be the first version where the PSA API is considered the main API, and large parts of the legacy API will be removed.
In Mbed TLS 4.0, the cryptography will be provided by a separate project [TF-PSA-Crypto](https://github.com/Mbed-TLS/TF-PSA-Crypto). For simplicity, in this document, we just refer to the whole as “Mbed TLS”.
### Document history
This document was originally written when preparing Mbed TLS 3.6. Mbed TLS 3.6 includes both PSA and legacy APIs covering largely overlapping ground. Many legacy APIs will be removed in Mbed TLS 4.0.
## Requirements
### Why mix APIs?
There is functionality that is tied to one API and is not directly available in the other API:
* Only PSA fully supports PSA accelerators and secure element integration.
* Only PSA supports isolating cryptographic material in a secure service.
* The legacy API has features that are not present (yet) in PSA, notably parsing and formatting asymmetric keys.
The legacy API can partially leverage PSA features via `MBEDTLS_USE_PSA_CRYPTO`, but this has limited scope.
In addition, many applications cannot be migrated in a single go. For large projects, it is impractical to rewrite a significant part of the code all at once. (For example, Mbed TLS itself will have taken more than 6 years to transition.) Projects that use one or more library in addition to Mbed TLS must follow the evolution of these libraries, each of which might have its own pace.
### Where mixing happens
Mbed TLS can be, and normally is, built with support for both APIs. Therefore no special effort is necessary to allow an application to use both APIs.
Special effort is necessary to use both APIs as part of the implementation of the same feature. From an informal analysis of typical application requirements, we identify four parts of the use of cryptography which can be provided by different APIs:
* Metadata manipulation: parsing and producing encrypted or signed files, finding mutually supported algorithms in a network protocol negotiation, etc.
* Key management: parsing, generating, deriving and formatting cryptographic keys.
* Data manipulation other than keys. In practice, most data formats within the scope of the legacy crypto APIs are trivial (ciphertexts, hashes, MACs, shared secrets). The one exception is ECDSA signatures.
* Cryptographic operations: hash, sign, encrypt, etc.
From this, we deduce the following requirements:
* Convert between PSA and legacy metadata.
* Creating a key with the legacy API and consuming it in the PSA API.
* Creating a key with the PSA API and consuming it in the legacy API.
* Manipulating data formats, other than keys, where the PSA API is lacking.
### Scope limitations
The goal of this document is to bridge the legacy API and the PSA API. The goal is not to provide a PSA way to do everything that is currently possible with the legacy API. The PSA API is less flexible in some regards, and extending it is out of scope in the present study.
With respect to the legacy API, we do not consider functionality of low-level modules for individual algorithms. Our focus is on applications that use high-level legacy crypto modules (md, cipher, pk) and need to combine that with uses of the PSA APIs.
## Gap analysis
The document [“Transitioning to the PSA API”](../../psa-transition.md) enumerates the public header files in Mbed TLS 3.4 and the API elements (especially enums and functions) that they provide, listing PSA equivalents where they exist. There are gaps in two cases:
* Where the PSA equivalents do not provide the same functionality. A typical example is parsing and formatting asymmetric keys.
* To convert between data representations used by legacy APIs and data representations used by PSA APIs.
Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap analysis on two topics: metadata and keys. This chapter explores the gaps in each family of cryptographic mechanisms.
### Generic metadata gaps
#### Need for error code conversion
Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use.
Mbed TLS needs these conversions because it has many functions that expose one API (legacy/API) but are implemented on top of the other API. Most applications would convert legacy and PSA error code to their own error codes, and converting between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` is not particularly helpful for that. Application code might need such conversion functions when implementing an X.509 or TLS callback (returning `MBEDTLS_ERR_xxx`) on top of PSA functions, but this is a very limited use case.
Conclusion: no need for public error code conversion functions.
### Hash gap analysis
Hashes do not involve keys, and involves no nontrivial data format. Therefore the only gap is with metadata, namely specifying a hash algorithm.
Hashes are often used as building blocks for other mechanisms (HMAC, signatures, key derivation, etc.). Therefore metadata about hashes is relevant not only when calculating hashes, but also when performing many other cryptographic operations.
Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls_md_type_t`. Such functions exist in Mbed TLS 3.5 (`mbedtls_md_psa_alg_from_type`, `mbedtls_md_type_from_psa_alg`) but they are declared only in private headers.
### MAC gap analysis
[TODO]
### Cipher and AEAD gap analysis
[TODO]
### Key derivation gap analysis
[TODO]
### Random generation gap analysis
[TODO]
### Asymmetric cryptography gap analysis
#### Asymmetric cryptography metadata
The legacy API only has generic support for two key types: RSA and ECC, via the pk module. ECC keys can also be further classified according to their curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module.
An RSA or ECC key can potentially be used for different algorithms in the scope of the pk module:
* RSA: PKCS#1v1.5 signature, PSS signature, PKCS#1v1.5 encryption, OAEP encryption.
* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement (via `mbedtls_pk_ec`).
ECC keys are also involved in EC-JPAKE, but this happens internally: the EC-JPAKE interface only needs one piece of metadata, namely, to identify a curve.
Since there is no algorithm that can be used with multiple types, and PSA keys have a policy that (for the most part) limits them to one algorithm, there does not seem to be a need to convert between legacy and PSA asymmetric key types on their own. The useful metadata conversions are:
* Selecting an **elliptic curve**.
This means converting between an `mbedtls_ecp_group_id` and a pair of `{psa_ecc_family_t; size_t}`.
This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_from_psa`, which were introduced into the public API between Mbed TLS 3.5 and 3.6 ([#8664](https://github.com/Mbed-TLS/mbedtls/pull/8664)).
* Selecting A **DHM group**.
PSA only supports predefined groups, whereas legacy only supports ad hoc groups. An existing application referring to `MBEDTLS_DHM_RFC7919_FFDHExxx` values would need to refer to `PSA_DH_FAMILY_RFC7919`; an existing application using arbitrary groups cannot migrate to PSA.
* Simultaneously supporting **a key type and an algorithm**.
On the legacy side, this is an `mbedtls_pk_type_t` value and more. For ECDSA, the choice between randomized and deterministic is made at compile time. For RSA, the choice of encryption or signature algorithm is made either by configuring the underlying `mbedtls_rsa_context` or when calling the operation function.
On the PSA side, this is a `psa_key_type_t` value and an algorithm which is normally encoded as policy information in a `psa_key_attributes_t`. The algorithm is also needed in its own right when calling operation functions.
#### Using a legacy key pair or public key with PSA
There are several scenarios where an application has a legacy key pair or public key (`mbedtls_pk_context`) and needs to create a PSA key object (`psa_key_id_t`).
Reasons for first creating a legacy key object, where it's impossible or impractical to directly create a PSA key:
* A very common case where the input is a legacy key object is parsing. PSA does not (yet) have an equivalent of the `mbedtls_pk_parse_xxx` functions.
* The PSA key creation interface is less flexible in some cases. In particular, PSA RSA key generation does not (yet) allow choosing the public exponent.
* The pk object may be created by a part of the application (or a third-party library) that hasn't been migrated to the PSA API yet.
Reasons for needing a PSA key object:
* Using the key with third-party interface that takes a PSA key identifier as input. (Mbed TLS itself has a few TLS functions that take PSA key identifiers, but as of Mbed TLS 3.5, it is always possible to use a legacy key instead.)
* Benefiting from a PSA accelerator, or from PSA's world separation, even without `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority scenario: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.)
Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partially exists in the form of `mbedtls_pk_wrap_as_opaque`, but it is not fully satisfactory, for reasons that are detailed in “[API to create a PSA key from a PK context](#api-to-create-a-psa-key-from-a-pk-context)” below.
#### Using a PSA key as a PK context
There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 and TLS APIs or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents.
There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it has several limitations:
* It creates a PK key of type `MBEDTLS_PK_OPAQUE` that wraps the PSA key. This is good enough in some scenarios, but not others. For example, it's ok for pkwrite, because we've upgraded the pkwrite code to handle `MBEDTLS_PK_OPAQUE`. That doesn't help users of third-party libraries that haven't yet been upgraded.
* It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object.
* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. This is not a priority concern, since we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA. However, this function is useful to use specific PSA keys in X.509/TLS regardless of whether X.509/TLS use the PSA API for all cryptographic operations, so this is a wart in the current API.
It therefore appears that we need two ways to “convert” a PSA key to PK:
* Wrapping, which is what `mbedtls_pk_setup_opaque` does. This works for any PSA key but is limited by the key's lifetime and creates a PK object with limited functionality.
* Copying, which requires a new function. This requires an exportable key but creates a fully independent, fully functional PK object.
Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable.
After some discussion, have not identified anything we want to change in the behavior of `mbedtls_pk_setup_opaque`. We only want to generalize it to non-`MBEDTLS_USE_PSA_CRYPTO` and to document it better.
#### Signature formats
The pk module uses signature formats intended for X.509. The PSA module uses the simplest sensible signature format.
* For RSA, the formats are the same.
* For ECDSA, PSA uses a fixed-size concatenation of (r,s), whereas X.509 and pk use an ASN.1 DER encoding of the sequence (r,s).
Gap: We need APIs to convert between these two formats. The conversion code already exists under the hood, but it's in pieces that can't be called directly.
There is a design choice here: do we provide conversions functions for ECDSA specifically, or do we provide conversion functions that take an algorithm as argument and just happen to be a no-op with RSA? One factor is plausible extensions. These conversions functions will remain useful in Mbed TLS 4.x and perhaps beyond. We will at least add EdDSA support, and its signature encoding is the fixed-size concatenation (r,s) even in X.509. We may well also add support for some post-quantum signatures, and their concrete format is still uncertain.
Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. Therefore we are not going to add a generic function at this stage.
For ECDSA, there are two plausible APIs: follow the ASN.1/X.509 write/parse APIs, or present an ordinary input/output API. The ASN.1 APIs are the way they are to accommodate nested TLV structures. But ECDSA signatures do not appear nested in TLV structures in either TLS (there's just a signature field) or X.509 (the signature is inside a BITSTRING, not directly in a SEQUENCE). So there does not seem to be a need for an ASN.1-like API for the ASN.1 format, just the format conversion itself in a buffer that just contains the signature.
#### Asymmetric cryptography TODO
[TODO] Other gaps?
## New APIs
This section presents new APIs to implement based on the [gap analysis](#gap-analysis).
### General notes
Each action to implement a function entails:
* Implement the library function.
* Document it precisely, including error conditions.
* Unit-test it.
* Mention it where relevant in the PSA transition guide.
### Hash APIs
Based on the [gap analysis](#hash-gap-analysis):
[ACTION] [#8340](https://github.com/Mbed-TLS/mbedtls/issues/8340) Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`.
### MAC APIs
[TODO]
### Cipher and AEAD APIs
[TODO]
### Key derivation APIs
[TODO]
### Random generation APIs
[TODO]
### Asymmetric cryptography APIs
#### Asymmetric cryptography metadata APIs
Based on the [gap analysis](#asymmetric-cryptography-metadata):
* No further work is needed about RSA specifically. The amount of metadata other than hashes is sufficiently small to be handled in ad hoc ways in applications, and hashes have [their own conversions](#hash-apis).
* No further work is needed about ECC specifically. We have just added adequate functions.
* No further work is needed about DHM specifically. There is no good way to translate the relevant information.
* [OPEN] Is there a decent way to convert between `mbedtls_pk_type_t` plus extra information, and `psa_key_type_t` plus policy information? The two APIs are different in crucial ways, with different splits between key type, policy information and operation algorithm.
Thinking so far: there isn't really a nice way to present this conversion. For a specific key, `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_copy_from_psa` do the job.
#### API to create a PSA key from a PK context
Based on the [gap analysis](#using-a-legacy-key-pair-or-public-key-with-psa):
Given an `mbedtls_pk_context`, we want a function that creates a PSA key with the same key material and algorithm. “Same key material” is straightforward, but “same algorithm” is not, because a PK context has incomplete algorithm information. For example, there is no way to distinguish between an RSA key that is intended for signature or for encryption. Between algorithms of the same nature, there is no way to distinguish a key intended for PKCS#1v1.5 and one intended for PKCS#1v2.1 (OAEP/PSS): this is indicated in the underlying RSA context, but the indication there is only a default that can be overridden by calling `mbedtls_pk_{sign,verify}_ext`. Also there is no way to distinguish between `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)` and `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`: in the legacy interface, this is only determined when actually doing a signature/verification operation. Therefore the function that creates the PSA key needs extra information to indicate which algorithm to put in the key's policy.
When creating a PSA key, apart from the key material, the key is determined by attributes, which fall under three categories:
* Type and size. These are directly related to the key material and can be deduced from it if the key material is in a structured format, which is the case with an `mbedtls_pk_context` input.
* Policy. This includes the chosen algorithm, which as discussed above cannot be fully deduced from the `mbedtls_pk_context` object. Just choosing one algorithm is problematic because it doesn't allow implementation-specific extensions, such as Mbed TLS's enrollment algorithm. The intended usage flags cannot be deduced from the PK context either, but the conversion function could sensibly just enable all the relevant usage flags. Users who want a more restrictive usage can call `psa_copy_key` and `psa_destroy_key` to obtain a PSA key object with a more restrictive usage.
* Persistence and location. This is completely orthogonal to the information from the `mbedtls_pk_context` object. It is convenient, but not necessary, for the conversion function to allow customizing these aspects. If it doesn't, users can call the conversion function and then call `psa_copy_key` and `psa_destroy_key` to move the key to its desired location.
To allow the full flexibility around policies, and make the creation of a persistent key more convenient, the conversion function shall take a `const psa_key_attributes_t *` input, like all other functions that create a PSA key. In addition, there shall be a helper function to populate a `psa_key_attributes_t` with a sensible default. This lets the caller choose a more flexible, or just different usage policy, unlike the default-then-copy approach which only allows restricting the policy.
This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not bake in the implementation-specific consideration that a PSA key has exactly two algorithms, and also allows the caller to benefit from default for the policy in more cases.
[ACTION] [#8708](https://github.com/Mbed-TLS/mbedtls/issues/8708) Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`.
```
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_flags_t usage,
psa_key_attributes_t *attributes);
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id);
```
* `mbedtls_pk_get_psa_attributes` does not change the id/lifetime fields of the attributes (which indicate a volatile key by default).
* [OPEN] Or should it reset them to 0? Resetting is more convenient for the case where the pk key is a `MBEDTLS_PK_OPAQUE`. But that's an uncommon use case. It's probably less surprising if this function leaves the lifetime-related alone, since its job is to set the type-related and policy-related attributes.
* `mbedtls_pk_get_psa_attributes` sets the type and size based on what's in the pk context.
* The key type is a key pair if the context contains a private key and the indicated usage is a private-key usage. The key type is a public key if the context only contains a public key, in which case a private-key usage is an error.
* `mbedtls_pk_get_psa_attributes` sets the usage flags based on the `usage` parameter. It extends the usage to other usage that is possible:
* `EXPORT` and `COPY` are always set.
* If `SIGN_{HASH,MESSAGE}` is set then so is `VERIFY_{HASH,MESSAGE}`.
* If `DECRYPT` is set then so is `ENCRYPT`.
* It is an error if `usage` has more than one flag set, or has a usage that is incompatible with the key type.
* `mbedtls_pk_get_psa_attributes` sets the algorithm usage policy based on information in the key object and on `usage`.
* For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_PKCS1V15_CRYPT` for an encrypt/decrypt usage.
* For an RSA key with the `MBEDTLS_RSA_PKCS_V21` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.)
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDSA` with a sign/verify usage, the algorithm policy is `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. In either case, the hash policy is `PSA_ALG_ANY_HASH`.
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDKEY_DH` with the usage `PSA_KEY_USAGE_DERIVE`, the algorithm is `PSA_ALG_ECDH`.
* For a `MBEDTLS_PK_OPAQUE`, this function reads the attributes of the existing PK key and copies them (without overriding the lifetime and key identifier in `attributes`), then applies a public-key restriction if needed.
* Public-key restriction: if `usage` is a public-key usage, change the type to the corresponding public-key type, and remove private-key usage flags from the usage flags read from the existing key.
* `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key).
* The key type can be a public key even if the private key is available.
* `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks.
* `mbedtls_pk_import_into_psa` does not check that the policy in the attributes is sensible. That's on the user.
#### API to copy a PSA key to a PK context
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
[ACTION] [#8709](https://github.com/Mbed-TLS/mbedtls/issues/8709) Implement `mbedtls_pk_copy_from_psa` as described below.
```
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
mbedtls_pk_context *pk);
```
* `pk` must be initialized, but not set up.
* It is an error if the key is neither a key pair nor a public key.
* It is an error if the key is not exportable.
* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse).
* Once this function returns, the pk object is completely independent of the PSA key.
* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`) if that is a matching operation type (sign/verify, encrypt/decrypt), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`).
* For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today.
* For an RSA key, the output key will allow both encrypt/decrypt and sign/verify regardless of the original key's policy. The original key's policy determines the output key's padding mode.
* The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. Convey this in the documentation.
#### API to create a PK object that wraps a PSA key
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
[ACTION] [#8712](https://github.com/Mbed-TLS/mbedtls/issues/8712) Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`.
[ACTION] [#8710](https://github.com/Mbed-TLS/mbedtls/issues/8710) Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly.
[OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`?
#### API to convert between signature formats
Based on the [gap analysis](#signature-formats):
[ACTION] [#7765](https://github.com/Mbed-TLS/mbedtls/issues/7765) Implement `mbedtls_ecdsa_raw_to_der` and `mbedtls_ecdsa_der_to_raw` as described below.
```
int mbedtls_ecdsa_raw_to_der(size_t bits,
const unsigned char *raw, size_t raw_len,
unsigned char *der, size_t der_size, size_t *der_len);
int mbedtls_ecdsa_der_to_raw(size_t bits,
const unsigned char *der, size_t der_len,
unsigned char *raw, size_t raw_size, size_t *raw_len);
```
* These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`.
* The input and output buffers can overlap.
* The `bits` parameter is necessary in the DER-to-raw direction because the DER format lacks leading zeros, so something else needs to convey the size of (r,s). The `bits` parameter is redundant in the raw-to-DER direction, but we have it anyway because [it helps catch errors](https://github.com/Mbed-TLS/mbedtls/pull/8681#discussion_r1445980971), and it isn't a burden on the caller because the information is readily available in practice.
* Should these functions rely on the ASN.1 module? We experimented [calling ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8681), [reimplementing simpler ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8696), and [providing the functions from the ASN.1 module](https://github.com/Mbed-TLS/mbedtls/pull/8703). Providing the functions from the ASN.1 module [won on a compromise of code size and simplicity](https://github.com/Mbed-TLS/mbedtls/issues/7765#issuecomment-1893670015).
@@ -11,11 +11,15 @@ is, of course, to actually do the migration work.
Limitations relevant for G1 (performing crypto operations)
==========================================================
Restartable ECC operations
--------------------------
Restartable (aka interruptible) ECC operations
----------------------------------------------
There is currently no support for that in PSA at all, but it will be added at
some point, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18816849>.
Support for interruptible ECDSA sign/verify was added to PSA in Mbed TLS 3.4.
However, support for interruptible ECDH is not present yet. Also, PK, X.509 and
TLS have not yet been adapted to take advantage of the new PSA APIs. See:
- <https://github.com/Mbed-TLS/mbedtls/issues/7292>;
- <https://github.com/Mbed-TLS/mbedtls/issues/7293>;
- <https://github.com/Mbed-TLS/mbedtls/issues/7294>.
Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
both enabled, some operations that should be restartable are not (ECDH in TLS
@@ -78,6 +82,10 @@ the one that requires the most work, but it would deliver value beyond PSA
migration by implementing RFC 7919. (Implementing RFC 7919 could be done any
time; making it mandatory can only be done in 4.0 or another major version.)
As of early 2023, the plan is to go with option 2 in Mbed TLS 4.0, which has
been announced on the mailing-list and got no push-back, see
<https://github.com/Mbed-TLS/mbedtls/issues/5278>.
RSA-PSS parameters
------------------
@@ -321,6 +329,8 @@ probably not acceptable.
in the meantime. Such an extension seems inconvenient and not motivated by
strong security arguments, so it's unclear whether it would be accepted.
Since Mbed TLS 3.4, option 1 is implemented.
Limitations relevant for G2 (isolation of long-term secrets)
============================================================
+54 -85
View File
@@ -18,13 +18,17 @@ needs to be changed to use new APIs. For a more detailed account of what's
implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and
internal changes implement (G1).
As of early 2023, work towards G5 is in progress: Mbed TLS 3.3 and 3.4 saw
some improvements in this area, and more will be coming in future releases.
Generally speaking, the numbering above doesn't mean that each goal requires
the preceding ones to be completed.
Compile-time options
====================
We currently have two compile-time options that are relevant to the migration:
We currently have a few compile-time options that are relevant to the migration:
- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
Crypto APIs.
@@ -36,7 +40,9 @@ We currently have two compile-time options that are relevant to the migration:
The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
are:
- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`;
- it's not fully compatible with `MBEDTLS_ECP_RESTARTABLE`: you can enable
both, but then you won't get the full effect of RESTARTBLE (see the
documentation of this option in `mbedtls_config.h`);
- to avoid a hard/default dependency of TLS, X.509 and PK on
`MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
- When `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
@@ -71,10 +77,10 @@ Crypto does not support restartable operations, there's a clear conflict: the
TLS and X.509 layers can't both use only PSA APIs and get restartable
behaviour.
Supporting this in PSA is on our roadmap and currently planned for end of
2022, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18883250>.
Support for restartable (aka interruptible) ECDSA sign/verify operation was
added to PSA in Mbed TLS 3.4, but support for ECDH is not present yet.
It will then require follow-up work to make use of the new PSA API in
It will then require follow-up work to make use of the new PSA APIs in
PK/X.509/TLS in all places where we currently allow restartable operations.
### Backward compatibility issues with making `MBEDTLS_USE_PSA_CRYPTO` always on
@@ -137,8 +143,11 @@ crypto API.
- Downside: tricky to implement if the PSA implementation is currently done on
top of that layer (dependency loop).
This strategy is currently (early 2022) used for all operations in the PK
layer.
This strategy is currently (early 2023) used for all operations in the PK
layer; the MD layer uses a variant where it dispatches to PSA if a driver is
available and the driver subsystem has been initialized, regardless of whether
`USE_PSA_CRYPTO` is enabled; see `md-cipher-dispatch.md` in the same directory
for details.
This strategy is not very well suited to the Cipher layer, as the PSA
implementation is currently done on top of that layer.
@@ -161,8 +170,9 @@ Replace calls for each operation
code size.
- Downside: TLS/X.509 code has to be done for each operation.
This strategy is currently (early 2022) used for the MD layer and the Cipher
layer.
This strategy is currently (early 2023) used for the MD layer and the Cipher
layer in X.509 and TLS. Crypto modules however always call to MD which may
then dispatch to PSA, see `md-cipher-dispatch.md`.
Opt-in use of PSA from the abstraction layer
--------------------------------------------
@@ -210,7 +220,10 @@ Strategies currently (early 2022) used with each abstraction layer:
- PK (for G1): silently call PSA
- PK (for G2): opt-in use of PSA (new key type)
- Cipher (G1): replace calls at each call site
- MD (G1): replace calls at each call site
- MD (G1, X.509 and TLS): replace calls at each call site (depending on
`USE_PSA_CRYPTO`)
- MD (G5): silently call PSA when a driver is available, see
`md-cipher-dispatch.md`.
Supporting builds with drivers without the software implementation
@@ -219,10 +232,6 @@ Supporting builds with drivers without the software implementation
This section presents a plan towards G5: save code size by compiling out our
software implementation when a driver is available.
Additionally, we want to save code size by compiling out the
abstractions layers that we are not using when `MBEDTLS_USE_PSA_CRYPTO` is
enabled (see previous section): MD and Cipher.
Let's expand a bit on the definition of the goal: in such a configuration
(driver used, software implementation and abstraction layer compiled out),
we want:
@@ -238,9 +247,10 @@ at feature parity with software-based builds.
We can roughly divide the work needed to get there in the following steps:
0. Have a working driver interface for the algorithms we want to replace.
1. Have users of these algorithms call to PSA, not the legacy API, for all
operations. (This is G1, and for PK, X.509 and TLS this is controlled by
`MBEDTLS_USE_PSA_CRYPTO`.) This needs to be done in the library and tests.
1. Have users of these algorithms call to PSA or an abstraction layer than can
dispatch to PSA, but not the low-level legacy API, for all operations.
(This is G1, and for PK, X.509 and TLS this is controlled by
`MBEDTLS_USE_PSA_CRYPTO`.) This needs to be done in the library and tests.
2. Have users of these algorithms not depend on the legacy API for information
management (getting a size for a given algorithm, etc.)
3. Adapt compile-time guards used to query availability of a given algorithm;
@@ -262,50 +272,32 @@ not possible to achieve good test coverage at the end of step 1 or step 2, it
is preferable to group with the next step(s) in the same PR until good test
coverage can be reached.
**Status as of Mbed TLS 3.2:**
**Status as of end of March 2023 (shortly after 3.4):**
- Step 0 is achieved for most algorithms, with only a few gaps remaining.
- Step 1 is achieved for most of PK, X.509, and TLS when
`MBEDTLS_USE_PSA_CRYPTO` is enabled with only a few gaps remaining (see
docs/use-psa-crypto.md).
- Step 1 is not achieved for a lot of the crypto library including the PSA
core. For example, `entropy.c` calls the legacy API
`mbedtls_sha256` (or `mbedtls_sha512` optionally); `hmac_drbg.c` calls the
legacy API `mbedtls_md` and `ctr_drbg.c` calls the legacy API `mbedtls_aes`;
the PSA core depends on the entropy module and at least one of the DRBG
modules (unless `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is used). Further, several
crypto modules have similar issues, for example RSA PKCS#1 v2.1 calls
`mbedtls_md` directly.
- Step 1 is achieved for the crypto library regarding hashes: everything uses
MD (not low-level hash APIs), which then dispatches to PSA if applicable.
- Step 1 is not achieved for all of the crypto library when it come to
ciphers. For example,`ctr_drbg.c` calls the legacy API `mbedtls_aes`.
- Step 2 is achieved for most of X.509 and TLS (same gaps as step 1) when
`MBEDTLS_USE_PSA_CRYPTO` is enabled - this was tasks like #5795, #5796,
#5797. It is being done in PK and RSA PKCS#1 v1.5 by PR #6065.
- Step 3 was mostly not started at all before 3.2; it is being done for PK by
PR #6065.
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
- Step 3 is done for hashes and top-level ECC modules (ECDSA, ECDH, ECJPAKE).
**Strategy for step 1:**
Regarding PK, X.509, and TLS, this is mostly achieved with only a few gaps.
(The strategy was outlined in the previous section.)
Regarding libmbedcrypto, outside of the RNG subsystem, for modules that
currently depend on other legacy crypto modules, this can be achieved without
backwards compatibility issues, by using the software implementation if
available, and "falling back" to PSA only if it's not. The compile-time
dependency changes from the current one (say, `MD_C` or `AES_C`) to "the
previous dependency OR PSA Crypto with needed algorithms". When building
without software implementation, users need to call `psa_crypto_init()` before
calling any function from these modules. This condition does not constitute a
break of backwards compatibility, as it was previously impossible to build in
those configurations, and in configurations were the build was possible,
application code keeps working unchanged. An work-in-progress example of
applying this strategy, for RSA PKCS#1 v2.1, is here:
<https://github.com/Mbed-TLS/mbedtls/pull/6141>
There is a problem with the modules used for the PSA RNG, as currently the RNG
is initialized before drivers and the key store. This part will need further
study, but in the meantime we can proceed with everything that's not the
entropy module of one of the DRBG modules, and that does not depend on one of
those modules.
Regarding libmbedcrypto:
- for hashes and ciphers, see `md-cipher-dispatch.md` in the same directory;
- for ECC, we have no internal uses of the top-level algorithms (ECDSA, ECDH,
ECJPAKE), however they all depend on `ECP_C` which in turn depends on
`BIGNUM_C`. So, direct calls from TLS, X.509 and PK to ECP and Bignum will
need to be replaced; see <https://github.com/Mbed-TLS/mbedtls/issues/6839> and
linked issues for a summary of intermediate steps and open points.
**Strategy for step 2:**
@@ -315,14 +307,11 @@ convenient, for example in parts of the code that accept old-style identifiers
(such as `mbedtls_md_type_t`) in their API and can't assume PSA to be
compiled in (such as `rsa.c`).
It is suggested that, as a temporary solution until we clean this up
later when removing the legacy API including its identifiers (G4), we may
occasionally use ad-hoc internal functions, such as the ones introduced by PR
6065 in `library/hash_info.[ch]`.
An alternative would be to have two different code paths depending on whether
`MBEDTLS_PSA_CRYPTO_C` is defined or not. However this is not great for
readability or testability.
When using an existing abstraction layer such as MD, it can provide
information management functions. In other cases, information that was in a
low-level module but logically belongs in a higher-level module can be moved
to that module (for example, TLS identifiers of curves and there conversion
to/from PSA or legacy identifiers belongs in TLS, not `ecp.c`).
**Strategy for step 3:**
@@ -338,35 +327,15 @@ dependencies above depending on whether `MBEDTLS_USE_PSA_CRYPTO` is defined:
if it is, the code want the algorithm available in PSA, otherwise, it wants it
available via the legacy API(s) is it using (MD and/or low-level).
The strategy for steps 1 and 2 above will introduce new situations: code that
currently compute hashes using MD (resp. a low-level hash module) will gain
the ability to "fall back" to using PSA if the legacy dependency isn't
available. Data related to a certain hash (OID, sizes, translations) should
only be included in the build if it is possible to use that hash in some way.
As much as possible, we're trying to create for each algorithm a single new
macro that can be used to express dependencies everywhere (except pure PSA
code that should always use `PSA_WANT`). For example, for hashes this is the
`MBEDTLS_MD_CAN_xxx` family. For ECC algorithms, we have similar
`MBEDTLS_PK_CAN_xxx` macros.
In order to cater to these new needs, new families of macros are introduced in
`legacy_or_psa.h`, see its documentation for details.
It should be noted that there are currently:
- too many different ways of computing a hash (low-level, MD, PSA);
- too many different ways to configure the library that influence which of
these ways is available and will be used (`MBEDTLS_USE_PSA_CRYPTO`,
`MBEDTLS_PSA_CRYPTO_CONFIG`, `mbedtls_config.h` + `psa/crypto_config.h`).
As a result, we need more families of dependency macros than we'd like to.
This is a temporary situation until we move to a place where everything is
based on PSA Crypto. In the meantime, long and explicit names where chosen for
the new macros in the hope of avoiding confusion.
Note: the new macros supplement but do not replace the existing macros:
- code that always uses PSA Crypto (for example, code specific to TLS 1.3)
should use `PSA_WANT_xxx`;
- code that always uses the legacy API (for example, crypto modules that have
not undergone step 1 yet) should use `MBEDTLS_xxx_C`;
- code that may use one of the two APIs, either based on
`MBEDTLS_USE_PSA_CRYPTO` (X.509, TLS 1.2, shared between TLS 1.2 and 1.3),
or based on availability (crypto modules after step 1), should use one of
the new macros from `legacy_or_psa.h`.
Note that in order to achieve that goal, even for code that obeys
`USE_PSA_CRYPTO`, it is useful to impose that all algorithms that are
available via the legacy APIs are also available via PSA.
Executing step 3 will mostly consist of using the right dependency macros in
the right places (once the previous steps are done).
+34 -19
View File
@@ -1,29 +1,24 @@
#!/bin/sh
#
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
#
# Purpose
#
# Show symbols in the X.509 and TLS libraries that are defined in another
# libmbedtlsXXX.a library. This is usually done to list Crypto dependencies.
# Show external links in built libraries (X509 or TLS) or modules. This is
# usually done to list Crypto dependencies or to check modules'
# interdependencies.
#
# Usage:
# - build the library with debug symbols and the config you're interested in
# (default, full minus MBEDTLS_USE_PSA_CRYPTO, full, etc.)
# - run this script with the name of your config as the only argument
# - launch this script with 1 or more arguments depending on the analysis' goal:
# - if only 1 argument is used (which is the name of the used config,
# ex: full), then the analysis is done on libmbedx509 and libmbedtls
# libraries by default
# - if multiple arguments are provided, then modules' names (ex: pk,
# pkparse, pkwrite, etc) are expected after the 1st one and the analysis
# will be done on those modules instead of the libraries.
set -eu
@@ -35,10 +30,21 @@ syms() {
nm "$FILE" | sed -n "s/[0-9a-f ]*${TYPE} \(mbedtls_.*\)/\1/p" | sort -u
}
# Check if the provided name refers to a module or library and return the
# same path with proper extension
get_file_with_extension() {
BASE=$1
if [ -f $BASE.o ]; then
echo $BASE.o
elif [ -f $BASE.a ]; then
echo $BASE.a
fi
}
# create listings for the given library
list() {
NAME="$1"
FILE="library/libmbed${NAME}.a"
FILE=$(get_file_with_extension "library/${NAME}")
PREF="${CONFIG}-$NAME"
syms '[TRrD]' $FILE > ${PREF}-defined
@@ -54,5 +60,14 @@ list() {
CONFIG="${1:-unknown}"
list x509
list tls
# List of modules to check is provided as parameters
if [ $# -gt 1 ]; then
shift 1
ITEMS_TO_CHECK="$@"
else
ITEMS_TO_CHECK="libmbedx509 libmbedtls"
fi
for ITEM in $ITEMS_TO_CHECK; do
list $ITEM
done
+685
View File
@@ -0,0 +1,685 @@
PSA API functions and shared memory
===================================
## Introduction
This document discusses the security architecture of systems where PSA API functions might receive arguments that are in memory that is shared with an untrusted process. On such systems, the untrusted process might access a shared memory buffer while the cryptography library is using it, and thus cause unexpected behavior in the cryptography code.
### Core assumptions
We assume the following scope limitations:
* Only PSA Crypto API functions are in scope (including Mbed TLS extensions to the official API specification). Legacy crypto, X.509, TLS, or any other function which is not called `psa_xxx` is out of scope.
* We only consider [input buffers](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#input-buffer-sizes) and [output buffers](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#output-buffer-sizes). Any other data is assumed to be in non-shared memory.
## System architecture discussion
### Architecture overview
We consider a system that has memory separation between partitions: a partition can't access another partition's memory directly. Partitions are meant to be isolated from each other: a partition may only affect the integrity of another partition via well-defined system interfaces. For example, this can be a Unix/POSIX-like system that isolates processes, or isolation between the secure world and the non-secure world relying on a mechanism such as TrustZone, or isolation between secure-world applications on such a system.
More precisely, we consider such a system where our PSA Crypto implementation is running inside one partition, called the **crypto service**. The crypto service receives remote procedure calls (RPC) from other partitions, validates their arguments (e.g. validation of key identifier ownership), and calls a PSA Crypto API function. This document is concerned with environments where the arguments passed to a PSA Crypto API function may be in shared memory (as opposed to environments where the inputs are always copied into memory that is solely accessible by the crypto service before calling the API function, and likewise with output buffers after the function returns).
When the data is accessible to another partition, there is a risk that this other partition will access it while the crypto implementation is working. Although this could be prevented by suspending the whole system while crypto is working, such a limitation is rarely desirable and most systems don't offer a way to do it. (Even systems that have absolute thread priorities, and where crypto has a higher priority than any untrusted partition, may be vulnerable due to having multiple cores or asynchronous data transfers with peripherals.)
The crypto service must guarantee that it behaves as if the rest of the world was suspended while it is executed. A behavior that is only possible if an untrusted entity accesses a buffer while the crypto service is processing the data is a security violation.
### Risks and vulnerabilities
We consider a security architecture with two or three entities:
* a crypto service, which offers PSA crypto API calls over RPC (remote procedure call) using shared memory for some input or output arguments;
* a client of the crypto service, which makes a RPC to the crypto service;
* in some scenarios, a client of the client, which makes a RPC to the crypto client which re-shares the memory with the crypto service.
The behavior of RPC is defined for in terms of values of inputs and outputs. This models an ideal world where the content of input and output buffers is not accessible outside the crypto service while it is processing an RPC. It is a security violation if the crypto service behaves in a way that cannot be achieved by setting the inputs before the RPC call, and reading the outputs after the RPC call is finished.
#### Read-read inconsistency
If an input argument is in shared memory, there is a risk of a **read-read inconsistency**:
1. The crypto code reads part of the input and validates it, or injects it into a calculation.
2. The client (or client's client) modifies the input.
3. The crypto code reads the same part again, and performs an action which would be impossible if the input had had the same value all along.
Vulnerability example (parsing): suppose the input contains data with a type-length-value or length-value encoding (for example, importing an RSA key). The crypto code reads the length field and checks that it fits within the buffer. (This could be the length of the overall data, or the length of an embedded field) Later, the crypto code reads the length again and uses it without validation. A malicious client can modify the length field in the shared memory between the two reads and thus cause a buffer overread on the second read.
Vulnerability example (dual processing): consider an RPC to perform authenticated encryption, using a mechanism with an encrypt-and-MAC structure. The authenticated encryption implementation separately calculates the ciphertext and the MAC from the plaintext. A client sets the plaintext input to `"PPPP"`, then starts the RPC call, then changes the input buffer to `"QQQQ"` while the crypto service is working.
* Any of `enc("PPPP")+mac("PPPP")`, `enc("PPQQ")+mac("PPQQ")` or `enc("QQQQ")+mac("QQQQ")` are valid outputs: they are outputs that can be produced by this authenticated encryption RPC.
* If the authenticated encryption calculates the ciphertext before the client changes the output buffer and calculates the MAC after that change, reading the input buffer again each time, the output will be `enc("PPPP")+mac("QQQQ")`. There is no input that can lead to this output, hence this behavior violates the security guarantees of the crypto service.
#### Write-read inconsistency
If an output argument is in shared memory, there is a risk of a **write-read inconsistency**:
1. The crypto code writes some intermediate data into the output buffer.
2. The client (or client's client) modifies the intermediate data.
3. The crypto code reads the intermediate data back and continues the calculation, leading to an outcome that would not be possible if the intermediate data had not been modified.
Vulnerability example: suppose that an RSA signature function works by formatting the data in place in the output buffer, then applying the RSA private-key operation in place. (This is how `mbedtls_rsa_pkcs1_sign` works.) A malicious client may write badly formatted data into the buffer, so that the private-key operation is not a valid signature (e.g. it could be a decryption), violating the RSA key's usage policy.
Vulnerability example with chained calls: we consider the same RSA signature operation as before. In this example, we additionally assume that the data to sign comes from an attestation application which signs some data on behalf of a final client: the key and the data to sign are under the attestation application's control, and the final client must not be able to obtain arbitrary signatures. The final client shares an output buffer for the signature with the attestation application, and the attestation application re-shares this buffer with the crypto service. A malicious final client can modify the intermediate data and thus sign arbitrary data.
#### Write-write disclosure
If an output argument is in shared memory, there is a risk of a **write-write disclosure**:
1. The crypto code writes some intermediate data into the output buffer. This intermediate data must remain confidential.
2. The client (or client's client) reads the intermediate data.
3. The crypto code overwrites the intermediate data.
Vulnerability example with chained calls (temporary exposure): an application encrypts some data, and lets its clients store the ciphertext. Clients may not have access to the plaintext. To save memory, when it calls the crypto service, it passes an output buffer that is in the final client's memory. Suppose the encryption mechanism works by copying its input to the output buffer then encrypting in place (for example, to simplify considerations related to overlap, or because the implementation relies on a low-level API that works in place). In this scenario, the plaintext is exposed to the final client while the encryption in progress, which violates the confidentiality of the plaintext.
Vulnerability example with chained calls (backtrack): we consider a provisioning application that provides a data encryption service on behalf of multiple clients, using a single shared key. Clients are not allowed to access each other's data. The provisioning application isolates clients by including the client identity in the associated data. Suppose that an AEAD decryption function processes the ciphertext incrementally by simultaneously writing the plaintext to the output buffer and calculating the tag. (This is how AEAD decryption usually works.) At the end, if the tag is wrong, the decryption function wipes the output buffer. Assume that the output buffer for the plaintext is shared from the client to the provisioning application, which re-shares it with the crypto service. A malicious client can read another client (the victim)'s encrypted data by passing the ciphertext to the provisioning application, which will attempt to decrypt it with associated data identifying the requesting client. Although the operation will fail beacuse the tag is wrong, the malicious client still reads the victim plaintext.
#### Write-read feedback
If a function both has an input argument and an output argument in shared memory, and processes its input incrementally to emit output incrementally, the following sequence of events is possible:
1. The crypto code processes part of the input and writes the corresponding part of the output.
2. The client reads the early output and uses that to calculate the next part of the input.
3. The crypto code processes the rest of the input.
There are cryptographic mechanisms for which this breaks security properties. An example is [CBC encryption](https://link.springer.com/content/pdf/10.1007/3-540-45708-9_2.pdf): if the client can choose the content of a plaintext block after seeing the immediately preceding ciphertext block, this gives the client a decryption oracle. This is a security violation if the key policy only allowed the client to encrypt, not to decrypt.
TODO: is this a risk we want to take into account? Although this extends the possible behaviors of the one-shot interface, the client can do the same thing legitimately with the multipart interface.
### Possible countermeasures
In this section, we briefly discuss generic countermeasures.
#### Copying
Copying is a valid countermeasure. It is conceptually simple. However, it is often unattractive because it requires additional memory and time.
Note that although copying is very easy to write into a program, there is a risk that a compiler (especially with whole-program optimization) may optimize the copy away, if it does not understand that copies between shared memory and non-shared memory are semantically meaningful.
Example: the PSA Firmware Framework 1.0 forbids shared memory between partitions. This restriction is lifted in version 1.1 due to concerns over RAM usage.
#### Careful accesses
The following rules guarantee that shared memory cannot result in a security violation other than [write-read feedback](#write-read-feedback):
* Never read the same input twice at the same index.
* Never read back from an output.
* Never write to the output twice at the same index.
* This rule can usefully be relaxed in many circumstances. It is ok to write data that is independent of the inputs (and not otherwise confidential), then overwrite it. For example, it is ok to zero the output buffer before starting to process the input.
These rules are very difficult to enforce.
Example: these are the rules that a GlobalPlatform TEE Trusted Application (application running on the secure side of TrustZone on Cortex-A) must follow.
## Protection requirements
### Responsibility for protection
A call to a crypto service to perform a crypto operation involves the following components:
1. The remote procedure call framework provided by the operating system.
2. The code of the crypto service.
3. The code of the PSA Crypto dispatch layer (also known as the core), which is provided by Mbed TLS.
4. The driver implementing the cryptographic mechanism, which may be provided by Mbed TLS (built-in driver) or by a third-party driver.
The [PSA Crypto API specification](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#stability-of-parameters) puts the responsibility for protection on the implementation of the PSA Crypto API, i.e. (3) or (4).
> In an environment with multiple threads or with shared memory, the implementation carefully accesses non-overlapping buffer parameters in order to prevent any security risk resulting from the content of the buffer being modified or observed during the execution of the function. (...)
In Mbed TLS 2.x and 3.x up to and including 3.5.0, there is no defense against buffers in shared memory. The responsibility shifts to (1) or (2), but this is not documented.
In the remainder of this chapter, we will discuss how to implement this high-level requirement where it belongs: inside the implementation of the PSA Crypto API. Note that this allows two possible levels: in the dispatch layer (independently of the implementation of each mechanism) or in the driver (specific to each implementation).
#### Protection in the dispatch layer
The dispatch layer has no control over how the driver layer will access buffers. Therefore the only possible protection at this layer method is to ensure that drivers have no access to shared memory. This means that any buffer located in shared memory must be copied into or out of a buffer in memory owned by the crypto service (heap or stack). This adds inefficiency, mostly in terms of RAM usage.
For buffers with a small static size limit, this is something we often do for convenience, especially with output buffers. However, as of Mbed TLS 3.5.0, it is not done systematically.
It is ok to skip the copy if it is known for sure that a buffer is not in shared memory. However, the location of the buffer is not under the control of Mbed TLS. This means skipping the copy would have to be a compile-time or run-time option which has to be set by the application using Mbed TLS. This is both an additional maintenance cost (more code to analyze, more testing burden), and a residual security risk in case the party who is responsible for setting this option does not set it correctly. As a consequence, Mbed TLS will not offer this configurability unless there is a compelling argument.
#### Protection in the driver layer
Putting the responsibility for protection in the driver layer increases the overall amount of work since there are more driver implementations than dispatch implementations. (This is true even inside Mbed TLS: almost all API functions have multiple underlying implementations, one for each algorithm.) It also increases the risk to the ecosystem since some drivers might not protect correctly. Therefore having drivers be responsible for protection is only a good choice if there is a definite benefit to it, compared to allocating an internal buffer and copying. An expected benefit in some cases is that there are practical protection methods other than copying.
Some cryptographic mechanisms are naturally implemented by processing the input in a single pass, with a low risk of ever reading the same byte twice, and by writing the final output directly into the output buffer. For such mechanism, it is sensible to mandate that drivers respect these rules.
In the next section, we will analyze how susceptible various cryptographic mechanisms are to shared memory vulnerabilities.
### Susceptibility of different mechanisms
#### Operations involving small buffers
For operations involving **small buffers**, the cost of copying is low. For many of those, the risk of not copying is high:
* Any parsing of formatted data has a high risk of [read-read inconsistency](#read-read-inconsistency).
* An internal review shows that for RSA operations, it is natural for an implementation to have a [write-read inconsistency](#write-read-inconsistency) or a [write-write disclosure](#write-write-disclosure).
Note that in this context, a “small buffer” is one with a size limit that is known at compile time, and small enough that copying the data is not prohibitive. For example, an RSA key fits in a small buffer. A hash input is not a small buffer, even if it happens to be only a few bytes long in one particular call.
The following buffers are considered small buffers:
* Any input or output directly related to asymmetric cryptography (signature, encryption/decryption, key exchange, PAKE), including key import and export.
* Note that this does not include inputs or outputs that are not processed by an asymmetric primitives, for example the message input to `psa_sign_message` or `psa_verify_message`.
* Cooked key derivation output.
* The output of a hash or MAC operation.
**Design decision: the dispatch layer shall copy all small buffers**.
#### Symmetric cryptography inputs with small output
Message inputs to hash, MAC and key derivation operations are at a low risk of [read-read inconsistency](#read-read-inconsistency) because they are unformatted data, and for all specified algorithms, it is natural to process the input one byte at a time.
**Design decision: require symmetric cryptography drivers to read their input without a risk of read-read inconsistency**.
TODO: what about IV/nonce inputs? They are typically small, but don't necessarily have a static size limit (e.g. GCM recommends a 12-byte nonce, but also allows large nonces).
#### Key derivation outputs
Key derivation typically emits its output as a stream, with no error condition detected after setup other than operational failures (e.g. communication failure with an accelerator) or running out of data to emit (which can easily be checked before emitting any data, since the data size is known in advance).
(Note that this is about raw byte output, not about cooked key derivation, i.e. deriving a structured key, which is considered a [small buffer](#operations-involving-small-buffers).)
**Design decision: require key derivation drivers to emit their output without reading back from the output buffer**.
#### Cipher and AEAD
AEAD decryption is at risk of [write-write disclosure](#write-write-disclosure) when the tag does not match.
AEAD encryption and decryption are at risk of [read-read inconsistency](#read-read-inconsistency) if they process the input multiple times, which is natural in a number of cases:
* when encrypting with an encrypt-and-authenticate or authenticate-then-encrypt structure (one read to calculate the authentication tag and another read to encrypt);
* when decrypting with an encrypt-then-authenticate structure (one read to decrypt and one read to calculate the authentication tag);
* with SIV modes (not yet present in the PSA API, but likely to come one day) (one full pass to calculate the IV, then another full pass for the core authenticated encryption);
Cipher and AEAD outputs are at risk of [write-read inconsistency](#write-read-inconsistency) and [write-write disclosure](#write-write-disclosure) if they are implemented by copying the input into the output buffer with `memmove`, then processing the data in place. In particular, this approach makes it easy to fully support overlapping, since `memmove` will take care of overlapping cases correctly, which is otherwise hard to do portably (C99 does not offer an efficient, portable way to check whether two buffers overlap).
**Design decision: the dispatch layer shall allocate an intermediate buffer for cipher and AEAD plaintext/ciphertext inputs and outputs**.
Note that this can be a single buffer for the input and the output if the driver supports in-place operation (which it is supposed to, since it is supposed to support arbitrary overlap, although this is not always the case in Mbed TLS, a [known issue](https://github.com/Mbed-TLS/mbedtls/issues/3266)). A side benefit of doing this intermediate copy is that overlap will be supported.
For all currently implemented AEAD modes, the associated data is only processed once to calculate an intermediate value of the authentication tag.
**Design decision: for now, require AEAD drivers to read the additional data without a risk of read-read inconsistency**. Make a note to revisit this when we start supporting an SIV mode, at which point the dispatch layer shall copy the input for modes that are not known to be low-risk.
#### Message signature
For signature algorithms with a hash-and-sign framework, the input to sign/verify-message is passed to a hash, and thus can follow the same rules as [symmetric cryptography inputs with small output](#symmetric-cryptography-inputs-with-small-output). This is also true for `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`, which is the only non-hash-and-sign signature mechanism implemented in Mbed TLS 3.5. This is not true for PureEdDSA (`#PSA_ALG_PURE_EDDSA`), which is not yet implemented: [PureEdDSA signature](https://www.rfc-editor.org/rfc/rfc8032#section-5.1.6) processes the message twice. (However, PureEdDSA verification only processes the message once.)
**Design decision: for now, require sign/verify-message drivers to read their input without a risk of read-read inconsistency**. Make a note to revisit this when we start supporting PureEdDSA, at which point the dispatch layer shall copy the input for algorithms such as PureEdDSA that are not known to be low-risk.
## Design of shared memory protection
This section explains how Mbed TLS implements the shared memory protection strategy summarized below.
### Shared memory protection strategy
* The core (dispatch layer) shall make a copy of the following buffers, so that drivers do not receive arguments that are in shared memory:
* Any input or output from asymmetric cryptography (signature, encryption/decryption, key exchange, PAKE), including key import and export.
* Plaintext/ciphertext inputs and outputs for cipher and AEAD.
* The output of a hash or MAC operation.
* Cooked key derivation output.
* A document shall explain the requirements on drivers for arguments whose access needs to be protected:
* Hash and MAC input.
* Cipher/AEAD IV/nonce (to be confirmed).
* AEAD associated data (to be confirmed).
* Key derivation input (excluding key agreement).
* Raw key derivation output (excluding cooked key derivation output).
* The built-in implementations of cryptographic mechanisms with arguments whose access needs to be protected shall protect those arguments.
Justification: see “[Susceptibility of different mechanisms](#susceptibility-of-different-mechanisms)”.
### Implementation of copying
Copy what needs copying. This is broadly straightforward, however there are a few things to consider.
#### Compiler optimization of copies
It is unclear whether the compiler will attempt to optimize away copying operations.
Once the copying code is implemented, it should be evaluated to see whether compiler optimization is a problem. Specifically, for the major compilers supported by Mbed TLS:
* Write a small program that uses a PSA function which copies inputs or outputs.
* Build the program with link-time optimization / full-program optimization enabled (e.g. `-flto` with `gcc`). Try also enabling the most extreme optimization options such as `-Ofast` (`gcc`) and `-Oz` (`clang`).
* Inspect the generated code with `objdump` or a similar tool to see if copying operations are preserved.
If copying behaviour is preserved by all major compilers then assume that compiler optimization is not a problem.
If copying behaviour is optimized away by the compiler, further investigation is needed. Experiment with using the `volatile` keyword to force the compiler not to optimize accesses to the copied buffers. If the `volatile` keyword is not sufficient, we may be able to use compiler or target-specific techniques to prevent optimization, for example memory barriers or empty `asm` blocks. These may be implemented and verified for important platforms while retaining a C implementation that is likely to be correct on most platforms as a fallback - the same approach taken by the constant-time module.
**Open questions: Will the compiler optimize away copies? If so, can it be prevented from doing so in a portable way?**
#### Copying code
We may either copy buffers on an ad-hoc basis using `memcpy()` in each PSA function, or use a unified set of functions for copying input and output data. The advantages of the latter are obvious:
* Any test hooks need only be added in one place.
* Copying code must only be reviewed for correctness in one place, rather than in all functions where it occurs.
* Copy bypass is simpler as we can just replace these functions with no-ops in a single place.
* Any complexity needed to prevent the compiler optimizing copies away does not have to be duplicated.
On the other hand, the only advantage of ad-hoc copying is slightly greater flexibility.
**Design decision: Create a unified set of functions for copying input and output data.**
#### Copying in multipart APIs
Multipart APIs may follow one of 2 possible approaches for copying of input:
##### 1. Allocate a buffer and copy input on each call to `update()`
This is simple and mirrors the approach for one-shot APIs nicely. However, allocating memory in the middle of a multi-part operation is likely to be bad for performance. Multipart APIs are designed in part for systems that do not have time to perform an operation at once, so introducing poor performance may be a problem here.
**Open question: Does memory allocation in `update()` cause a performance problem? If so, to what extent?**
##### 2. Allocate a buffer at the start of the operation and subdivide calls to `update()`
In this approach, input and output buffers are allocated at the start of the operation that are large enough to hold the expected average call to `update()`. When `update()` is called with larger buffers than these, the PSA API layer makes multiple calls to the driver, chopping the input into chunks of the temporary buffer size and filling the output from the results until the operation is finished.
This would be more complicated than approach (1) and introduces some extra issues. For example, if one of the intermediate calls to the driver's `update()` returns an error, it is not possible for the driver's state to be rolled back to before the first call to `update()`. It is unclear how this could be solved.
However, this approach would reduce memory usage in some cases and prevent memory allocation during an operation. Additionally, since the input and output buffers would be fixed-size it would be possible to allocate them statically, avoiding the need for any dynamic memory allocation at all.
**Design decision: Initially use approach (1) and treat approach (2) as an optimization to be done if necessary.**
### Validation of copying
#### Validation of copying by review
This is fairly self-explanatory. Review all functions that use shared memory and ensure that they each copy memory. This is the simplest strategy to implement but is less reliable than automated validation.
#### Validation of copying with memory pools
Proposed general idea: have tests where the test code calling API functions allocates memory in a certain pool, and code in the library allocates memory in a different pool. Test drivers check that needs-copying arguments are within the library pool, not within the test pool.
#### Validation of copying by memory poisoning
Proposed general idea: in test code, “poison” the memory area used by input and output parameters that must be copied. Poisoning means something that prevents accessing memory while it is poisoned. This could be via memory protection (allocate with `mmap` then disable access with `mprotect`), or some kind of poisoning for an analyzer such as MSan or Valgrind.
In the library, the code that does the copying temporarily unpoisons the memory by calling a test hook.
```c
static void copy_to_user(void *copy_buffer, void *const input_buffer, size_t length) {
#if defined(MBEDTLS_TEST_HOOKS)
if (memory_poison_hook != NULL) {
memory_poison_hook(copy_buffer, length);
}
#endif
memcpy(copy_buffer, input_buffer, length);
#if defined(MBEDTLS_TEST_HOOKS)
if (memory_unpoison_hook != NULL) {
memory_unpoison_hook(copy_buffer, length);
}
#endif
}
```
The reason to poison the memory before calling the library, rather than after the copy-in (and symmetrically for output buffers) is so that the test will fail if we forget to copy, or we copy the wrong thing. This would not be the case if we relied on the library's copy function to do the poisoning: that would only validate that the driver code does not access the memory on the condition that the copy is done as expected.
##### Options for implementing poisoning
There are several different ways that poisoning could be implemented:
1. Using Valgrind's memcheck tool. Valgrind provides a macro `VALGRIND_MAKE_MEM_NO_ACCESS` that allows manual memory poisoning. Valgrind memory poisoning is already used for constant-flow testing in Mbed TLS.
2. Using Memory Sanitizer (MSan), which allows us to mark memory as uninitialized. This is also used for constant-flow testing. It is suitable for input buffers only, since it allows us to detect when a poisoned buffer is read but not when it is written.
3. Using Address Sanitizer (ASan). This provides `ASAN_POISON_MEMORY_REGION` which marks memory as inaccessible.
4. Allocating buffers separate pages and calling `mprotect()` to set pages as inaccessible. This has the disadvantage that we will have to manually ensure that buffers sit in their own pages, which likely means making a copy.
5. Filling buffers with random data, keeping a copy of the original. For input buffers, keep a copy of the original and copy it back once the PSA function returns. For output buffers, fill them with random data and keep a separate copy of it. In the memory poisoning hooks, compare the copy of random data with the original to ensure that the output buffer has not been written directly.
Approach (2) is insufficient for the full testing we require as we need to be able to check both input and output buffers.
Approach (5) is simple and requires no extra tooling. It is likely to have good performance as it does not use any sanitizers. However, it requires the memory poisoning test hooks to maintain extra copies of the buffers, which seems difficult to implement in practice. Additionally, it does not precisely test the property we want to validate, so we are relying on the tests to fail if given random data as input. It is possible (if unlikely) that the PSA function will access the poisoned buffer without causing the test to fail. This becomes more likely when we consider test cases that call PSA functions on incorrect inputs to check that the correct error is returned. For these reasons, this memory poisoning approach seems unsuitable.
All three remaining approaches are suitable for our purposes. However, approach (4) is more complex than the other two. To implement it, we would need to allocate poisoned buffers in separate memory pages. They would require special handling and test code would likely have to be designed around this special handling.
Meanwhile, approaches (1) and (3) are much more convenient. We are simply required to call a special macro on some buffer that was allocated by us and the sanitizer takes care of everything else. Of these two, ASan appears to have a limitation related to buffer alignment. From code comments quoted in [the documentation](https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning):
> This function is not guaranteed to poison the whole region - it may poison only subregion of [addr, addr+size) due to ASan alignment restrictions.
Specifically, ASan will round the buffer size down to 8 bytes before poisoning due to details of its implementation. For more information on this, see [Microsoft documentation of this feature](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-runtime?view=msvc-170#alignment-requirements-for-addresssanitizer-poisoning).
It should be possible to work around this by manually rounding buffer lengths up to the nearest multiple of 8 in the poisoning function, although it's remotely possible that this will cause other problems. Valgrind does not appear to have this limitation (unless Valgrind is simply more poorly documented). However, running tests under Valgrind causes a much greater slowdown compared with ASan. As a result, it would be beneficial to implement support for both Valgrind and ASan, to give the extra flexibility to choose either performance or accuracy as required. This should be simple as both have very similar memory poisoning interfaces.
**Design decision: Implement memory poisoning tests with both Valgrind's memcheck and ASan manual poisoning.**
##### Validation with new tests
Validation with newly created tests would be simpler to implement than using existing tests, since the tests can be written to take into account memory poisoning. It is also possible to build such a testsuite using existing tests as a starting point - `mbedtls_test_psa_exercise_key` is a test helper that already exercises many PSA operations on a key. This would need to be extended to cover operations without keys (e.g. hashes) and multipart operations, but it provides a good base from which to build all of the required testing.
Additionally, we can ensure that all functions are exercised by automatically generating test data files.
##### Validation with existing tests
An alternative approach would be to integrate memory poisoning validation with existing tests. This has two main advantages:
* All of the tests are written already, potentially saving development time.
* The code coverage of these tests is greater than would be achievable writing new tests from scratch. In practice this advantage is small as buffer copying will take place in the dispatch layer. The tests are therefore independent of the values of parameters passed to the driver, so extra coverage in these parameters does not gain anything.
It may be possible to transparently implement memory poisoning so that existing tests can work without modification. This would be achieved by replacing the implementation of `malloc()` with one that allocates poisoned buffers. However, there are some difficulties with this:
* Not all buffers allocated by tests are used as inputs and outputs to PSA functions being tested.
* Those buffers that are inputs to a PSA function need to be unpoisoned right up until the function is called, so that they can be filled with input data.
* Those buffers that are outputs from a PSA function need to be unpoisoned straight after the function returns, so that they can be read to check the output is correct.
These issues may be solved by creating some kind of test wrapper around every PSA function call that poisons the memory. However, it is unclear how straightforward this will be in practice. If this is simple to achieve, the extra coverage and time saved on new tests will be a benefit. If not, writing new tests is the best strategy.
**Design decision: Add memory poisoning transparently to existing tests.**
#### Discussion of copying validation
Of all discussed approaches, validation by memory poisoning appears as the best. This is because it:
* Does not require complex linking against different versions of `malloc()` (as is the case with the memory pool approach).
* Allows automated testing (unlike the review approach).
**Design decision: Use a memory poisoning approach to validate copying.**
### Shared memory protection requirements
TODO: write document and reference it here.
### Validation of careful access for built-in drivers
For PSA functions whose inputs and outputs are not copied, it is important that we validate that the builtin drivers are correctly accessing their inputs and outputs so as not to cause a security issue. Specifically, we must check that each memory location in a shared buffer is not accessed more than once by a driver function. In this section we examine various possible methods for performing this validation.
Note: We are focusing on read-read inconsistencies for now, as most of the cases where we aren't copying are inputs.
#### Review
As with validation of copying, the simplest method of validation we can implement is careful code review. This is the least desirable method of validation for several reasons:
1. It is tedious for the reviewers.
2. Reviewers are prone to make mistakes (especially when performing tedious tasks).
3. It requires engineering time linear in the number of PSA functions to be tested.
4. It cannot assure the quality of third-party drivers, whereas automated tests can be ported to any driver implementation in principle.
If all other approaches turn out to be prohibitively difficult, code review exists as a fallback option. However, it should be understood that this is far from ideal.
#### Tests using `mprotect()`
Checking that a memory location is not accessed more than once may be achieved by using `mprotect()` on a Linux system to cause a segmentation fault whenever a memory access happens. Tests based on this approach are sketched below.
##### Linux mprotect+ptrace
Idea: call `mmap` to allocate memory for arguments and `mprotect` to deny or reenable access. Use `ptrace` from a parent process to react to SIGSEGV from a denied access. On SIGSEGV happening in the faulting region:
1. Use `ptrace` to execute a `mprotect` system call in the child to enable access. TODO: How? `ptrace` can modify registers and memory in the child, which includes changing parameters of a syscall that's about to be executed, but not directly cause the child process to execute a syscall that it wasn't about to execute.
2. Use `ptrace` with `PTRACE_SINGLESTEP` to re-execute the failed load/store instrution.
3. Use `ptrace` to execute a `mprotect` system call in the child to disable access.
4. Use `PTRACE_CONT` to resume the child execution.
Record the addresses that are accessed. Mark the test as failed if the same address is read twice.
##### Debugger + mprotect
Idea: call `mmap` to allocate memory for arguments and `mprotect` to deny or reenable access. Use a debugger to handle SIGSEGV (Gdb: set signal catchpoint). If the segfault was due to accessing the protected region:
1. Execute `mprotect` to allow access.
2. Single-step the load/store instruction.
3. Execute `mprotect` to disable access.
4. Continue execution.
Record the addresses that are accessed. Mark the test as failed if the same address is read twice. This part might be hard to do in the gdb language, so we may want to just log the addresses and then use a separate program to analyze the logs, or do the gdb tasks from Python.
#### Instrumentation (Valgrind)
An alternative approach is to use a dynamic instrumentation tool (the most obvious being Valgrind) to trace memory accesses and check that each of the important memory addresses is accessed no more than once.
Valgrind has no tool specifically that checks the property that we are looking for. However, it is possible to generate a memory trace with Valgrind using the following:
```
valgrind --tool=lackey --trace-mem=yes --log-file=logfile ./myprogram
```
This will execute `myprogram` and dump a record of every memory access to `logfile`, with its address and data width. If `myprogram` is a test that does the following:
1. Set up input and output buffers for a PSA function call.
2. Leak the start and end address of each buffer via `print()`.
3. Write data into the input buffer exactly once.
4. Call the PSA function.
5. Read data from the output buffer exactly once.
Then it should be possible to parse the output from the program and from Valgrind and check that each location was accessed exactly twice: once by the program's setup and once by the PSA function.
#### Fixed Virtual Platform testing
It may be possible to measure double accesses by running tests on a Fixed Virtual Platform such as Corstone 310 ecosystem FVP, available [here](https://developer.arm.com/downloads/-/arm-ecosystem-fvps). There exists a pre-packaged example program for the Corstone 310 FVP available as part of the Open IoT SDK [here](https://git.gitlab.arm.com/iot/open-iot-sdk/examples/sdk-examples/-/tree/main/examples/mbedtls/cmsis-rtx/corstone-310) that could provide a starting point for a set of tests.
Running on an FVP allows two approaches to careful-access testing:
* Convenient scripted use of a debugger with [Iris](https://developer.arm.com/documentation/101196/latest/). This allows memory watchpoints to be set, perhaps more flexibly than with GDB.
* Tracing of all memory accesses with [Tarmac Trace](https://developer.arm.com/documentation/100964/1123/Plug-ins-for-Fast-Models/TarmacTrace). To validate the single-access properties, the [processor memory access trace source](https://developer.arm.com/documentation/100964/1123/Plug-ins-for-Fast-Models/TarmacTrace/Processor-memory-access-trace) can be used to output all memory accesses happening on the FVP. This output can then be easily parsed and processed to ensure that the input and output buffers are accessed only once. The addresses of buffers can either be leaked by the program through printing to the serial port or set to fixed values in the FVP's linker script.
#### Discussion of careful-access validation
The best approach for validating the correctness of memory accesses is an open question that requires further investigation. To answer this question, each of the test strategies discussed above must be prototyped as follows:
1. Take 1-2 days to create a basic prototype of a test that uses the approach.
2. Document the prototype - write a short guide that can be followed to arrive at the same prototype.
3. Evaluate the prototype according to its usefulness. The criteria of evaluation should include:
* Ease of implementation - Was the prototype simple to implement? Having implemented it, is it simple to extend it to do all of the required testing?
* Flexibility - Could the prototype be extended to cover other careful-access testing that may be needed in future?
* Performance - Does the test method perform well? Will it cause significant slowdown to CI jobs?
* Ease of reproduction - Does the prototype require a particular platform or tool to be set up? How easy would it be for an external user to run the prototype?
* Comprehensibility - Accounting for the lower code quality of a prototype, would developers unfamiliar with the tests based on the prototype be able to understand them easily?
* Portability - How well can this approach be ported to multiple platforms? This would allow us to ensure that there are no double-accesses due to a bug that only affects a specific target.
Once each prototype is complete, choose the best approach to implement the careful-access testing. Implement tests using this approach for each of the PSA interfaces that require careful-access testing:
* Hash
* MAC
* AEAD (additional data only)
* Key derivation
* Asymmetric signature (input only)
##### New vs existing tests
Most of the test methods discussed above need extra setup. Some require leaking of buffer bounds, predictable memory access patterns or allocation of special buffers. FVP testing even requires the tests to be run on a non-host target.
With this complexity in mind it does not seem feasible to run careful-access tests using existing testsuites. Instead, new tests should be written that exercise the drivers in the required way. Fortunately, the only interfaces that need testing are hash, MAC, AEAD (testing over AD only), Key derivation and Asymmetric signature, which limits the number of new tests that must be written.
#### Validation of validation for careful-access
In order to ensure that the careful-access validation works, it is necessary to write tests to check that we can correctly detect careful-access violations when they occur. To do this, write a test function that:
* Reads its input multiple times at the same location.
* Writes to its output multiple times at the same location.
Then, write a careful-access test for this function and ensure that it fails.
## Analysis of argument protection in built-in drivers
TODO: analyze the built-in implementations of mechanisms for which there is a requirement on drivers. By code inspection, how satisfied are we that they meet the requirement?
## Copy bypass
For efficiency, we are likely to want mechanisms to bypass the copy and process buffers directly in builds that are not affected by shared memory considerations.
Expand this section to document any mechanisms that bypass the copy.
Make sure that such mechanisms preserve the guarantees when buffers overlap.
## Detailed design
### Implementation by module
Module | Input protection strategy | Output protection strategy | Notes
---|---|---|---
Hash and MAC | Careful access | Careful access | Low risk of multiple-access as the input and output are raw unformatted data.
Cipher | Copying | Copying |
AEAD | Copying (careful access for additional data) | Copying |
Key derivation | Careful access | Careful access |
Asymmetric signature | Careful access | Copying | Inputs to signatures are passed to a hash. This will no longer hold once PureEdDSA support is implemented.
Asymmetric encryption | Copying | Copying |
Key agreement | Copying | Copying |
PAKE | Copying | Copying |
Key import / export | Copying | Copying | Keys may be imported and exported in DER format, which is a structured format and therefore susceptible to read-read inconsistencies and potentially write-read inconsistencies.
### Copying functions
As discussed in [Copying code](#copying-code), it is simpler to use a single unified API for copying. Therefore, we create the following functions:
* `psa_crypto_copy_input(const uint8_t *input, size_t input_length, uint8_t *input_copy, size_t input_copy_length)`
* `psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_length, uint8_t *output, size_t output_length)`
These seem to be a repeat of the same function, however it is useful to retain two separate functions for input and output parameters so that we can use different test hooks in each when using memory poisoning for tests.
Given that the majority of functions will be allocating memory on the heap to copy, it is helpful to build convenience functions that allocate the memory as well.
In order to keep track of allocated copies on the heap, we can create new structs:
```c
typedef struct psa_crypto_local_input_s {
uint8_t *buffer;
size_t length;
} psa_crypto_local_input_t;
typedef struct psa_crypto_local_output_s {
uint8_t *original;
uint8_t *buffer;
size_t length;
} psa_crypto_local_output_t;
```
These may be used to keep track of input and output copies' state, and ensure that their length is always stored with them. In the case of output copies, we keep a pointer to the original buffer so that it is easy to perform a writeback to the original once we have finished outputting.
With these structs we may create 2 pairs of functions, one pair for input copies:
```c
psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len,
psa_crypto_local_input_t *local_input);
void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input);
```
* `psa_crypto_local_input_alloc()` calls `calloc()` to allocate a new buffer of length `input_len`, copies the contents across from `input`. It then stores `input_len` and the pointer to the copy in the struct `local_input`.
* `psa_crypto_local_input_free()` calls `free()` on the local input that is referred to by `local_input` and sets the pointer in the struct to `NULL`.
We also create a pair of functions for output copies:
```c
psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len,
psa_crypto_local_output_t *local_output);
psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output);
```
* `psa_crypto_local_output_alloc()` calls `calloc()` to allocate a new buffer of length `output_len` and stores `output_len` and the pointer to the buffer in the struct `local_output`. It also stores a pointer to `output` in `local_output->original`.
* `psa_crypto_local_output_free()` copies the contents of the output buffer `local_output->buffer` into the buffer `local_output->original`, calls `free()` on `local_output->buffer` and sets it to `NULL`.
Some PSA functions may not use these convenience functions as they may have local optimizations that reduce memory usage. For example, ciphers may be able to use a single intermediate buffer for both input and output.
In order to abstract the management of the copy state further, to make it simpler to add, we create the following 6 convenience macros:
For inputs:
* `LOCAL_INPUT_DECLARE(input, input_copy_name)`, which declares and initializes a `psa_crypto_local_input_t` and a pointer with the name `input_copy_name` in the current scope.
* `LOCAL_INPUT_ALLOC(input, input_size, input_copy)`, which tries to allocate an input using `psa_crypto_local_input_alloc()`. On failure, it sets an error code and jumps to an exit label. On success, it sets `input_copy` to point to the copy of the buffer.
* `LOCAL_INPUT_FREE(input, input_copy)`, which frees the input copy using `psa_crypto_local_input_free()` and sets `input_copy` to `NULL`.
For outputs:
* `LOCAL_OUTPUT_DECLARE(output, output_copy_name)`, analogous to `LOCAL_INPUT_DECLARE()` for `psa_crypto_local_output_t`.
* `LOCAL_OUTPUT_ALLOC(output, output_size, output_copy)`, analogous to `LOCAL_INPUT_ALLOC()` for outputs, calling `psa_crypto_local_output_alloc()`.
* `LOCAL_OUTPUT_FREE(output, output_copy)`, analogous to `LOCAL_INPUT_FREE()` for outputs. If the `psa_crypto_local_output_t` is in an invalid state (the copy pointer is valid, but the original pointer is `NULL`) this macro sets an error status.
These macros allow PSA functions to have copying added while keeping the code mostly unmodified. Consider a hypothetical PSA function:
```c
psa_status_t psa_foo(const uint8_t *input, size_t input_length,
uint8_t *output, size_t output_size, size_t *output_length)
{
/* Do some operation on input and output */
}
```
By changing the name of the input and output parameters, we can retain the original variable name as the name of the local copy while using a new name (e.g. with the suffix `_external`) for the original buffer. This allows copying to be added near-seamlessly as follows:
```c
psa_status_t psa_foo(const uint8_t *input_external, size_t input_length,
uint8_t *output_external, size_t output_size, size_t *output_length)
{
psa_status_t status;
LOCAL_INPUT_DECLARE(input_external, input);
LOCAL_OUTPUT_DECLARE(output_external, output);
LOCAL_INPUT_ALLOC(input_external, input);
LOCAL_OUTPUT_ALLOC(output_external, output);
/* Do some operation on input and output */
exit:
LOCAL_INPUT_FREE(input_external, input);
LOCAL_OUTPUT_FREE(output_external, output);
}
```
A second advantage of using macros for the copying (other than simple convenience) is that it allows copying to be easily disabled by defining alternate macros that function as no-ops. Since buffer copying is specific to systems where shared memory is passed to PSA functions, it is useful to be able to disable it where it is not needed, to save code size.
To this end, the macros above are defined conditionally on a new config option, `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS`, which may be set whenever PSA functions are assumed to have exclusive access to their input and output buffers. When `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS` is set, the macros do not perform copying.
### Implementation of copying validation
As discussed in the [design exploration of copying validation](#validation-of-copying), the best strategy for validation of copies appears to be validation by memory poisoning, implemented using Valgrind and ASan.
To perform memory poisoning, we must implement the functions alluded to in [Validation of copying by memory poisoning](#validation-of-copying-by-memory-poisoning):
```c
void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size);
void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size);
```
This should poison or unpoison the given buffer, respectively.
* `mbedtls_test_memory_poison()` is equivalent to calling `VALGRIND_MAKE_MEM_NOACCESS(ptr, size)` or `ASAN_POISON_MEMORY_REGION(ptr, size)`.
* `mbedtls_test_memory_unpoison()` is equivalent to calling `VALGRIND_MAKE_MEM_DEFINED(ptr, size)` or `ASAN_UNPOISON_MEMORY_REGION(ptr, size)`.
The PSA copying function must then have test hooks implemented as outlined in [Validation of copying by memory poisoning](#validation-of-copying-by-memory-poisoning).
As discussed in [the design exploration](#validation-with-existing-tests), the preferred approach for implementing copy-testing is to implement it transparently using existing tests. This is specified in more detail below.
#### Transparent allocation-based memory poisoning
In order to implement transparent memory poisoning we require a wrapper around all PSA function calls that poisons any input and output buffers.
The easiest way to do this is to create wrapper functions that poison the memory and then `#define` PSA function names to be wrapped versions of themselves. For example, to replace `psa_aead_update()`:
```c
psa_status_t mem_poison_psa_aead_update(psa_aead_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
mbedtls_test_memory_poison(input, input_length);
mbedtls_test_memory_poison(output, output_size);
psa_status_t status = psa_aead_update(operation, input, input_length,
output, output_size, output_length);
mbedtls_test_memory_unpoison(input, input_length);
mbedtls_test_memory_unpoison(output, output_size);
return status;
}
#define psa_aead_update(...) mem_poison_psa_aead_update(__VA_ARGS__)
```
There now exists a more generic mechanism for making exactly this kind of transformation - the PSA test wrappers, which exist in the files `tests/include/test/psa_test_wrappers.h` and `tests/src/psa_test_wrappers.c`. These are wrappers around all PSA functions that allow testing code to be inserted at the start and end of a PSA function call.
The test wrappers are generated by a script, although they are not automatically generated as part of the build process. Instead, they are checked into source control and must be manually updated when functions change by running `tests/scripts/generate_psa_wrappers.py`.
Poisoning code is added to these test wrappers where relevant in order to pre-poison and post-unpoison the parameters to the functions.
#### Configuration of poisoning tests
Since the memory poisoning tests will require the use of interfaces specific to the sanitizers used to poison memory, they must only be enabled when we are building with ASan or Valgrind. For now, we can auto-detect ASan at compile-time and set an option: `MBEDTLS_TEST_MEMORY_CAN_POISON`. When this option is enabled, we build with memory-poisoning support. This enables transparent testing with ASan without needing any extra configuration options.
Auto-detection and memory-poisoning with Valgrind is left for future work.
#### Validation of validation for copying
To make sure that we can correctly detect functions that access their input/output buffers rather than the copies, it would be best to write a test function that misbehaves and test it with memory poisoning. Specifically, the function should:
* Read its input buffer and after calling the input-buffer-copying function to create a local copy of its input.
* Write to its output buffer before and after calling the output-buffer-copying function to copy-back its output.
Then, we could write a test that uses this function with memory poisoning and ensure that it fails. Since we are expecting a failure due to memory-poisoning, we would run this test separately from the rest of the memory-poisoning testing.
This testing is implemented in `programs/test/metatest.c`, which is a program designed to check that test failures happen correctly. It may be run via the script `tests/scripts/run-metatests.sh`.
+536
View File
@@ -0,0 +1,536 @@
# PSA storage resilience design
## Introduction
The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if the underlying storage exhibits non-nominal behavior. In this document, _resilience_ means correct behavior of the key store even under if the underlying platform behaves in a non-nominal, but still partially controlled way.
At this point, we are only concerned about one specific form of resilience: to a system crash or power loss. That is, we assume that the underlying platform behaves nominally, except that occasionally it may restart. In the field, this can happen due to a sudden loss of power.
This document explores the problem space, defines a library design and a test design.
## Resilience goals for API functions
**Goal: PSA Crypto API functions are atomic and committing.**
_Atomic_ means that when an application calls an API function, as far as the application is concerned, at any given point in time, the system is either in a state where the function has not started yet, or in a state where the function has returned. The application never needs to worry about an intermediate state.
_Committing_ means that when a function returns, the data has been written to the persistent storage. As a consequence, if the system restarts during a sequence of storage modifications $M_1, M_2, \ldots, M_n$, we know that when the system restarts, a prefix of the sequence has been performed. For example, there will never be a situation where $M_2$ has been performed but not $M_1$.
The committing property is important not only for sequences of operations, but also when reporting the result of an operation to an external system. For example, if a key creation function in the PSA Crypto API reports to the application that a key has been created, and the application reports to a server that the key has been created, it is guaranteed that the key exists even if the system restarts.
## Assumptions on the underlying file storage
PSA relies on a PSA ITS (Internal Trusted Storage) interface, which exposes a simple API. There are two functions to modify files:
* `set()` writes a whole file (either creating it, or replacing the previous content).
* `remove()` removes a file (returning a specific error code if the file does not exist).
**Assumption: the underlying ITS functions are atomic and committing.**
Since the underlying functions are atomic, the content of a file is always a version that was previously passed to `set()`. We do not try to handle the case where a file might be partially written.
## Overview of API functions
For a transparent key, all key management operations (creation or destruction) on persistent keys rely on a single call to the underlying storage (`set()` for a key creation, `remove()` for a key destruction). This also holds for an opaque key stored in a secure element that does not have its own key store: in this case, the core stores a wrapped (i.e. encrypted) copy of the key material, but this does not impact how the core interacts with the storage. Other API functions do not modify the storage.
The following case requires extra work related to resilience:
* [Key management for stateful secure element keys](#designing-key-management-for-secure-element-keys).
As a consequence, apart from the listed cases, the API calls inherit directly from the [resilience properties of the underyling storage](#assumptions-on-the-underlying-file-storage). We do not need to take any special precautions in the library design, and we do not need to perform any testing of resilience for transparent keys.
(This section was last updated for Mbed TLS 3.4.0 implementing PSA Crypto API 1.1.)
## Designing key management for secure element keys
In this section, we use “(stateful) secure element key” to mean a key stored in a stateful secure element, i.e. a secure element that stores keys. This excludes keys in a stateleess secure element for which the core stores a wrapped copy of the key. We study the problem of how key management in stateful secure elements interacts with storage and explore the design space.
### Assumptions on stateful secure elements
**Assumption: driver calls for key management in stateful secure elements are atomic and committing.**
(For stateless secure elements, this assumption is vacuously true.)
### Dual management of keys: the problem
For a secure element key, key management requires a commitment on both sites. For example, consider a successful key creation operation:
1. The core sends a request to the secure element to create a key.
2. The secure element modifies its key store to create the key.
3. The secure element reports to the core that the key has been created.
4. The core reports to the application that the key has been created.
If the core loses power between steps 1 and 2, the key does not exist yet. This is fine from an application's perspective since the core has not committed to the key's existence, but the core needs to take care not to leave resources in storage that are related to the non-existent key. If the core loses power between steps 2 and 3, the key exists in the secure element. From an application's perspective, the core may either report that the key exists or that it does not exist, but in the latter case, the core needs to free the key in the secure element, to avoid leaving behind inaccessible resources.
As a consequence, the content of the storage cannot remain the same between the end of step 1 and the end of step 3, since the core must behave differently depending on whether step 2 has taken place.
Accomplishing a transaction across system boundaries is a well-known problem in database management, with a well-known solution: two-phase commit.
### Overview of two-phase commit with stateful secure elements
With a key in a stateful secure element, a successful creation process goes as follows (see [“Key management in a secure element with storage” in the driver interface specification](../../proposed/psa-driver-interface.html#key-management-in-a-secure-element-with-storage)):
1. The core calls the driver's `"allocate_key"` entry point.
2. The driver allocates a unique identifier _D_ for the key. This is unrelated to the key identifier _A_ used by the application interface. This step must not modify the state of the secure element.
3. The core updates the storage to indicate that key identifier _A_ has the identifier _D_ in the driver, and that _A_ is in a half-created state.
4. The core calls the driver's key creation entry point, passing it the driver's chosen identifier _D_.
5. The driver creates the key in the secure element. When this happens, it concludes the voting phase of the two-phase commit: effectively, the secure element decides to commit. (It is however possible to revert this commitment by giving the secure element the order to destroy the key.)
6. The core updates the storage to indicate that _A_ is now in a fully created state. This concludes the commit phase of the two-phase commit.
If there is a loss of power:
* Before step 3: the system state has not changed at all. As far as the world is concerned, the key creation attempt never happened.
* Between step 3 and step 6: upon restart, the core needs to find out whether the secure element completed step 5 or not, and reconcile the state of the storage with the state of the secure element.
* After step 6: the key has been created successfully.
Key destruction goes as follows:
1. The core updates the storage indicating that the key is being destroyed.
2. The core calls the driver's `"destroy_key"` entry point.
3. The secure element destroys the key.
4. The core updates the storage to indicate that the key has been destroyed.
If there is a loss of power:
* Before step 1: the system state has not changed at all. As far as the world is concerned, the key destruction attempt never happened.
* Between step 1 and step 4: upon restart, the core needs to find out whether the secure element completed step 3 or not, and reconcile the state of the storage with the state of the secure element.
* After step 4: the key has been destroyed successfully.
In both cases, upon restart, the core needs to perform a transaction recovery. When a power loss happens, the core decides whether to commit or abort the transaction.
Note that the analysis in this section assumes that the driver does not update its persistent state during a key management operation (or at least not in a way that is influences the key management process — for example, it might renew an authorization token).
### Optimization considerations for transactions
We assume that power failures are rare. Therefore we will primarily optimize for the normal case. Transaction recovery needs to be practical, but does not have to be fully optimized.
The main quantity we will optimize for is the number of storage updates in the nominal case. This is good for performance because storage writes are likely to dominate the runtime in some hardware configurations where storage writes are slow and communication with the secure element is fast, for key management operations that require a small amount of computation. In addition, minimizing the number of storage updates is good for the longevity of flash media.
#### Information available during recovery
The PSA ITS API does not support enumerating files in storage: an ITS call can only access one file identifier. Therefore transaction recovery cannot be done by traversing files whose name is or encodes the key identifier. It must start by traversing a small number of files whose names are independent of the key identifiers involved.
#### Minimum effort for a transaction
Per the [assumptions on the underlying file storage](#assumptions-on-the-underlying-file-storage), each atomic operation in the internal storage concerns a single file: either removing it, or setting its content. Furthermore there is no way to enumerate the files in storage.
A key creation function must transform the internal storage from a state where file `id` does not exist, to a state where file `id` exists and has its desired final content (containing the key attributes and the driver's key identifier). The situation is similar with key destruction, except that the initial and final states are exchanged. Neither the initial state nor the final state reference `id` otherwise.
For a key that is not in a stateful element, the transaction consists of a single write operation. As discussed previously, this is not possible with a stateful secure element because the state of the internal storage needs to change both before and after the state change in the secure element. No other single-write algorithm works.
If there is a power failure around the time of changing the state of the secure element, there must be information in the internal storage that indicates that key `id` has a transaction in progress. The file `id` cannot be used for this purpose because there is no way to enumerate all keys (and even if there was, it would not be practical). Therefore the transaction will need to modify some other file `t` with a fixed name (a name that doesn't depend on the key). Since the final system state should be identical to the initial state except for the file `id`, the minimum number of storage operations for a transaction is 3:
* Write (create or update) a file `t` referencing `id`.
* Write the final state of `id`.
* Restore `t` to its initial state.
The strategies discussed in the [overview above](#overview-of-two-phase-commit-with-stateful-secure-elements) follow this pattern, with `t` being the file containing the transaction list that the recovery consults. We have just proved that this pattern is optimal.
Note that this pattern requires the state of `id` to be modified only once. In particular, if a key management involves writing an intermediate state for `id` before modifying the secure element state and writing a different state after that, this will require a total of 4 updates to internal storage. Since we want to minimize the number of storage updates, we will not explore designs that involved updating `id` twice or more.
### Recovery strategies
When the core starts, it needs to know about transaction(s) that need to be resumed. This information will be stored in a persistent “transaction list”, with one entry per key. In this section, we explore recovery strategies, and we determine what the transaction list needs to contain as well as when it needs to be updated. Other sections will explore the format of the transaction list, as well as how many keys it needs to contain.
#### Exploring the recovery decision tree
There are four cases for recovery when a transaction is in progress. In each case, the core can either decide to commit the transaction (which may require replaying the interrupted part) or abort it (which may require a rewind in the secure element). It may call the secure element driver's `"get_key_attributes"` entry point to find out whether the key is present.
* Key creation, key not present in the secure element:
* Committing means replaying the driver call in the key creation. This requires all the input, for example the data to import. This seems impractical in general. Also, the second driver call require a new call to `"allocate_key"` which will in general changing the key's driver identifier, which complicates state management in the core. Given the likely complexity, we exclude this strategy.
* Aborting means removing any trace of the key creation.
* Key creation, key present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted.
* Aborting means destroying the key in the secure element and removing any local storage used for that key.
* Key destruction, key not present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key.
* Aborting would mean re-creating the key in the secure element, which is impossible in general since the key material is no longer present.
* Key destruction, key present in the secure element:
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key and destroying the key in the secure element.
* Aborting means keeping the key. This requires no action on the secure element, and is only practical locally if the local storage is intact.
#### Comparing recovery strategies
From the analysis above, assuming that all keys are treated in the same way, there are 4 possible strategies.
* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element driver to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point.
* Minimize the information processing: [always destroy the key](#exploring-the-always-destroy-strategy), i.e. abort all key creations and commit all key destructions. This does not require querying the state of the secure element. This does not require any special precautions to preserve information about the key during the transaction. It simplifies recovery in that the recovery process might not even need to know whether it's recovering a key creation or a key destruction.
* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element driver to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further.
* Always abort key creation, but follow the state of the secure element for key destruction. I can't think of a good reason to choose this strategy.
Requiring the driver to have a `"get_key_attributes"` entry point is potentially problematic because some secure elements don't have room to store key attributes: a key slot always exists, and it's up to the user to remember what, if anything, they put in it. The driver has to remember anyway, so that it can find a free slot when creating a key. But with a recovery strategy that doesn't involve a `"get_key_attributes"` entry point, the driver design is easier: the driver doesn't need to protect the information about slots in use against a power failure, the core takes care of that.
#### Exploring the follow-the-secure-element strategy
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier (not constant-size), and an indication of whether the key is being created or destroyed.
For key creation, we have all the information to store in the key file once the `"allocate_key"` call returns. We must store all the information that will go in the key file before calling the driver's key creation entry point. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list, indicating that it is being created.
3. Write the key file.
4. Call the driver's key creation entry point.
5. Remove the key from the transaction list.
During recovery, for each key in the transaction list that was being created:
* If the key exists in the secure element, just remove it from the transaction list.
* If the key does not exist in the secure element, first remove the key file if it is present, then remove the key from the transaction list.
For key destruction, we need to preserve the key file until after the key has been destroyed. Therefore the normal sequence of operations is:
1. Add the key to the transaction list, indicating that it is being destroyed.
2. Call the driver's `"destroy_key"` entry point.
3. Remove the key file.
4. Remove the key from the transaction list.
During recovery, for each key in the transaction list that was being created:
* If the key exists in the secure element, call the driver's `"destroy_key"` entry point, then remove the key file, and finally remote the key from the transaction lits.
* If the key does not exist in the secure element, remove the key file if it is still present, then remove the key from the transaction list.
#### Exploring the always-destroy strategy
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier (not constant-size).
For key creation, we do not need to store the key's metadata until it has been created in the secure element. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list.
3. Call the driver's key creation entry point.
4. Write the key file.
5. Remove the key from the transaction list.
For key destruction, we can remove the key file before contacting the secure element. Therefore the normal sequence of operations is:
1. Add the key to the transaction list.
2. Remove the key file.
3. Call the driver's `"destroy_key"` entry point.
4. Remove the key from the transaction list.
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
1. Remove the key file, treating `DOES_NOT_EXIST` as a success.
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
3. Remove the key from the transaction list.
#### Always-destroy strategy with a simpler transaction file
We can modify the [always-destroy strategy](#exploring-the-always-destroy-strategy) to make the transaction file simpler: if we ensure that the key file always exists if the key exists in the secure element, then the transaction list does not need to include the driver key identifier: it can be read from the key file.
For key creation, we need to store the key's metadata before creating in the secure element. Therefore the normal sequence of operations is:
1. Call the driver's `"allocate_key"` entry point.
2. Add the key to the transaction list.
3. Write the key file.
4. Call the driver's key creation entry point.
5. Remove the key from the transaction list.
For key destruction, we need to contact the secure element before removing the key file. Therefore the normal sequence of operations is:
1. Add the key to the transaction list.
2. Call the driver's `"destroy_key"` entry point.
3. Remove the key file.
4. Remove the key from the transaction list.
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
1. Load the driver key identifier from the key file. If the key file does not exist, skip to step 4.
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
3. Remove the key file, treating `DOES_NOT_EXIST` as a success.
4. Remove the key from the transaction list.
Compared with the basic always-destroy strategy:
* The transaction file handling is simpler since its entries have a fixed size.
* The flow of information is somewhat different from transparent keys and keys in stateless secure elements: we aren't just replacing “create the key material” by “tell the secure element to create the key material”, those happen at different times. But there's a different flow for stateful secure elements anyway, since the call to `"allocate_key"` has no analog in the stateless secure element or transparent cases.
#### Assisting secure element drivers with recovery
The actions of the secure element driver may themselves be non-atomic. So the driver must be given a chance to perform recovery.
To simplify the design of the driver, the core should guarantee that the driver will know if a transaction was in progress and the core cannot be sure about the state of the secure element. Merely calling a read-only entry point such as `"get_key_attributes"` does not provide enough information to the driver for it to know that it should actively perform recovery related to that key.
This gives an advantage to the “always destroy” strategy. Under this strategy, if the key might be in a transitional state, the core will request a key destruction from the driver. This means that, if the driver has per-key auxiliary data to clean up, it can bundle that as part of the key's destruction.
### Testing non-atomic processes
In this section, we discuss how to test non-atomic processes that must implement an atomic and committing interface. As discussed in [“Overview of API functions”](#overview-of-api-functions), this concerns key management in stateful secure elements.
#### Naive test strategy for non-atomic processes
Non-atomic processes consist of a series of atomic, committing steps.
Our general strategy to test them is as follows: every time there is a modification of persistent state, either in storage or in the (simulated) secure element, try both the nominal case and simulating a power loss. If a power loss occurs, restart the system (i.e. clean up and call `psa_crypto_init()`), and check that the system ends up in a consistent state.
Note that this creates a binary tree of possibilities: after each state modification, there may or may not be a restart, and after that different state modifications may occur, each of which may or may not be followed by a restart.
For example, consider testing of one key creation operation (see [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements), under the simplifying assumption that each storage update step, as well as the recovery after a restart, each make a single (atomic) storage modification and no secure element access. The nominal case consists of three state modifications: storage modification (start transaction), creation on the secure element, storage modification (commit transaction). We need to test the following sequences:
* Start transaction, restart, recovery.
* Start transaction, secure element operation, restart, recovery.
* Start transaction, secure element operation, commit transaction.
If, for example, recovery consists of two atomic steps, the tree of possibilities expands and may be infinite:
* Start transaction, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
* etc.
* Start transaction, secure element operation, restart, ...
* Start transaction, secure element operation, commit transaction.
In order to limit the possibilities, we need to make some assumptions about the recovery step. For example, if we have confidence that recovery step 1 is idempotent (i.e. doing it twice is the same as doing it once), we don't need to test what happens in execution sequences that take recovery step 1 more than twice in a row.
### Splitting normal behavior and transaction recovery
We introduce an abstraction level in transaction recovery:
* Normal operation must maintain a certain invariant on the state of the world (internal storage and secure element).
* Transaction recovery is defined over all states of the world that satisfy this invariant.
This separation of concerns greatly facilitates testing, since it is now split into two parts:
* During the testing of normal operation, we can use read-only invasive testing to ensure that the invariant is maintained. No modification of normal behavior (such as simulated power failures) is necessary.
* Testing of transaction recovery is independent of how the system state was reached. We only need to artificially construct a representative sample of system states that match the invariant. Transaction recovery is itself an operation that must respect the invariant, and so we do not need any special testing for the case of an interrupted recovery.
Another benefit of this approach is that it is easier to specify and test what happens if the library is updated on a device with leftovers from an interrupted transaction. We will require and test that the new version of the library supports recovery of the old library's states, without worrying how those states were reached.
#### Towards an invariant for transactions
As discussed in the section [“Recovery strategies”](#recovery-strategies), the information about active transactions is stored in a transaction list file. The name of the transaction list file does not depend on the identifiers of the keys in the list, but there may be more than one transaction list, for example one per secure element. If so, each transaction list can be considered independently.
When no transaction is in progress, the transaction list does not exist, or is empty. The empty case must be supported because this is the initial state of the filesystem. When no transaction is in progress, the state of the secure element must be consistent with references to keys in that secure element contained in key files. More generally, if a key is not in the transaction list, then the key must be present in the secure element if and only if the key file is in the internal storage.
For the purposes of the state invariant, it matters whether the transaction list file contains the driver key identifier, or if the driver key identifier is only stored in the key file. This is because the core needs to know the driver key id in order to access the secure element. If the transaction list does not contain the driver key identifier, and the key file does not exist, the key must not be present in the secure element.
We thus have two scenarios, each with their own invariant: one where the transaction list contains only key identifiers, and one where it also contains the secure element's key identifier (as well as the location of the secure element if this is not encoded in the name of the transaction list file).
#### Storage invariant if the transaction list contains application key identifiers only
Invariants:
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
If `id` is in the transaction list and the file `id` exists, the key may or may not be present in the secure element.
The invariant imposes constraints on the [order of operations for the two-phase commit](#overview-of-two-phase-commit-with-stateful-secure-elements): key creation must create `id` before calling the secure element's key creation entry point, and key destruction must remove `id` after calling the secure element's key destruction entry point.
For recovery:
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
* If the file `id` exists:
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
#### Storage invariant if the transaction list contains driver key identifiers
Invariants:
* If `id` is not in the transaction list and the file `id` does not exist, then no resources corresponding to that key are in a secure element.
* If `id` is not in the transaction list and the file `id` exists, then the key is present in the secure element.
If `id` is in the transaction list, neither the state of `id` in the internal storage nor the state of the key in the secure element is known.
For recovery:
* If the file `id` does not exist, then destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success).
* If the file `id` exists:
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
#### Coverage of states that respect the invariant
For a given key, we have to consider three a priori independent boolean states:
* Whether the key file exists.
* Whether the key is in the secure element.
* Whether the key is in the transaction list.
There is full coverage for one key if we have tests of recovery for the states among these $2^3 = 8$ possibilities that satisfy the storage invariant.
In addition, testing should adequately cover the case of multiple keys in the transaction list. How much coverage is adequate depends on the layout of the list as well as white-box considerations of how the list is manipulated.
### Choice of a transaction design
#### Chosen transaction algorithm
Based on [“Optimization considerations for transactions”](#optimization-considerations-for-transactions), we choose a transaction algorithm that consists in the following operations:
1. Add the key identifier to the transaction list.
2. Call the secure element's key creation or destruction entry point.
3. Remove the key identifier from the transaction list.
In addition, before or after step 2, create or remove the key file in the internal storage.
In order to conveniently support multiple transactions at the same time, we pick the simplest possible layout for the transaction list: a simple array of key identifiers. Since the transaction list does not contain the driver key identifier:
* During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point.
* During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage.
This choice of algorithm does not require the secure element driver to have a `"get_key_attributes"` entry point.
#### Chosen storage invariant
The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows:
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
* If `id` is in the transaction list and a key exists by that identifier, the key's location is a stateful secure element.
#### Chosen recovery process
To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy with a simple transaction file](#always-destroy-strategy-with-a-simpler-transaction-file). The the recovery process is as follows:
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
* If the file `id` exists, call the secure element's key destruction entry point (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
## Specification of key management in stateful secure elements
This section only concerns stateful secure elements as discussed in [“Designing key management for secure element keys”](#designing-key-management-for-secure-element-keys), i.e. secure elements with an `"allocate_key"` entry point. The design follows the general principle described in [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements) and the specific choices justified in [“Choice of a transaction design”](choice-of-a-transaction-design).
### Transaction list file manipulation
The transaction list is a simple array of key identifiers.
To add a key identifier to the list:
1. Load the current list from the transaction list if it exists and it is not already cached in memory.
2. Append the key identifier to the array.
3. Write the updated list file.
To remove a key identifier from the list:
1. Load the current list if it is not already cached in memory. It is an error if the file does not exist since it must contain this identifier.
2. Remove the key identifier from the array. If it wasn't the last element in array, move array elements to fill the hole.
3. If the list is now empty, remove the transaction list file. Otherwise write the updated list to the file.
### Key creation process in the core
Let _A_ be the application key identifier.
1. Call the driver's `"allocate_key"` entry point, obtaining the driver key identifier _D_ chosen by the driver.
2. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
3. Create the key file _A_ in the internal storage. Note that this is done at a different time from what happens when creating a transparent key or a key in a stateless secure element: in those cases, creating the key file happens after the actual creation of the key material.
4. Call the secure element's key creation entry point.
5. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
If any step fails:
* If the secure element's key creation entry point has been called and succeeded, call the secure element's destroy entry point.
* If the key file has been created in the internal storage, remove it.
* Remove the key from the transaction list.
Note that this process is identical to key destruction, except that the key is already in the transaction list.
### Key destruction process in the core
Let _A_ be the application key identifier.
We assume that the key is loaded in a key slot in memory: the core needs to know the key's location in order to determine whether the key is in a stateful secure element, and if so to know the driver key identifier. A possible optimization would be to load only that information in local variables, without occupying a key store; this has the advantage that key destruction works even if the key store is full.
1. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
2. Call the secure element's `"destroy_key"` entry point.
3. Remove the key file _A_ from the internal storage.
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
5. Free the corresponding key slot in memory.
If any step fails, remember the error but continue the process, to destroy the resources associated with the key as much as is practical.
### Transaction recovery
For each key _A_ in the transaction list file, if the file _A_ exists in the internal storage:
1. Load the key into a key slot in memory (to get its location and the driver key identifier, although we could get the location from the transaction list).
2. Call the secure element's `"destroy_key"` entry point.
3. Remove the key file _A_ from the internal storage.
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
5. Free the corresponding key slot in memory.
The transaction list file can be processed in any order.
It is correct to update the transaction list after recovering each key, or to only delete the transaction list file once the recovery is over.
### Concrete format of the transaction list file
The transaction list file contains a [fixed header](#transaction-list-header-format) followed by a list of [fixed-size elements](#transaction-list-element-format).
The file uid is `PSA_CRYPTO_ITS_TRANSACTION_LIST_UID` = 0xffffff53.
#### Transaction list header format
* Version (2 bytes): 0x0003. (Chosen to differ from the first two bytes of a [dynamic secure element transaction file](#dynamic-secure-element-transaction-file), to reduce the risk of a mix-up.)
* Key name size (2 bytes): `sizeof(psa_storage_uid_t)`. Storing this size avoids reading bad data if Mbed TLS is upgraded to a different integration that names keys differently.
#### Transaction list element format
In practice, there will rarely be more than one active transaction at a time, so the size of an element is not critical for efficiency. Therefore, in addition to the key identifier which is required, we add some potentially useful information in case it becomes useful later. We do not put the driver key identifier because its size is not a constant.
* Key id: `sizeof(psa_storage_uid_t)` bytes.
* Key lifetime: 4 bytes (`sizeof(psa_key_lifetime_t)`). Currently unused during recovery.
* Operation type: 1 byte. Currently unused during recovery.
* 0: destroy key.
* 1: import key.
* 2: generate key.
* 3: derive key.
* 4: import key.
* Padding: 3 bytes. Reserved for future use. Currently unused during recovery.
#### Dynamic secure element transaction file
Note that the code base already references a “transaction file” (`PSA_CRYPTO_ITS_TRANSACTION_UID` = 0xffffff54), used by dynamic secure elements (feature enabled with `MBEDTLS_PSA_CRYPTO_SE_C`). This is a deprecated feature that has not been fully implemented: when this feature is enabled, the transaction file gets written during transactions, but if it exists when PSA crypto starts, `psa_crypto_init()` fails because [recovery has never been implemented](https://github.com/ARMmbed/mbed-crypto/issues/218).
For the new kind of secure element driver, we pick a different file name to avoid any mixup.
## Testing key management in secure elements
### Instrumentation for checking the storage invariant
#### Test hook locations
When `MBEDTLS_TEST_HOOKS` is enabled, each call to `psa_its_set()` or `psa_its_remove()` also calls a test hook, passing the file UID as an argument to the hook.
When a stateful secure element driver is present in the build, we use this hook to verify that the storage respects the [storage invariant](#chosen-storage-invariant). In addition, if there is some information about key ongoing operation (set explicitly by the test function as a global variable in the test framework), the hook tests that the content of the storage is compatible with the ongoing operation.
#### Test hook behavior
The storage invariant check cannot check all keys in storage, and does not need to (for example, it would be pointless to check anything about transparent keys). It checks the following keys:
* When invoked from the test hook on a key file: on that key.
* When invoked from the test hook on the transaction file: on all the keys listed in the transaction file.
* When invoked from a test secure element: on the specified key.
#### Test hook extra data
Some tests set global variables to indicate which persistent keys they manipulate. We instrument at least some of these tests to also indicate what operation is in progress on the key. See the GitHub issues or the source code for details.
### Testing of transaction recovery
When no secure element driver is present in the build, the presence of a transaction list file during initialization is an error.
#### Recovery testing process
When the stateful test secure element driver is present in the build, we run test cases on a representative selection of states of the internal storage and the test secure element. Each test case for transaction recovery has the following form:
1. Create the initial state:
* Create a transaction list file with a certain content.
* Create key files that we want to have in the test.
* Call the secure element test driver to create keys without going throught the PSA API.
2. Call `psa_crypto_init()`. Expect success if the initial state satisfies the [storage invariant](#chosen-storage-invariant) and failure otherwise.
3. On success, check that the expected keys exist, and that keys that are expected to have been destroyed by recovery do not exist.
4. Clean up the storage and the secure element test driver's state.
#### States to test recovery on
For a given key located in a secure element, the following combination of states are possible:
* Key file: present, absent.
* Key in secure element: present, absent.
* Key in the transaction file: no, creation (import), destruction.
We test all $2 \times 2 \times 3 = 12$ possibilities, each in its own test case. In each case, call the test function that checks the storage invariant and check that its result is as expected. Then, if the storage invariant is met, follow the [recovery testing process](#recovery-testing-process).
In addition, have at least one positive test case for each creation method other than import, to ensure that we don't reject a valid value.
Note: testing of a damaged filesystem (including a filesystem that doesn't meet the invariant) is out of scope of the present document.
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@@ -0,0 +1,367 @@
# Thread-safety of the PSA subsystem
Currently, PSA Crypto API calls in Mbed TLS releases are not thread-safe.
As of Mbed TLS 3.6, an MVP for making the [PSA Crypto key management API](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html) and [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init) thread-safe has been implemented. Implementations which only ever call PSA functions from a single thread are not affected by this new feature.
Summary of recent work:
- Key Store:
- Slot states are described in the [Key slot states](#key-slot-states) section. They guarantee safe concurrent access to slot contents.
- Key slots are protected by a global mutex, as described in [Key store consistency and abstraction function](#key-store-consistency-and-abstraction-function).
- Key destruction strategy abiding by [Key destruction guarantees](#key-destruction-guarantees), with an implementation discussed in [Key destruction implementation](#key-destruction-implementation).
- `global_data` variables in `psa_crypto.c` and `psa_crypto_slot_management.c` are now protected by mutexes, as described in the [Global data](#global-data) section.
- The testing system has now been made thread-safe. Tests can now spin up multiple threads, see [Thread-safe testing](#thread-safe-testing) for details.
- Some multithreaded testing of the key management API has been added, this is outlined in [Testing-and-analysis](#testing-and-analysis).
- The solution uses the pre-existing `MBEDTLS_THREADING_C` threading abstraction.
- The core makes no additional guarantees for drivers. See [Driver policy](#driver-policy) for details.
The other functions in the PSA Crypto API are planned to be made thread-safe in future, but currently we are not testing this.
## Overview of the document
* The [Guarantees](#guarantees) section describes the properties that are followed when PSA functions are invoked by multiple threads.
* The [Usage guide](#usage-guide) section gives guidance on initializing, using and freeing PSA when using multiple threads.
* The [Current strategy](#current-strategy) section describes how thread-safety of key management and `global_data` is achieved.
* The [Testing and analysis](#testing-and-analysis) section discusses the state of our testing, as well as how this testing will be extended in future.
* The [Future work](#future-work) section outlines our long-term goals for thread-safety; it also analyses how we might go about achieving these goals.
## Definitions
*Concurrent calls*
The PSA specification defines concurrent calls as: "In some environments, an application can make calls to the Crypto API in separate threads. In such an environment, concurrent calls are two or more calls to the API whose execution can overlap in time." (See PSA documentation [here](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls).)
*Thread-safety*
In general, a system is thread-safe if any valid set of concurrent calls is handled as if the effect and return code of every call is equivalent to some sequential ordering. We implement a weaker notion of thread-safety, we only guarantee thread-safety in the circumstances described in the [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions) section.
## Guarantees
### Correctness out of the box
Building with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C` gives code which is correct; there are no race-conditions, deadlocks or livelocks when concurrently calling any set of PSA key management functions once `psa_crypto_init` has been called (see the [Initialization](#initialization) section for details on how to correctly initialize the PSA subsystem when using multiple threads).
We do not test or support calling other PSA API functions concurrently.
There is no busy-waiting in our implementation, every API call completes in a finite number of steps regardless of the locking policy of the underlying mutexes.
When only considering key management functions: Mbed TLS 3.6 abides by the minimum expectation for concurrent calls set by the PSA specification (see [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)).
#### PSA Concurrent calling conventions
These are the conventions which are planned to be added to the PSA 1.2 specification, Mbed TLS 3.6 abides by these when only considering [key management functions](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html):
> The result of two or more concurrent calls must be consistent with the same set of calls being executed sequentially in some order, provided that the calls obey the following constraints:
>
> * There is no overlap between an output parameter of one call and an input or output parameter of another call. Overlap between input parameters is permitted.
>
> * A call to `psa_destroy_key()` must not overlap with a concurrent call to any of the following functions:
> - Any call where the same key identifier is a parameter to the call.
> - Any call in a multi-part operation, where the same key identifier was used as a parameter to a previous step in the multi-part operation.
>
> * Concurrent calls must not use the same operation object.
>
> If any of these constraints are violated, the behaviour is undefined.
>
> The consistency requirement does not apply to errors that arise from resource failures or limitations. For example, errors resulting from resource exhaustion can arise in concurrent execution that do not arise in sequential execution.
>
> As an example of this rule: suppose two calls are executed concurrently which both attempt to create a new key with the same key identifier that is not already in the key store. Then:
> * If one call returns `PSA_ERROR_ALREADY_EXISTS`, then the other call must succeed.
> * If one of the calls succeeds, then the other must fail: either with `PSA_ERROR_ALREADY_EXISTS` or some other error status.
> * Both calls can fail with error codes that are not `PSA_ERROR_ALREADY_EXISTS`.
>
> If the application concurrently modifies an input parameter while a function call is in progress, the behaviour is undefined.
### Backwards compatibility
Code which was working prior to Mbed TLS 3.6 will still work. Implementations which only ever call PSA functions from a single thread, or which protect all PSA calls using a mutex, are not affected by this new feature. If an application previously worked with a 3.X version, it will still work on version 3.6.
### Supported threading implementations
Currently, the only threading library with support shipped in the code base is pthread (enabled by `MBEDTLS_THREADING_PTHREAD`). The only concurrency primitives we use are mutexes, see [Condition variables](#condition-variables) for discussion about implementing new primitives in future major releases.
Users can add support to any platform which has mutexes using the Mbed TLS platform abstraction layer (see `include/mbedtls/threading.h` for details).
We intend to ship support for other platforms including Windows in future releases.
### Key destruction guarantees
Much like all other API calls, `psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns:
1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier.
2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources.
When `psa_destroy_key` is called on a key that is in use, guarantee 2 may be violated. This is consistent with the PSA specification requirements, as destruction of a key in use is undefined.
In future versions we aim to enforce stronger requirements for key destruction, see [Long term key destruction requirements](#long-term-key-destruction-requirements) for details.
### Driver policy
The core makes no additional guarantees for drivers. Driver entry points may be called concurrently from multiple threads. Threads can concurrently call entry points using the same key, there is also no protection from destroying a key which is in use.
### Random number generators
The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`.
When using the built-in RNG implementations, i.e. when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled, querying the RNG is thread-safe (`mbedtls_psa_random_init` and `mbedtls_psa_random_seed` are only thread-safe when called while holding `mbedtls_threading_psa_rngdata_mutex`. `mbedtls_psa_random_free` is not thread-safe).
When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, it is down to the external implementation to ensure thread-safety, should threading be enabled.
## Usage guide
### Initialization
The PSA subsystem is initialized via a call to [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init). This is a thread-safe function, and multiple calls to `psa_crypto_init` are explicitly allowed. It is valid to have multiple threads each calling `psa_crypto_init` followed by a call to any PSA key management function (if the init succeeds).
### General usage
Once initialized, threads can use any PSA function if there is no overlap between their calls. All threads share the same set of keys, as soon as one thread returns from creating/loading a key via a key management API call the key can be used by any thread. If multiple threads attempt to load the same persistent key, with the same key identifier, only one thread can succeed - the others will return `PSA_ERROR_ALREADY_EXISTS`.
Applications may need careful handling of resource management errors. As explained in ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)), operations in progress can have memory related side effects. It is possible for a lack of resources to cause errors which do not arise in sequential execution. For example, multiple threads attempting to load the same persistent key can lead to some threads returning `PSA_ERROR_INSUFFICIENT_MEMORY` if the key is not currently in the key store - while trying to load a persistent key into the key store a thread temporarily reserves a free key slot.
If a mutex operation fails, which only happens if the mutex implementation fails, the error code `PSA_ERROR_SERVICE_FAILURE` will be returned. If this code is returned, execution of the PSA subsystem must be stopped. All functions which have internal mutex locks and unlocks (except for when the lock/unlock occurs in a function that has no return value) will return with this error code in this situation.
### Freeing
There is no thread-safe way to free all PSA resources. This is because any such operation would need to wait for all other threads to complete their tasks before wiping resources.
`mbedtls_psa_crypto_free` must only be called by a single thread once all threads have completed their operations.
## Current strategy
This section describes how we have implemented thread-safety. There is discussion of: techniques, internal properties for enforcing thread-safe access, how the system stays consistent and our abstraction model.
### Protected resources
#### Global data
We have added a mutex `mbedtls_threading_psa_globaldata_mutex` defined in `include/mbedtls/threading.h`, which is used to make `psa_crypto_init` thread-safe.
There are two `psa_global_data_t` structs, each with a single instance `global_data`:
* The struct in `library/psa_crypto.c` is protected by `mbedtls_threading_psa_globaldata_mutex`. The RNG fields within this struct are not protected by this mutex, and are not always thread-safe (see [Random number generators](#random-number-generators)).
* The struct in `library/psa_crypto_slot_management.c` has two fields: `key_slots` is protected as described in [Key slots](#key-slots), `key_slots_initialized` is protected by the global data mutex.
#### Mutex usage
A deadlock would occur if a thread attempts to lock a mutex while already holding it. Functions which need to be called while holding the global mutex have documentation to say this.
To avoid performance degradation, functions must hold mutexes for as short a time as possible. In particular, they must not start expensive operations (eg. doing cryptography) while holding the mutex.
#### Key slots
Keys are stored internally in a global array of key slots known as the "key store", defined in `library/psa_slot_management.c`.
##### Key slot states
Each key slot has a state variable and a `registered_readers` counter. These two variables dictate whether an operation can access a slot, and in what way the slot can be used.
There are four possible states for a key slot:
* `PSA_SLOT_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 `PSA_SLOT_FILLING` and begin to load data into the slot.
* `PSA_SLOT_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 this state.
* `PSA_SLOT_FULL`: the slot contains a key, and any thread is able to use the key after registering as a reader, increasing `registered_readers` by 1.
* `PSA_SLOT_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 (`registered_readers > 0`). No thread can register to read this slot. The slot must not be wiped until the last reader unregisters. It is during the last unregister that the contents of the slot are wiped, and the slot's state is set to `PSA_SLOT_EMPTY`.
###### Key slot state transition diagram
![](key-slot-state-transitions.png)
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. Internal functions have italicized labels. The `PSA_SLOT_PENDING_DELETION -> PSA_SLOT_EMPTY` transition can be done by any function which calls `psa_unregister_read`.
The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3Vxbd5s4EP4t%2B%2BDH5CBxf6zrJJvW7aYn7W7dFx9qZFstBg7gW379CnMxkoUtY%2BGQ%2BiVISCPQjD59mhnSU98vNg%2BRE84%2FBS7yelBxNz110IMQAEsnf9KabVZjmHnFLMJu3mhf8YxfUF6p5LVL7KKYapgEgZfgkK6cBL6PJglV50RRsKabTQOPHjV0Zuig4nnieIe1%2F2E3mWe1FjT39X8jPJsXIwPDzu4snKJx%2Fibx3HGDdaVKveup76MgSLKrxeY98tLJK%2BYl63dfc7d8sAj5iUiHH%2BBlOP338cP6i%2B37%2Ff7oV%2Fjr442aSVk53jJ%2F4R40PCKv7%2BIVuZyll%2FffhsOimsiv3OE0njvxOEKOi6K4uPszYtuzUnbzk2yLSScPTvRLCv31HCfoOXQm6Z01MbF0hGThkRIgl04cZkqf4g1yS1HVScnnaYWiBG0qVfkkPaBggZJoS5rkdzUrV1hhsUpeXlf0n1fNK6ov6pzc4mal5L1SyEWulzN0BABHSeyM%2Be671NpJaeI5cYwn9ERFwdJ30xkaKKREJifafs9v7QqjamGwqbYbbIvSBidlJ3I9qtTvu6SFoketNuJgGU3QabtMnGiGkiPttKwdcqlVfKjbiu50ju6Kugh5ToJX9NrnKTQf4SnA5M1qTUc3GJvI3jvvVV2rrCDTvrUrP4sSq6mM2GyaDsTurK2chAsMENaiBC7WcBg746UfoRmOExTtEKCy2HH9UieaGzo%2Fya5BL2wPz%2FzUmInloIhUpOsXE1h%2Bl99YYNdNZfQjFOMX5%2BdOXmpzYToLu3nR%2Bz19wLXC48uMRYpyc8lHofCbhyDKLVRMm1LZDbzMwAoxgOkSTKcxakfpIjvD3aenr6O3CfOdQ3lbOsrneK1U8BocxetyXygLo2qhZl9ojvJQEOVBt1CetpwDNBYG%2BRObRcuoXvDSU6g%2BdbA3%2Fo224wkB9QQH%2FlvD9WJhdRHXc8mQEsr2bw%2FkDzf2%2B8fh8PHzQ6exWjVeGas1kb3xrFPTX3%2FcsenVlaSLKOnp7vNgZ%2B6CehrcDe%2B%2BPv7z%2BW3qqHOkx2yL84ifUZudhZtznsKJdYrzwE5xHqiQzc%2FSoAnI2VTTDXoX1DXj1gS6CS1TJwWVES9KiIDBMCvtuozIEkEMLkciZAVFKzSeRgjtuFLsBQmfJwkCDXeYmExAwuViXBw6OWpnOVuBC12kbKUY7VosDfD4hnyYvNWbHA6zXq96POyWEzCFSkUpoNIgqEaDGkhdewVWqpZiNgNLTWHAkti6yphk237B5oA5xT6O5wLHyjcGXOVSvRi5bogVabZJQ5cqx0ItrtQrABmPkzO6nCzJRuqWFOx6YQ1xN1lzRBMNa6idQjStiNmWMdyGHi%2FdYASxB4sawCI24GwrzfLlWf%2FANo2NpqIcfy7ItAcn2mvWMfnkInvipotn0NcmAD9MQu8FLR%2Fxs%2F7uaSN2nq1hpyejMpew0pqwTzNKKjYkMZKx47tjL5j8Lvn2%2BPtFA6VyJ14Q7wj8Wb3CJbHaaq%2BDwf8wel7iuIxdDqgWvZou5Oe5ZJr0Q%2F1ae5zKS6mQQtarG5SgT6PCztuN5GiCG1u3IjnQhJSV6HrDjQ3UOdauxMRV3gmRi1UuipMo2F6OcXLwtLMQVy5jCS4IzTLoM2CxDC403xuaTdktQByXicj32nKJ%2Bym0Oh8X28e3bnltVYbX6k1D1arJOBsEibssi6t3NDR1w3YBeI4uLinUymYc9ZJwBxRujjY9CNzZuUqSjLAnlIarFj2hon4DvdPwY4Cm8MOkyhjtJUByra547orZHXCpzgKKtPSXFFCKrpKJDO3mbCP9ha%2FXK2VWn4aGJjDUHE50QTjp2Gmtxkt3NpxAhs0Y7WXe8c0O1tKZhr42eZ61NQ4PqdPbdV8dX%2FYywsvlF05yIRGorwSJPKrNaFJ6iKaxX6oryMTEGxoHSFTNvIWWpWtQszUbqpbKyqVCy1AIts6NnpC3qY4CbPohTEW9NaFS%2FtTjbwTso8IAOEeY3vzJ2gnKcLP23%2FKnMcdBQQJgKrpFc0hJFLKNbJwnvNwMp3BsWbMvqx%2F3Hye%2BH3I%2FjJHDGanEmkZf47XGGEWzFruViqMyOTI667YSxmX9hCNNHmPk2pwQYUxxBi%2FCIEsRPMtPP0M%2BipykgYM%2FCM%2BPJaT00kURXu3yfsbBMgmX1DOfn1X9GlB5FB0kIKWuAe65%2BGLvHSX0almMsLMJDCeyCeScfv6wT%2FdEAyKimUz7YFkRebtSbpNNu7IPcs6F8zEZQaIh4L0gqUvww0j7vh7F%2FW9ujL7iR%2FfmYWy1QF0KOy2JxzmWSicnvP4nF93KumPJi9n4UMmQFxOKWea550bW3W9qcrPiuCZdz4yaJ4x1gVwcXb8SyAWwDTlsQmUijIxPogmYkeL%2B3%2BJkzff%2FXEi9%2Bx8%3D).
##### Key slot access primitives
The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned. The sole reason for having an expected state parameter here is to help guarantee that our functions work as expected, this error code cannot occur without an internal coding error.
Changing a slot's state to `PSA_SLOT_EMPTY` is done via `psa_wipe_key_slot`, this function wipes the entirety of the key slot.
The reader count of a slot is incremented via `psa_register_read`, and decremented via `psa_unregister_read`. Library functions register to read a slot via the `psa_get_and_lock_key_slot_X` functions, read from the slot, then call `psa_unregister_read` to make known that they have finished reading the slot's contents.
##### Key store consistency and abstraction function
The key store is protected by a single global mutex `mbedtls_threading_key_slot_mutex`.
We maintain the consistency of the key store by ensuring that all reads and writes to `slot->state` and `slot->registered_readers` are performed under `mbedtls_threading_key_slot_mutex`. All the access primitives described above must be called while the mutex is held; there is a convenience function `psa_unregister_read_under_mutex` which wraps a call to `psa_unregister_read` in a mutex lock/unlock pair.
A thread can only traverse the key store while holding `mbedtls_threading_key_slot_mutex`, the set of keys within the key store which the thread holding the mutex can access is equivalent to the set:
{mbedtls_svc_key_id_t k : (\exists slot := &global_data.key_slots[i]) [
(slot->state == PSA_SLOT_FULL) &&
(slot->attr.id == k)]}
The union of this set and the set of persistent keys not currently loaded into slots is our abstraction function for the key store, any key not in this union does not currently exist as far as the code is concerned (even if the key is in a slot which has a `PSA_SLOT_FILLING` or `PSA_SLOT_PENDING_DELETION` state). Attempting to start using any key which is not a member of the union will result in a `PSA_ERROR_INVALID_HANDLE` error code.
##### Locking and unlocking the mutex
If a lock or unlock operation fails and this is the first failure within a function, the function will return `PSA_ERROR_SERVICE_FAILURE`. If a lock or unlock operation fails after a different failure has been identified, the status code is not overwritten.
We have defined a set of macros in `library/psa_crypto_core.h` to capture the common pattern of (un)locking the mutex and returning or jumping to an exit label upon failure.
##### Key creation and loading
To load a new key into a slot, the following internal utility functions are used:
* `psa_reserve_free_key_slot` - This function, which must be called under `mbedtls_threading_key_slot_mutex`, iterates through the key store to find a slot whose state is `PSA_SLOT_EMPTY`. If found, it reserves the slot by setting its state to `PSA_SLOT_FILLING`. If not found, it will see if there are any persistent keys loaded which do not have any readers, if there are it will kick one such key out of the key store.
* `psa_start_key_creation` - This function wraps around `psa_reserve_free_key_slot`, if a slot has been found then the slot id is set. This second step is not done under the mutex, at this point the calling thread has exclusive access to the slot.
* `psa_finish_key_creation` - After the contents of the key have been loaded (again this loading is not done under the mutex), the thread calls `psa_finish_key_creation`. This function takes the mutex, checks that the key does not exist in the key store (this check cannot be done before this stage), sets the slot's state to `PSA_SLOT_FULL` and releases the mutex. Upon success, any thread is immediately able to use the new key.
* `psa_fail_key_creation` - If there is a failure at any point in the key creation stage, this clean-up function takes the mutex, wipes the slot, and releases the mutex. Immediately after this unlock, any thread can start to use the slot for another key load.
##### Re-loading persistent keys
As described above, persistent keys can be kicked out of the key slot array provided they are not currently being used (`registered_readers == 0`). When attempting to use a persistent key that has been kicked out of a slot, the call to `psa_get_and_lock_key_slot` will see that the key is not in a slot, call `psa_reserve_free_key_slot` and load the key back into the reserved slot. This entire sequence is done during a single mutex lock, which is necessary for thread-safety (see documentation of `psa_get_and_lock_key_slot`).
If `psa_reserve_free_key_slot` cannot find a suitable slot, the key cannot be loaded back in. This will lead to a `PSA_ERROR_INSUFFICIENT_MEMORY` error.
##### Using existing keys
One-shot operations follow a standard pattern when using an existing key:
* They call one of the `psa_get_and_lock_key_slot_X` functions, which then finds the key and registers the thread as a reader.
* They operate on the key slot, usually copying the key into a separate buffer to be used by the operation. This step is not performed under the key slot mutex.
* Once finished, they call `psa_unregister_read_under_mutex`.
Multi-part and restartable operations each have a "setup" function where the key is passed in, these functions follow the above pattern. The key is copied into the `operation` object, and the thread unregisters from reading the key (the operations do not access the key slots again). The copy of the key will not be destroyed during a call to `psa_destroy_key`, the thread running the operation is responsible for deleting its copy in the clean-up. This may need to change to enforce the long term key requirements ([Long term key destruction requirements](#long-term-key-destruction-requirements)).
##### Key destruction implementation
The locking strategy here is explained in `library/psa_crypto.c`. The destroying thread (the thread calling `psa_destroy_key`) does not always wipe the key slot. The destroying thread registers to read the key, sets the slot's state to `PSA_SLOT_PENDING_DELETION`, wipes the slot from memory if the key is persistent, and then unregisters from reading the slot.
`psa_unregister_read` internally calls `psa_wipe_key_slot` if and only if the slot's state is `PSA_SLOT_PENDING_DELETION` and the slot's registered reader counter is equal to 1. This implements a "last one out closes the door" approach. The final thread to unregister from reading a destroyed key will automatically wipe the contents of the slot; no readers remain to reference the slot post deletion, so there cannot be corruption.
### 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.
To help justify that our system is linearizable, here are the linearization points/planned linearization points of each PSA call :
* Key creation functions (including `psa_copy_key`) - The linearization point for a successful call is the mutex unlock within `psa_finish_key_creation`; it is at this point that the key becomes visible to other threads. The linearization point for a failed call is the closest mutex unlock after the failure is first identified.
* `psa_destroy_key` - The linearization point for a successful destruction is the mutex unlock, the slot is now in the state `PSA_SLOT_PENDING_DELETION` meaning that the key has been destroyed. For failures, the linearization point is the same.
* `psa_purge_key`, `psa_close_key` - The linearization point is the mutex unlock after wiping the slot for a success, or unregistering for a failure.
* One shot operations - The linearization point is the final unlock of the mutex within `psa_get_and_lock_key_slot`, as that is the point in which it is decided whether or not the key exists.
* Multi-part operations - The linearization point of the key input function is the final unlock of the mutex within `psa_get_and_lock_key_slot`. All other steps have no non resource-related side effects (except for key derivation, covered in the key creation functions).
Please note that one shot operations and multi-part operations are not yet considered thread-safe, as we have not yet tested whether they rely on unprotected global resources. The key slot access in these operations is thread-safe.
## Testing and analysis
### Thread-safe testing
It is now possible for individual tests to spin up multiple threads. This work has made the global variables used in tests thread-safe. If multiple threads fail a test assert, the first failure will be reported with correct line numbers.
Although the `step` feature used in some tests is thread-safe, it may produce unexpected results for multi-threaded tests. `mbedtls_test_set_step` or `mbedtls_test_increment_step` calls within threads can happen in any order, thus may not produce the desired result when precise ordering is required.
### Current state of testing
Our testing is a work in progress. It is not feasible to run our traditional, single-threaded, tests in such a way that tests concurrency. We need to write new test suites for concurrency testing.
Our tests currently only run on pthread, we hope to expand this in the future (our API already allows this).
We run tests using [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) to detect data races. We test the key store, and test that our key slot state system is enforced. We also test the thread-safety of `psa_crypto_init`.
Currently, not every API call is tested, we also cannot feasibly test every combination of concurrent API calls. API calls can in general be split into a few categories, each category calling the same internal key management functions in the same order - it is the internal functions that are in charge of locking mutexes and interacting with the key store; we test the thread-safety of these functions.
Since we do not run every cryptographic operation concurrently, we do not test that operations are free of unexpected global variables.
### Expanding testing
Through future work on testing, it would be good to:
* For every API call, have a test which runs multiple copies of the call simultaneously.
* After implementing other threading platforms, expand the tests to these platforms.
* Have increased testing for kicking persistent keys out of slots.
* Explicitly test that all global variables are protected, for this we would need to cover every operation in a concurrent scenario while running ThreadSanitizer.
* Run tests on more threading implementations, once these implementations are supported.
### Performance
Key loading does somewhat run in parallel, deriving the key and copying it key into the slot is not done under any mutex.
Key destruction is entirely sequential, this is required for persistent keys to stop issues with re-loading keys which cannot otherwise be avoided without changing our approach to thread-safety.
## Future work
### Long term requirements
As explained previously, we eventually aim to make the entirety of the PSA API thread-safe. This will build on the work that we have already completed. This requires a full suite of testing, see [Expanding testing](#expanding-testing) for details.
### Long term performance requirements
Our plan for cryptographic operations is that they are not performed under any global mutex. One-shot operations and multi-part operations will each only hold the global mutex for finding the relevant key in the key slot, and unregistering as a reader after the operation, using their own operation-specific mutexes to guard any shared data that they use.
We aim to eventually replace some/all of the mutexes with RWLocks, if possible.
### Long term key destruction requirements
The [PSA Crypto Key destruction specification](https://arm-software.github.io/psa-api/crypto/1.1/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.
Here are our long term key destruction goals:
`psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns:
1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier.
2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources.
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.
#### Condition variables
It would be ideal to add these to a future major version; we cannot add these as requirements to the default `MBEDTLS_THREADING_C` for backwards compatibility reasons.
Condition variables would enable us to fulfil the final requirement in [Long term key destruction requirements](#long-term-key-destruction-requirements). Destruction would then work as follows:
* When a thread calls `psa_destroy_key`, they continue as normal until the `psa_unregister_read` call.
* Instead of calling `psa_unregister_read`, the thread waits until the condition `slot->registered_readers == 1` is true (the destroying thread is the final reader).
* At this point, the destroying thread directly calls `psa_wipe_key_slot`.
A few changes are needed for this to follow our destruction requirements:
* Multi-part operations will need to remain registered as readers of their key slot until their copy of the key is destroyed, i.e. at the end of the finish/abort call.
* The functionality where `psa_unregister_read` can wipe the key slot will need to be removed, slot wiping is now only done by the destroying/wiping thread.
### Protecting operation contexts
Currently, we rely on the crypto service to ensure that the same operation is not invoked concurrently. This abides by the PSA Crypto API Specification ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)).
Concurrent access to the same operation object 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.
If, in future, we want to protect against this within the library then operations will require a status field protected by a global mutex. On entry, API calls would check the state and return an error if the state is ACTIVE. If the state is INACTIVE, then the call will set the state to ACTIVE, do the operation section and then restore the state to INACTIVE before returning.
### Future driver work
A future policy we may wish to enforce for drivers is:
* 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.
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 there are several drivers with circular dependencies. That is, Driver A makes a call that is dispatched to Driver B; upon executing this call Driver B makes a call that is dispatched to Driver A. For example Driver A does CCM, which calls driver B to do CBC-MAC, which in turn calls Driver A to perform AES.
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 would be non-thread-safe if the `thread-safe` property is set to true.
To make re-entrancy 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 fewer guarantees from the core and need to implement more complex logic. We can reasonably expect them to be more flexible in terms of re-entrancy 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 here.
@@ -1,6 +1,6 @@
# Mbed Crypto driver interface test strategy
# Mbed TLS driver interface test strategy
This document describes the test strategy for the driver interfaces in Mbed Crypto. Mbed Crypto has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed Crypto itself; testing drivers is out of scope.
This document describes the test strategy for the driver interfaces in Mbed TLS. Mbed TLS has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed TLS itself; testing drivers is out of scope.
The driver interfaces are standardized through PSA Cryptography functional specifications.
@@ -16,9 +16,9 @@ Drivers exposing this interface need to be registered at compile time by declari
#### Dynamic secure element driver interface
The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed TLS and one or more third-party drivers.
The SE interface consists of one function provided by Mbed Crypto (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed Crypto, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
The SE interface consists of one function provided by Mbed TLS (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed TLS, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
### SE driver interface unit tests
@@ -57,7 +57,7 @@ For each API function that can lead to a driver call (more precisely, for each d
#### SE driver outputs
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed Crypto handles the outputs.
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed TLS handles the outputs.
* Correct outputs.
* Incorrect outputs such as an invalid output length.
@@ -47,7 +47,7 @@ The PSA subsystem provides storage on top of the PSA trusted storage interface.
* [Storage transaction file](#storage-transaction-resumption).
* [Driver state files](#driver-state-files).
For a more detailed description, refer to the [Mbed Crypto storage specification](../mbed-crypto-storage-specification.md).
For a more detailed description, refer to the [Mbed TLS storage specification](../mbed-crypto-storage-specification.md).
In addition, Mbed TLS includes an implementation of the PSA trusted storage interface on top of C stdio. This document addresses the test strategy for [PSA ITS over file](#psa-its-over-file) in a separate section below.
+9 -3
View File
@@ -30,17 +30,23 @@ Each test case has a description which succinctly describes for a human audience
#### SSL test case descriptions
Each test case in `ssl-opt.sh` has a description which succinctly describes for a human audience what the test does. The test description is the first parameter to `run_tests`.
Each test case in `ssl-opt.sh` has a description which succinctly describes for a human audience what the test does. The test description is the first parameter to `run_test`.
The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, the description must be written on the same line as `run_test`, in double quotes, for the sake of `check_test_cases.py`.
### SSL cipher suite tests
Each test case in `compat.sh` has a description which succinctly describes for a human audience what the test does. The test description is `$TITLE` defined in `run_client`.
The same rules and guidelines apply as for [unit test descriptions](#unit-test-descriptions). In addition, failure cause in `compat.sh` is not classified as `ssl-opt.sh`, so the information of failed log files are followed as prompt.
## Running tests
### Outcome file
#### Generating an outcome file
Unit tests and `ssl-opt.sh` record the outcome of each test case in a **test outcome file**. This feature is enabled if the environment variable `MBEDTLS_TEST_OUTCOME_FILE` is set. Set it to the path of the desired file.
Unit tests, `ssl-opt.sh` and `compat.sh` record the outcome of each test case in a **test outcome file**. This feature is enabled if the environment variable `MBEDTLS_TEST_OUTCOME_FILE` is set. Set it to the path of the desired file.
If you run `all.sh --outcome-file test-outcome.csv`, this collects the outcome of all the test cases in `test-outcome.csv`.
@@ -52,7 +58,7 @@ The outcome file has 6 fields:
* **Platform**: a description of the platform, e.g. `Linux-x86_64` or `Linux-x86_64-gcc7-msan`.
* **Configuration**: a unique description of the configuration (`mbedtls_config.h`).
* **Test suite**: `test_suite_xxx` or `ssl-opt`.
* **Test suite**: `test_suite_xxx`, `ssl-opt` or `compat`.
* **Test case**: the description of the test case.
* **Result**: one of `PASS`, `SKIP` or `FAIL`.
* **Cause**: more information explaining the result.
+10 -227
View File
@@ -4,17 +4,8 @@ TLS 1.3 support
Overview
--------
Mbed TLS provides a partial implementation of the TLS 1.3 protocol defined in
the "Support description" section below. The TLS 1.3 support enablement
is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option.
The development of the TLS 1.3 protocol is based on the TLS 1.3 prototype
located at https://github.com/hannestschofenig/mbedtls. The prototype is
itself based on a version of the development branch that we aim to keep as
recent as possible (ideally the head) by merging regularly commits of the
development branch into the prototype. The section "Prototype upstreaming
status" below describes what remains to be upstreamed.
Mbed TLS provides an implementation of the TLS 1.3 protocol. The TLS 1.3 support
may be enabled using the MBEDTLS_SSL_PROTO_TLS1_3 configuration option.
Support description
-------------------
@@ -26,14 +17,14 @@ Support description
- Mbed TLS supports ECDHE key establishment.
- Mbed TLS does not support DHE key establishment.
- Mbed TLS supports DHE key establishment.
- Mbed TLS supports pre-shared keys for key establishment, pre-shared keys
provisioned externally as well as provisioned via the ticket mechanism.
- Mbed TLS supports session resumption via the ticket mechanism.
- Mbed TLS does not support sending or receiving early data (0-RTT data).
- Mbed TLS supports sending and receiving early data (0-RTT data).
- Supported cipher suites: depends on the library configuration. Potentially
all of them:
@@ -51,7 +42,7 @@ Support description
| signature_algorithms | YES |
| use_srtp | no |
| heartbeat | no |
| apln | YES |
| alpn | YES |
| signed_certificate_timestamp | no |
| client_certificate_type | no |
| server_certificate_type | no |
@@ -59,7 +50,7 @@ Support description
| key_share | YES |
| pre_shared_key | YES |
| psk_key_exchange_modes | YES |
| early_data | no |
| early_data | YES |
| cookie | no |
| supported_versions | YES |
| certificate_authorities | no |
@@ -71,7 +62,8 @@ Support description
Potentially all ECDHE groups:
secp256r1, x25519, secp384r1, x448 and secp521r1.
Finite field groups (DHE) are not supported.
Potentially all DHE groups:
ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144 and ffdhe8192.
- Supported signature algorithms (both for certificates and CertificateVerify):
depends on the library configuration.
@@ -86,17 +78,11 @@ Support description
- Supported versions:
- TLS 1.2 and TLS 1.3 with version negotiation on the client side, not server
side.
- TLS 1.2 and TLS 1.3 with version negotiation on client and server side.
- TLS 1.2 and TLS 1.3 can be enabled in the build independently of each
other.
- If both TLS 1.3 and TLS 1.2 are enabled at build time, only one of them can
be configured at runtime via `mbedtls_ssl_conf_{min,max}_tls_version` for a
server endpoint. Otherwise, `mbedtls_ssl_setup` will raise
`MBEDTLS_ERR_SSL_BAD_CONFIG` error.
- Compatibility with existing SSL/TLS build options:
The TLS 1.3 implementation is compatible with nearly all TLS 1.2
@@ -111,7 +97,7 @@ Support description
| Mbed TLS configuration option | Support |
| ---------------------------------------- | ------- |
| MBEDTLS_SSL_ALL_ALERT_MESSAGES | no |
| MBEDTLS_SSL_ALL_ALERT_MESSAGES | yes |
| MBEDTLS_SSL_ASYNC_PRIVATE | no |
| MBEDTLS_SSL_CONTEXT_SERIALIZATION | no |
| MBEDTLS_SSL_DEBUG_ALL | no |
@@ -173,33 +159,6 @@ Support description
TLS 1.3 specification.
Prototype upstreaming status
----------------------------
The following parts of the TLS 1.3 prototype remain to be upstreamed:
- Sending (client) and receiving (server) early data (0-RTT data).
- New TLS Message Processing Stack (MPS)
The TLS 1.3 prototype is developed alongside a rewrite of the TLS messaging layer,
encompassing low-level details such as record parsing, handshake reassembly, and
DTLS retransmission state machine.
MPS has the following components:
- Layer 1 (Datagram handling)
- Layer 2 (Record handling)
- Layer 3 (Message handling)
- Layer 4 (Retransmission State Machine)
- Reader (Abstracted pointer arithmetic and reassembly logic for incoming data)
- Writer (Abstracted pointer arithmetic and fragmentation logic for outgoing data)
Of those components, the following have been upstreamed
as part of `MBEDTLS_SSL_PROTO_TLS1_3`:
- Reader ([`library/mps_reader.h`](../../library/mps_reader.h))
Coding rules checklist for TLS 1.3
----------------------------------
@@ -272,10 +231,6 @@ TLS 1.3 specific coding rules:
- the macro to check for data when reading from an input buffer
`MBEDTLS_SSL_CHK_BUF_READ_PTR`.
These macros were introduced after the prototype was written thus are
likely not to be used in prototype where we now would use them in
development.
The three first types, MBEDTLS_BYTE_{0-8}, MBEDTLS_PUT_UINT{8|16|32|64}_BE
and MBEDTLS_GET_UINT{8|16|32|64}_BE improve the readability of the code and
reduce the risk of writing or reading bytes in the wrong order.
@@ -478,175 +433,3 @@ outbound message on server side as well.
* state change: the state change is done in the main state handler to ease
the navigation of the state machine transitions.
Writing and reading early or 0-RTT data
---------------------------------------
An application function to write and send a buffer of data to a server through
TLS may plausibly look like:
```
int write_data( mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written )
{
*data_written = 0;
while( *data_written < data_to_write_len )
{
ret = mbedtls_ssl_write( ssl, data_to_write + *data_written,
data_to_write_len - *data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_written += ret;
}
return( 0 );
}
```
where ssl is the SSL context to use, data_to_write the address of the data
buffer and data_to_write_len the number of data bytes. The handshake may
not be completed, not even started for the SSL context ssl when the function is
called and in that case the mbedtls_ssl_write() API takes care transparently of
completing the handshake before to write and send data to the server. The
mbedtls_ssl_write() may not been able to write and send all data in one go thus
the need for a loop calling it as long as there are still data to write and
send.
An application function to write and send early data and only early data,
data sent during the first flight of client messages while the handshake is in
its initial phase, would look completely similar but the call to
mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
```
int write_early_data( mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written )
{
*data_written = 0;
while( *data_written < data_to_write_len )
{
ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written,
data_to_write_len - *data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_written += ret;
}
return( 0 );
}
```
Note that compared to write_data(), write_early_data() can also return
MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
specifically by the user of write_early_data(). A fresh SSL context (typically
just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
be expected when calling `write_early_data`.
All together, code to write and send a buffer of data as long as possible as
early data and then as standard post-handshake application data could
plausibly look like:
```
ret = write_early_data( ssl, data_to_write, data_to_write_len,
&early_data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
{
goto error;
}
ret = write_data( ssl, data_to_write + early_data_written,
data_to_write_len - early_data_written, &data_written );
if( ret < 0 )
goto error;
data_written += early_data_written;
```
Finally, taking into account that the server may reject early data, application
code to write and send a buffer of data could plausibly look like:
```
ret = write_early_data( ssl, data_to_write, data_to_write_len,
&early_data_written );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
{
goto error;
}
/*
* Make sure the handshake is completed as it is a requisite to
* mbedtls_ssl_get_early_data_status().
*/
while( !mbedtls_ssl_is_handshake_over( ssl ) )
{
ret = mbedtls_ssl_handshake( ssl );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
goto error;
}
}
ret = mbedtls_ssl_get_early_data_status( ssl );
if( ret < 0 )
goto error;
if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED )
early_data_written = 0;
ret = write_data( ssl, data_to_write + early_data_written,
data_to_write_len - early_data_written, &data_written );
if( ret < 0 )
goto error;
data_written += early_data_written;
```
Basically, the same holds for reading early data on the server side without the
complication of possible rejection. An application function to read early data
into a given buffer could plausibly look like:
```
int read_early_data( mbedtls_ssl_context *ssl,
unsigned char *buffer,
size_t buffer_size,
size_t *data_len )
{
*data_len = 0;
while( *data_len < buffer_size )
{
ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len,
buffer_size - *data_len );
if( ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
return( ret );
}
*data_len += ret;
}
return( 0 );
}
```
with again calls to read_early_data() expected to be done with a fresh SSL
context.
+460
View File
@@ -0,0 +1,460 @@
This document explains how to create builds of Mbed TLS where some
cryptographic mechanisms are provided only by PSA drivers (that is, no
built-in implementation of those algorithms), from a user's perspective.
This is useful to save code size for people who are using either a hardware
accelerator, or an alternative software implementation that is more
aggressively optimized for code size than the default one in Mbed TLS.
General considerations
----------------------
This document assumes that you already have a working driver.
Otherwise, please see the [PSA driver example and
guide](psa-driver-example-and-guide.md) for information on writing a
driver.
In order to have some mechanism provided only by a driver, you'll want
the following compile-time configuration options enabled:
- `MBEDTLS_PSA_CRYPTO_C` (enabled by default) - this enables PSA Crypto.
- `MBEDTLS_USE_PSA_CRYPTO` (disabled by default) - this makes PK, X.509 and
TLS use PSA Crypto. You need to enable this if you're using PK, X.509 or TLS
and want them to have access to the algorithms provided by your driver. (See
[the dedicated document](use-psa-crypto.md) for details.)
- `MBEDTLS_PSA_CRYPTO_CONFIG` (disabled by default) - this enables
configuration of cryptographic algorithms using `PSA_WANT` macros in
`include/psa/crypto_config.h`. See [Conditional inclusion of cryptographic
mechanism through the PSA API in Mbed
TLS](proposed/psa-conditional-inclusion-c.md) for details.
In addition, for each mechanism you want provided only by your driver:
- Define the corresponding `PSA_WANT` macro in `psa/crypto_config.h` - this
means the algorithm will be available in the PSA Crypto API.
- Define the corresponding `MBEDTLS_PSA_ACCEL` in your build. This could be
defined in `psa/crypto_config.h` or your compiler's command line. This
informs the PSA code that an accelerator is available for this mechanism.
- Undefine / comment out the corresponding `MBEDTLS_xxx_C` macro in
`mbedtls/mbedtls_config.h`. This ensures the built-in implementation is not
included in the build.
For example, if you want SHA-256 to be provided only by a driver, you'll want
`PSA_WANT_ALG_SHA_256` and `MBEDTLS_PSA_ACCEL_SHA_256` defined, and
`MBEDTLS_SHA256_C` undefined.
In addition to these compile-time considerations, at runtime you'll need to
make sure you call `psa_crypto_init()` before any function that uses the
driver-only mechanisms. Note that this is already a requirement for any use of
the PSA Crypto API, as well as for use of the PK, X.509 and TLS modules when
`MBEDTLS_USE_PSA_CRYPTO` is enabled, so in most cases your application will
already be doing this.
Mechanisms covered
------------------
For now, only the following (families of) mechanisms are supported:
- hashes: SHA-3, SHA-2, SHA-1, MD5, etc.
- elliptic-curve cryptography (ECC): ECDH, ECDSA, EC J-PAKE, ECC key types.
- finite-field Diffie-Hellman: FFDH algorithm, DH key types.
- 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
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.
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`,
`SHA_1`, `SHA_224`, `SHA_256`, `SHA_384`, `SHA_512`, `SHA3_224`, `SHA3_256`,
`SHA3_384`, `SHA3_512`.
In such a build, all crypto operations (via the PSA Crypto API, or non-PSA
APIs), as well as X.509 and TLS, will work as usual, except that direct calls
to low-level hash APIs (`mbedtls_sha256()` etc.) are not possible for the
modules that are disabled.
You need to call `psa_crypto_init()` before any crypto operation that uses
a hash algorithm that is provided only by a driver, as mentioned in [General
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
`mbedtls/config_adjust_legacy_crypto.h`.
### HMAC
In addition to accelerated hash operations, it is also possible to accelerate
HMAC by enabling and accelerating:
- HMAC algorithm and key type, i.e. `[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_HMAC` and
`[PSA_WANT|MBEDTLS_PSA_ACCEL]KEY_TYPE_HMAC`.
- Required hash algorithm(s) as explained in [Hashes](#hashes) section.
In such a build it is possible to disable legacy HMAC support by disabling
`MBEDTLS_MD_C` and still getting crypto operations, X.509 and TLS to work as
usual. Exceptions are:
- As mentioned in [Hashes](#hashes) direct calls to legacy lo-level hash APIs
(`mbedtls_sha256()` etc.) will not be possible for the legacy modules that
are disabled.
- Legacy HMAC support (`mbedtls_md_hmac_xxx()`) won't be possible.
- `MBEDTLS_PKCS[5|7]_C`, `MBEDTLS_HMAC_DRBG_C` and `MBEDTLS_HKDF_C` since they
depend on the legacy implementation of HMAC.
- disabling HMAC_DRBG_C cause deterministic ECDSA (i.e.
`MBEDTLS_DETERMINISTIC_ECDSA` on the legacy side and
`PSA_WANT_ALG_DETERMINISTIC_ECDSA` on the PSA one) to be not available.
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
- you have driver support for all ECC curves that are enabled (that is, for
each `PSA_WANT_ECC_xxx` macro enabled, the corresponding
`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
`MBEDTLS_PSA_ACCEL_ALG_ECDSA` is enabled;
- enable `PSA_WANT_ALG_JPAKE` without `MBEDTLS_ECJPAKE_C`, provided
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
In addition, if:
- none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`, `MBEDTLS_ECJPAKE_C` are enabled
(see conditions above), and
- you have driver support for all enabled ECC key pair operations - that is,
for each `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx` macro enabled, the
corresponding `MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_xxx` macros is also
enabled,
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 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`.
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).
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
`mbedtls/build_info.h` where xxx can take the same values as for
`MBEDTLS_ECP_DP_xxx` macros.
Note that for externally-provided drivers, the integrator is responsible for
ensuring the appropriate `MBEDTLS_PSA_ACCEL_xxx` macros are defined. However,
for the p256-m driver that's provided with the library, those macros are
automatically defined when enabling `MBEDTLS_PSA_P256M_DRIVER_ENABLED`.
### Limitations regarding fully removing `ecp.c`
A limited subset of `ecp.c` will still be automatically re-enabled if any of
the following is enabled:
- `MBEDTLS_PK_PARSE_EC_COMPRESSED` - support for parsing ECC keys where the
public part is in compressed format;
- `MBEDTLS_PK_PARSE_EC_EXTENDED` - support for parsing ECC keys where the
curve is identified not by name, but by explicit parameters;
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE` - support for deterministic
derivation of an ECC keypair with `psa_key_derivation_output_key()`.
Note: when any of the above options is enabled, a subset of `ecp.c` will
automatically be included in the build in order to support it. Therefore
you can still disable `MBEDTLS_ECP_C` in `mbedtls_config.h` and this will
result in some code size savings, but not as much as when none of the
above features are enabled.
We do have plans to support each of these with `ecp.c` fully removed in the
future, however there is no established timeline. If you're interested, please
let us know, so we can take it into consideration in our planning.
### Limitations regarding restartable / interruptible ECC operations
At the moment, there is no driver support for interruptible operations
(see `psa_sign_hash_start()` + `psa_sign_hash_complete()` etc.) so as a
consequence these are not supported in builds without `MBEDTLS_ECDSA_C`.
Similarly, there is no PSA support for interruptible ECDH operations so these
are not supported without `ECDH_C`. See also limitations regarding
restartable operations with `MBEDTLS_USE_PSA_CRYPTO` in [its
documentation](use-psa-crypto.md).
Again, we have plans to support this in the future but not with an established
timeline, please let us know if you're interested.
### Limitations regarding "mixed" builds (driver and built-in)
In order for a build to be driver-only (no built-in implementation), all the
requested algorithms, key types (key operations) and curves must be
accelerated (plus a few other restrictions, see "Limitations regarding fully
removing `ecp.c`" above). However, what if you have an accelerator that only
supports some algorithms, some key types (key operations), or some curves, but
want to have more enabled in you build?
It is possible to have acceleration for only a subset of the requested
algorithms. In this case, the built-in implementation of the accelerated
algorithms will be disabled, provided all the requested curves and key types
that can be used with this algorithm are also declared as accelerated.
There is very limited support for having acceleration for only a subset of the
requested key type operations. The only configuration that's tested is that of
a driver accelerating `PUBLIC_KEY`, `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`,
`KEY_PAIR_EXPORT` but not `KEY_PAIR_GENERATE`. (Note: currently the driver
interface does not support `KEY_PAIR_DERIVE`.)
There is limited support for having acceleration for only a subset of the
requested curves. In such builds, only the PSA API is currently tested and
working; there are known issues in PK, and X.509 and TLS are untested.
Finite-field Diffie-Hellman
---------------------------
Support is pretty similar to the "Elliptic-curve cryptography (ECC)" section
above.
Key management and usage can be enabled by means of the usual `PSA_WANT` +
`MBEDTLS_PSA_ACCEL` pairs:
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_PUBLIC_KEY`;
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_BASIC`;
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_IMPORT`;
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_EXPORT`;
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_GENERATE`;
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`).
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.
+11 -2
View File
@@ -80,9 +80,18 @@ If a feature is not requested for inclusion in the PSA Crypto configuration file
#### Configuration symbols for key types
For each constant or constructor macro of the form `PSA_KEY_TYPE_xxx`, the symbol **`PSA_WANT_KEY_TYPE_xxx`** indicates that support for this key type is desired.
For most constant or constructor macros of the form `PSA_KEY_TYPE_xxx`, the symbol **`PSA_WANT_KEY_TYPE_xxx`** indicates that support for this key type is desired.
For asymmetric cryptography, `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR` determines whether private-key operations are desired, and `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY` determines whether public-key operations are desired. `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR` implicitly enables `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY`: there is no way to only include private-key operations (which typically saves little code).
As an exception, starting in Mbed TLS 3.5.0, for `KEY_PAIR` types (that is, private keys for asymmetric cryptography), the feature selection is more fine-grained, with an additional suffix:
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options is enabled.
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_IMPORT` enables support for `psa_import_key` to import a key of that type.
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type.
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type.
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_EXPORT` enables support for `psa_export_key` to export a key of that type.
For asymmetric cryptography, `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` determines whether private-key operations are desired, and `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY` determines whether public-key operations are desired. `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` implicitly enables `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY`, as well as support for `psa_export_public_key` on the private key: there is no way to only include private-key operations (which typically saves little code).
Note: the implementation is always free to include support for more than what was explicitly requested. (For example, as of Mbed TLS 3.5.0, `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` implicitly enables import and export support for that key type, but this may not be the case in future versions.) Applications should always request support for all operations they need, rather than rely on them being implicitly enabled by the implementation. The only thing that is documented and guaranteed in the future is as follows: `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` -> `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` -> `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY`.
#### Configuration symbols for elliptic curves
+2 -1
View File
@@ -2,12 +2,13 @@ PSA Cryptoprocessor driver developer's guide
============================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
This document describes how to write drivers of cryptoprocessors such as accelerators and secure elements for the PSA cryptography subsystem of Mbed TLS.
This document focuses on behavior that is specific to Mbed TLS. For a reference of the interface between Mbed TLS and drivers, refer to the [PSA Cryptoprocessor Driver Interface specification](psa-driver-interface.html).
The interface is not fully implemented in Mbed TLS yet and is disabled by default. You can enable the experimental work in progress by setting `MBEDTLS_PSA_CRYPTO_DRIVERS` in the compile-time configuration. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code when `MBEDTLS_PSA_CRYPTO_DRIVERS` is enabled.
The interface is not fully implemented in Mbed TLS yet. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code.
## Introduction
+4 -10
View File
@@ -2,10 +2,11 @@ Building Mbed TLS with PSA cryptoprocessor drivers
==================================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
This document describes how to build Mbed TLS with additional cryptoprocessor drivers that follow the PSA cryptoprocessor driver interface.
The interface is not fully implemented in Mbed TLS yet and is disabled by default. You can enable the experimental work in progress by setting `MBEDTLS_PSA_CRYPTO_DRIVERS` in the compile-time configuration. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code when `MBEDTLS_PSA_CRYPTO_DRIVERS` is enabled.
The interface is not fully implemented in Mbed TLS yet. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code.
## Introduction
@@ -19,21 +20,14 @@ Concretely speaking, a driver consists of one or more **driver description files
To build Mbed TLS with drivers:
1. Activate `MBEDTLS_PSA_CRYPTO_DRIVERS` in the library configuration.
```
cd /path/to/mbedtls
scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
```
2. Pass the driver description files through the Make variable `PSA_DRIVERS` when building the library.
1. Pass the driver description files through the Make variable `PSA_DRIVERS` when building the library.
```
cd /path/to/mbedtls
make PSA_DRIVERS="/path/to/acme/driver.json /path/to/nadir/driver.json" lib
```
3. Link your application with the implementation of the driver functions.
2. Link your application with the implementation of the driver functions.
```
cd /path/to/application
+305 -23
View File
@@ -5,6 +5,8 @@ This document describes an interface for cryptoprocessor drivers in the PSA cryp
This specification is work in progress and should be considered to be in a beta stage. There is ongoing work to implement this interface in Mbed TLS, which is the reference implementation of the PSA Cryptography API. At this stage, Arm does not expect major changes, but minor changes are expected based on experience from the first implementation and on external feedback.
For a practical guide, with a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
## Introduction
### Purpose of the driver interface
@@ -301,25 +303,289 @@ TODO
TODO
#### Operation family `"key_derivation"`
### Driver entry points for key derivation
This family requires the following type and entry points:
Key derivation is more complex than other multipart operations for several reasons:
* Type `"key_derivation_operation_t"`: the type of a key derivation operation context.
* `"key_derivation_setup"`: called by `psa_key_derivation_setup()`.
* `"key_derivation_set_capacity"`: called by `psa_key_derivation_set_capacity()`. The core will always enforce the capacity, therefore this function does not need to do anything for algorithms where the output stream only depends on the effective generated length and not on the capacity.
* `"key_derivation_input_bytes"`: called by `psa_key_derivation_input_bytes()` and `psa_key_derivation_input_key()`. For transparent drivers, when processing a call to `psa_key_derivation_input_key()`, the core always calls the applicable driver's `"key_derivation_input_bytes"` entry point.
* `"key_derivation_input_integer"`: called by `psa_key_derivation_input_integer()`.
* `"key_derivation_input_key"` (opaque drivers only)
* `"key_derivation_output_bytes"`: called by `psa_key_derivation_output_bytes()`; also by `psa_key_derivation_output_key()` for transparent drivers.
* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()` for transparent drivers when deriving an asymmetric key pair, and also for opaque drivers.
* `"key_derivation_verify_bytes"` (opaque drivers only).
* `"key_derivation_verify_key"` (opaque drivers only).
* `"key_derivation_abort"`: called by all key derivation functions of the PSA Cryptography API.
* There are multiple inputs and outputs.
* Multiple drivers can be involved. This happens when an operation combines a key agreement and a subsequent symmetric key derivation, each of which can have independent drivers. This also happens when deriving an asymmetric key, where processing the secret input and generating the key output might involve different drivers.
* When multiple drivers are involved, they are not always independent: if the secret input is managed by an opaque driver, it might not allow the core to retrieve the intermediate output and pass it to another driver.
* The involvement of an opaque driver cannot be determined as soon as the operation is set up (since `psa_key_derivation_setup()` does not determine the key input).
TODO: key input and output for opaque drivers; deterministic key generation for transparent drivers
#### Key derivation driver dispatch logic
TODO
The core decides whether to dispatch a key derivation operation to a driver based on the location associated with the input step `PSA_KEY_DERIVATION_INPUT_SECRET`.
1. If this step is passed via `psa_key_derivation_input_key()` for a key in a secure element:
* If the driver for this secure element implements the `"key_derivation"` family for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
Note that for all currently specified algorithms, the key type for the secret input does not matter.
* Otherwise the core calls the secure element driver's [`"export_key"`](#key-management-with-opaque-drivers) entry point.
2. Otherwise ([or on fallback?](#fallback-for-key-derivation-in-opaque-drivers)), if there is a transparent driver for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
3. Otherwise, or on fallback, the core uses its built-in implementation.
#### Summary of entry points for the operation family `"key_derivation"`
A key derivation driver has the following entry points:
* `"key_derivation_setup"` (mandatory): always the first entry point to be called. This entry point provides the [initial inputs](#key-derivation-driver-initial-inputs). See [“Key derivation driver setup”](#key-derivation-driver-setup).
* `"key_derivation_input_step"` (mandatory if the driver supports a key derivation algorithm with long inputs, otherwise ignored): provide an extra input for the key derivation. This entry point is only mandatory in drivers that support algorithms that have extra inputs. See [“Key derivation driver long inputs”](#key-derivation-driver-long-inputs).
* `"key_derivation_output_bytes"` (mandatory): derive cryptographic material and output it. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
* `"key_derivation_output_key"`, `"key_derivation_verify_bytes"`, `"key_derivation_verify_key"` (optional, opaque drivers only): derive key material which remains inside the same secure element. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
* `"key_derivation_set_capacity"` (mandatory for opaque drivers that implement `"key_derivation_output_key"` for “cooked”, i.e. non-raw-data key types; ignored for other opaque drivers; not permitted for transparent drivers): update the capacity policy on the operation. See [“Key derivation driver operation capacity”](#key-derivation-driver-operation-capacity).
* `"key_derivation_abort"` (mandatory): always the last entry point to be called.
For naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the `"key_derivation"` entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections:
```
typedef ... acme_key_derivation_operation_t;
psa_status_t acme_key_derivation_abort(acme_key_derivation_operation_t *operation);
```
#### Key derivation driver initial inputs
The core conveys the initial inputs for a key derivation via an opaque data structure of type `psa_crypto_driver_key_derivation_inputs_t`.
```
typedef ... psa_crypto_driver_key_derivation_inputs_t; // implementation-specific type
```
A driver receiving an argument that points to a `psa_crypto_driver_key_derivation_inputs_t` can retrieve its contents by calling one of the type-specific functions below. To determine the correct function, the driver can call `psa_crypto_driver_key_derivation_get_input_type()`.
```
enum psa_crypto_driver_key_derivation_input_type_t {
PSA_KEY_DERIVATION_INPUT_TYPE_INVALID = 0,
PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED,
PSA_KEY_DERIVATION_INPUT_TYPE_BYTES,
PSA_KEY_DERIVATION_INPUT_TYPE_KEY,
PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER,
// Implementations may add other values, and may freely choose the
// numerical values for each identifer except as explicitly specified
// above.
};
psa_crypto_driver_key_derivation_input_type_t psa_crypto_driver_key_derivation_get_input_type(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step);
```
The function `psa_crypto_driver_key_derivation_get_input_type()` determines whether a given step is present and how to access its value:
* `PSA_KEY_DERIVATION_INPUT_TYPE_INVALID`: the step is invalid for the algorithm of the operation that the inputs are for.
* `PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED`: the step is optional for the algorithm of the operation that the inputs are for, and has been omitted.
* `PSA_KEY_DERIVATION_INPUT_TYPE_BYTES`: the step is valid and present and is a transparent byte string. Call `psa_crypto_driver_key_derivation_get_input_size()` to obtain the size of the input data. Call `psa_crypto_driver_key_derivation_get_input_bytes()` to make a copy of the input data (design note: [why a copy?](#key-derivation-inputs-and-buffer-ownership)).
* `PSA_KEY_DERIVATION_INPUT_TYPE_KEY`: the step is valid and present and is a byte string passed via a key object. Call `psa_crypto_driver_key_derivation_get_input_key()` to obtain a pointer to the key context.
* `PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER`: the step is valid and present and is an integer. Call `psa_crypto_driver_key_derivation_get_input_integer()` to retrieve the integer value.
```
psa_status_t psa_crypto_driver_key_derivation_get_input_size(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
size_t *size);
psa_status_t psa_crypto_driver_key_derivation_get_input_bytes(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
psa_status_t psa_crypto_driver_key_derivation_get_input_key(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
const psa_key_attributes_t *attributes,
uint8_t** p_key_buffer, size_t *key_buffer_size);
psa_status_t psa_crypto_driver_key_derivation_get_input_integer(
const psa_crypto_driver_key_derivation_inputs_t *inputs,
psa_key_derivation_step_t step,
uint64_t *value);
```
The get-data functions take the following parameters:
* The first parameter `inputs` must be a pointer passed by the core to a key derivation driver setup entry point which has not returned yet.
* The `step` parameter indicates the input step whose content the driver wants to retrieve.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_size`, the core sets `*size` to the size of the specified input in bytes.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_bytes`, the core fills the first *N* bytes of `buffer` with the specified input and sets `*buffer_length` to *N*, where *N* is the length of the input in bytes. The value of `buffer_size` must be at least *N*, otherwise this function fails with the status `PSA_ERROR_BUFFER_TOO_SMALL`.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_key`, the core sets `*key_buffer` to a pointer to a buffer containing the key context and `*key_buffer_size` to the size of the key context in bytes. The key context buffer remains valid for the duration of the driver entry point. If the driver needs to access the key context after the current entry point returns, it must make a copy of the key context.
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_integer`, the core sets `*value` to the value of the specified input.
These functions can return the following statuses:
* `PSA_SUCCESS`: the call succeeded and the requested value has been copied to the output parameter (`size`, `buffer`, `value` or `p_key_buffer`) and if applicable the size of the value has been written to the applicable parameter (`buffer_length`, `key_buffer_size`).
* `PSA_ERROR_DOES_NOT_EXIST`: the input step is valid for this particular algorithm, but it is not part of the initial inputs. This is not a fatal error. The driver will receive the input later as a [long input](#key-derivation-driver-long-inputs).
* `PSA_ERROR_INVALID_ARGUMENT`: the input type is not compatible with this function or was omitted. Call `psa_crypto_driver_key_derivation_get_input_type()` to find out the actual type of this input step. This is not a fatal error and the driver can, for example, subsequently call the appropriate function on the same step.
* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_key_derivation_get_input_bytes` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_key_derivation_get_input_size` to obtain the required size.
* The core may return other errors such as `PSA_ERROR_CORRUPTION_DETECTED` or `PSA_ERROR_COMMUNICATION_FAILURE` to convey implementation-specific error conditions. Portable drivers should treat such conditions as fatal errors.
#### Key derivation driver setup
A key derivation driver must implement the following entry point:
```
psa_status_t acme_key_derivation_setup(
acme_key_derivation_operation_t *operation,
psa_algorithm_t alg,
const psa_crypto_driver_key_derivation_inputs_t *inputs);
```
* `operation` is a zero-initialized operation object.
* `alg` is the algorithm for the key derivation operation. It does not include a key agreement component.
* `inputs` is an opaque pointer to the [initial inputs](#key-derivation-driver-initial-inputs) for the key derivation.
#### Key derivation driver long inputs
Some key derivation algorithms take long inputs which it would not be practical to pass in the [initial inputs](#key-derivation-driver-initial-inputs). A driver that implements a key derivation algorithm that takes such inputs must provide a `"key_derivation_input_step"` entry point. The core calls this entry point for all the long inputs after calling `"acme_key_derivation_setup"`. A long input step may be fragmented into multiple calls of `psa_key_derivation_input_bytes()`, and the core may reassemble or refragment those fragments before passing them to the driver. Calls to this entry point for different step values occur in an unspecified order and may be interspersed.
```
psa_status_t acme_key_derivation_input_step(
acme_key_derivation_operation_t *operation,
psa_key_derivation_step_t step,
const uint8_t *input, size_t input_length);
```
At the time of writing, no standard key derivation algorithm has long inputs. It is likely that such algorithms will be added in the future.
#### Key derivation driver operation capacity
The core keeps track of an operation's capacity and enforces it. The core guarantees that it will not request output beyond the capacity of the operation, with one exception: opaque drivers that support [`"key_derivation_output_key"`](#key-derivation-driver-outputs), i.e. for key types where the derived key material is not a direct copy of the key derivation's output stream.
Such drivers must enforce the capacity limitation and must return `PSA_ERROR_INSUFFICIENT_CAPACITY` from any output request that exceeds the operation's capacity. Such drivers must provide the following entry point:
```
psa_status_t acme_key_derivation_set_capacity(
acme_key_derivation_operation_t *operation,
size_t capacity);
```
`capacity` is guaranteed to be less or equal to any value previously set through this entry point, and is guaranteed not to be `PSA_KEY_DERIVATION_UNLIMITED_CAPACITY`.
If this entry point has not been called, the operation has an unlimited capacity.
#### Key derivation driver outputs
A key derivation driver must provide the following entry point:
```
psa_status_t acme_key_derivation_output_bytes(
acme_key_derivation_operation_t *operation,
uint8_t *output, size_t length);
```
An opaque key derivation driver may provide the following entry points:
```
psa_status_t acme_key_derivation_output_key(
const psa_key_attributes_t *attributes,
acme_key_derivation_operation_t *operation,
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
psa_status_t acme_key_derivation_verify_bytes(
acme_key_derivation_operation_t *operation,
const uint8_t *expected output, size_t length);
psa_status_t acme_key_derivation_verify_key(
acme_key_derivation_operation_t *operation,
uint8_t *key_buffer, size_t key_buffer_size);
```
The core calls a key derivation driver's output entry point when the application calls `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()` or `psa_key_derivation_verify_key()`.
If the key derivation's `PSA_KEY_DERIVATION_INPUT_SECRET` input is in a secure element and the derivation operation is handled by that secure element, the core performs the following steps:
* For a call to `psa_key_derivation_output_key()`:
1. If the derived key is in the same secure element, if the driver has an `"key_derivation_output_key"` entry point, call that entry point. If the driver has no such entry point, or if that entry point returns `PSA_ERROR_NOT_SUPPORTED`, continue with the following steps, otherwise stop.
1. If the driver's capabilities indicate that its `"import_key"` entry point does not support the derived key, stop and return `PSA_ERROR_NOT_SUPPORTED`.
1. Otherwise proceed as for `psa_key_derivation_output_bytes()`, then import the resulting key material.
* For a call to `psa_key_derivation_verify_key()`:
1. If the driver has a `"key_derivation_verify_key"` entry point, call it and stop.
1. Call the driver's `"export_key"` entry point on the key object that contains the expected value, then proceed as for `psa_key_derivation_verify_bytes()`.
* For a call to `psa_key_derivation_verify_bytes()`:
1. If the driver has a `"key_derivation_verify_bytes"` entry point, call that entry point on the expected output, then stop.
1. Otherwise, proceed as for `psa_key_derivation_output_bytes()`, and compare the resulting output to the expected output inside the core.
* For a call to `psa_key_derivation_output_bytes()`:
1. Call the `"key_derivation_output_bytes"` entry point. The core may call this entry point multiple times to implement a single call from the application when deriving a cooked (non-raw) key as described below, or if the output size exceeds some implementation limit.
If the key derivation operation is not handled by an opaque driver as described above, the core calls the `"key_derivation_output_bytes"` from the applicable transparent driver (or multiple drivers in succession if fallback applies). In some cases, the core then calls additional entry points in the same or another driver:
* For a call to `psa_key_derivation_output_key()` for some key types, the core calls a transparent driver's `"derive_key"` entry point. See [“Transparent cooked key derivation”](#transparent-cooked-key-derivation).
* For a call to `psa_key_derivation_output_key()` where the derived key is in a secure element, call that secure element driver's `"import_key"` entry point.
#### Transparent cooked key derivation
Key derivation is said to be *raw* for some key types, where the key material of a derived (8×*n*)-bit key consists of the next *n* bytes of output from the key derivation, and *cooked* otherwise. When deriving a raw key, the core only calls the driver's `"output_bytes"` entry point, except when deriving a key entirely inside a secure element as described in [“Key derivation driver outputs”](#key-derivation-driver-outputs). When deriving a cooked key, the core calls a transparent driver's `"derive_key"` entry point if available.
A capability for cooked key derivation contains the following properties (this is not a subset of [the usual entry point properties](#capability-syntax)):
* `"entry_points"` (mandatory, list of strings). Must be `["derive_key"]`.
* `"derived_types"` (mandatory, list of strings). Each element is a [key type specification](#key-type-specifications). This capability only applies when deriving a key of the specified type.
* `"derived_sizes"` (optional, list of integers). Each element is a size for the derived key, in bits. This capability only applies when deriving a key of the specified sizes. If absent, this capability applies to all sizes for the specified types.
* `"memory"` (optional, boolean). If present and true, the driver must define a type `"derive_key_memory_t"` and the core will allocate an object of that type as specified below.
* `"names"` (optional, object). A mapping from entry point names to C function and type names, as usual.
* `"fallback"` (optional, boolean). If present and true, the driver may return `PSA_ERROR_NOT_SUPPORTED` if it only partially supports the specified mechanism, as usual.
A transparent driver with the prefix `"acme"` that implements cooked key derivation must provide the following type and function:
```
typedef ... acme_derive_key_memory_t; // only if the "memory" property is true
psa_status_t acme_derive_key(
const psa_key_attributes_t *attributes,
const uint8_t *input, size_t input_length,
acme_derive_key_memory_t *memory, // if the "memory" property is false: void*
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
```
* `attributes` contains the attributes of the specified key. Note that only the key type and the bit-size are guaranteed to be set.
* `input` is a buffer of `input_length` bytes which contains the raw key stream, i.e. the data that `psa_key_derivation_output_bytes()` would return.
* If `"memory"` property in the driver capability is true, `memory` is a data structure that the driver may use to store data between successive calls of the `"derive_key"` entry point to derive the same key. If the `"memory"` property is false or absent, the `memory` parameter is a null pointer.
* `key_buffer` is a buffer for the output material, in the appropriate [export format](#key-format-for-transparent-drivers) for the key type. Its size is `key_buffer_size` bytes.
* On success, `*key_buffer_length` must contain the number of bytes written to `key_buffer`.
This entry point may return the following statuses:
* `PSA_SUCCESS`: a key was derived successfully. The driver has placed the representation of the key in `key_buffer`.
* `PSA_ERROR_NOT_SUPPORTED` (for the first call only) (only if fallback is enabled): the driver cannot fulfill this request, but a fallback driver might.
* `PSA_ERROR_INSUFFICIENT_DATA`: the core must call the `"derive_key"` entry point again with the same `memory` object and with subsequent data from the key stream.
* Any other error is a fatal error.
The core calls the `"derive_key"` entry point in a loop until it returns a status other than `PSA_ERROR_INSUFFICIENT_DATA`. Each call has a successive fragment of the key stream. The `memory` object is guaranteed to be the same for successive calls, but note that its address may change between calls. Before the first call, `*memory` is initialized to all-bits-zero.
For standard key types, the `"derive_key"` entry point is called with a certain input length as follows:
* `PSA_KEY_TYPE_DES`: the length of the key.
* `PSA_KEY_TYPE_ECC_KEY_PAIR(…)`, `PSA_KEY_TYPE_DH_KEY_PAIR(…)`: $m$ bytes, where the bit-size of the key $n$ satisfies $8 (m-1) < n \le 8 m$.
* `PSA_KEY_TYPE_RSA_KEY_PAIR`: an implementation-defined length. A future version of this specification may specify a length.
* Other key types: not applicable.
See [“Open questions around cooked key derivation”](#open-questions-around-cooked-key-derivation) for some points that may not be fully settled.
#### Key agreement
The core always decouples key agreement from symmetric key derivation.
To implement a call to `psa_key_derivation_key_agreement()` where the private key is in a secure element that has a `"key_agreement_to_key"` entry point which is applicable for the given key type and algorithm, the core calls the secure element driver as follows:
1. Call the `"key_agreement_to_key"` entry point to create a key object containing the shared secret. The key object is volatile and has the type `PSA_KEY_TYPE_DERIVE`.
2. Call the `"key_derivation_setup"` entry point, passing the resulting key object .
3. Perform the rest of the key derivation, up to and including the call to the `"key_derivation_abort"` entry point.
4. Call the `"destroy_key"` entry point to destroy the key containing the key object.
In other cases, the core treats `psa_key_derivation_key_agreement()` as if it was a call to `psa_raw_key_agreement()` followed by a call to `psa_key_derivation_input_bytes()` on the shared secret.
The entry points related to key agreement have the following prototypes for a driver with the prefix `"acme"`:
```
psa_status_t acme_key_agreement(psa_algorithm_t alg,
const psa_key_attributes_t *our_attributes,
const uint8_t *our_key_buffer,
size_t our_key_buffer_length,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t acme_key_agreement_to_key(psa_algorithm_t alg,
const psa_key_attributes_t *our_attributes,
const uint8_t *our_key_buffer,
size_t our_key_buffer_length,
const uint8_t *peer_key,
size_t peer_key_length,
const psa_key_attributes_t *shared_secret_attributes,
uint8_t *shared_secret_key_buffer,
size_t shared_secret_key_buffer_size,
size_t *shared_secret_key_buffer_length);
```
Note that unlike most other key creation entry points, in `"acme_key_agreement_to_key"`, the attributes for the shared secret are not placed near the beginning, but rather grouped with the other parameters related to the shared secret at the end of the parameter list. This is to avoid potential confusion with the attributes of the private key that is passed as an input.
### Driver entry points for PAKE
@@ -390,10 +656,6 @@ psa_status_t psa_crypto_driver_pake_get_peer(
const psa_crypto_driver_pake_inputs_t *inputs,
uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length);
psa_status_t psa_crypto_driver_pake_get_role(
    const psa_crypto_driver_pake_inputs_t *inputs,
    psa_pake_role_t *role);
psa_status_t psa_crypto_driver_pake_get_cipher_suite(
    const psa_crypto_driver_pake_inputs_t *inputs,
    psa_pake_cipher_suite_t *cipher_suite);
@@ -474,7 +736,8 @@ For `PSA_ALG_JPAKE` the following steps are available for input operation:
* `PSA_JPAKE_X4S_STEP_ZK_PUBLIC`    Round 2: input Schnorr NIZKP public key for the X4S key
* `PSA_JPAKE_X4S_STEP_ZK_PROOF`     Round 2: input Schnorr NIZKP proof for the X4S key
The core checks that input_length is smaller than PSA_PAKE_INPUT_MAX_SIZE.
The core checks that `input_length` is not greater than `PSA_PAKE_INPUT_SIZE(alg, prim, step)` and
the driver can rely on that.
### PAKE driver get implicit key
@@ -509,8 +772,9 @@ psa_status_t acme_generate_key(const psa_key_attributes_t *attributes,
size_t key_buffer_size,
size_t *key_buffer_length);
```
Additionally, opaque drivers can create keys through their [`"key_derivation_output_key"`](#key-derivation-driver-outputs) and [`"key_agreement_key"`](#key-agreement) entry points. Transparent drivers can create key material through their [`"derive_key"`](#transparent-cooked-key-derivation) entry point.
TODO: derivation, copy
TODO: copy
* The key attributes (`attributes`) have the same semantics as in the PSA Cryptography application interface.
* For the `"import_key"` entry point, the input in the `data` buffer is either the export format or an implementation-specific format that the core documents as an acceptable input format for `psa_import_key()`.
@@ -643,7 +907,7 @@ psa_status_t acme_import_key(const psa_key_attributes_t *attributes,
This entry point has several roles:
1. Parse the key data in the input buffer `data`. The driver must support the export format for the key types that the entry point is declared for. It may support additional formats as specified in the description of [`psa_import_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) in the PSA Cryptography API specification.
2. Validate the key data. The necessary validation is described in the section [“Key validation with transparent drivers”](#key-validation-with-transparent-drivers) above.
2. Validate the key data. The necessary validation is described in the section [“Key validation](#key-validation) above.
3. [Determine the key size](#key-size-determination-on-import) and output it through `*bits`.
4. Copy the validated key data from `data` to `key_buffer`. The output must be in the canonical format documented for [`psa_export_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) or [`psa_export_public_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_public_key), so if the input is not in this format, the entry point must convert it.
@@ -833,7 +1097,7 @@ If the key is stored in wrapped form outside the secure element, and the wrapped
Opaque drivers may provide the following key management entry points:
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations).
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations), or [as a fallback for key derivation](#key-derivation-driver-dispatch-logic).
* `"export_public_key"`: called by the core to obtain the public key of a key pair. The core may call this entry point at any time to obtain the public key, which can be for `psa_export_public_key()` but also at other times, including during a cryptographic operation that requires the public key such as a call to `psa_verify_message()` on a key pair object.
* `"import_key"`: called by `psa_import_key()`, or by `psa_copy_key()` when copying a key from another location.
* `"generate_key"`: called by `psa_generate_key()`.
@@ -1104,6 +1368,12 @@ Should drivers really have to cope with overlap?
Should the core guarantee that the output buffer size has the size indicated by the applicable buffer size macro (which may be an overestimation)?
#### Key derivation inputs and buffer ownership
Why is `psa_crypto_driver_key_derivation_get_input_bytes` a copy, rather than giving a pointer?
The main reason is to avoid complex buffer ownership. A driver entry point does not own memory after the entry point return. This is generally necessary because an API function does not own memory after the entry point returns. In the case of key derivation inputs, this could be relaxed because the driver entry point is making callbacks to the core: these functions could return a pointer that is valid until the driver entry point returns, which would allow the driver to process the data immediately (e.g. hash it rather than copy it).
### Partial computations in drivers
#### Substitution points
@@ -1147,6 +1417,18 @@ An example use case for updating the persistent state at arbitrary times is to r
`psa_crypto_driver_get_persistent_state` does not identify the calling driver, so the driver needs to remember which driver it's calling. This may require a thread-local variable in a multithreaded core. Is this ok?
#### Open questions around cooked key derivation
`"derive_key"` is not a clear name. Can we use a better one?
For the `"derive_key"` entry point, how does the core choose `input_length`? Doesn't the driver know better? Should there be a driver entry point to determine the length, or should there be a callback that allows the driver to retrieve the input? Note that for some key types, it's impossible to predict the amount of input in advance, because it depends on some complex calculation or even on random data, e.g. if doing a randomized pseudo-primality test. However, for all key types except RSA, the specification mandates how the key is derived, which practically dictates how the pseudorandom key stream is consumed. So it's probably ok.
#### Fallback for key derivation in opaque drivers
Should [dispatch to an opaque driver](#key-derivation-driver-dispatch-logic) allow fallback, so that if `"key_derivation_setup"` returns `PSA_ERROR_NOT_SUPPORTED` then the core exports the key from the secure element instead?
Should the ["`key_derivation_output_key`"](#key-derivation-driver-outputs) capability indicate which key types the driver can derive? How should fallback work? For example, consider a secure element that implements HMAC, HKDF and ECDSA, and that can derive an HMAC key from HKDF without exporting intermediate material but can only import or randomly generate ECC keys. How does this driver convey that it can't derive an ECC key with HKDF, but it can let the core do this and import the resulting key?
### Randomness
#### Input to `"add_entropy"`
@@ -1,11 +1,11 @@
Migrating to an auto generated psa_crypto_driver_wrappers.c file
Migrating to an auto generated psa_crypto_driver_wrappers.h file
================================================================
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.c file.
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.md).
## Introduction
The design of the Driver Wrappers code generation is based on the design proposal https://github.com/Mbed-TLS/mbedtls/pull/5067
@@ -27,10 +27,10 @@ While that is the larger goal, for version 1.1 here's what's changed
#### What's changed
(1) psa_crypto_driver_wrappers.c will from this point on be auto generated.
(2) The auto generation is based on the template file at **scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja**.
(3) The driver JSONS to be used for generating the psa_crypto_driver_wrappers.c file can be found at **scripts/data_files/driver_jsons/** as their default location, this path includes the schemas against which the driver schemas will be validated (driver_opaque_schema.json, driver_transparent_schema.json) and a driverlist.json which specifies the drivers to be considered and the order in which they want to be called into. The default location for driverlist.json and driver JSONS can be overloaded by passing an argument --json-dir while running the script generate_driver_wrappers.py.
(4) While the complete driver wrapper templating support is yet to come in, if the library user sees a need to patch psa_crypto_driver_wrappers.c file, the user will need to patch into the template file as needed (psa_crypto_driver_wrappers.c.jinja).
(1) psa_crypto_driver_wrappers.h will from this point on be auto generated.
(2) The auto generation is based on the template file at **scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja**.
(3) The driver JSONS to be used for generating the psa_crypto_driver_wrappers.h file can be found at **scripts/data_files/driver_jsons/** as their default location, this path includes the schemas against which the driver schemas will be validated (driver_opaque_schema.json, driver_transparent_schema.json) and a driverlist.json which specifies the drivers to be considered and the order in which they want to be called into. The default location for driverlist.json and driver JSONS can be overloaded by passing an argument --json-dir while running the script generate_driver_wrappers.py.
(4) While the complete driver wrapper templating support is yet to come in, if the library user sees a need to patch psa_crypto_driver_wrappers.h file, the user will need to patch into the template file as needed (psa_crypto_driver_wrappers.h.jinja).
#### How to set your driver up
+180
View File
@@ -0,0 +1,180 @@
# PSA Cryptoprocessor driver development examples
As of Mbed TLS 3.4.0, the PSA Driver Interface has only been partially implemented. As a result, the deliverables for writing a driver and the method for integrating a driver with Mbed TLS will vary depending on the operation being accelerated. This document describes how to write and integrate cryptoprocessor drivers depending on which operation or driver type is being implemented.
The `docs/proposed/` directory contains three documents which pertain to the proposed, work-in-progress driver system. The [PSA Driver Interface](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md) describes how drivers will interface with Mbed TLS in the future, as well as driver types, operation types, and entry points. As many key terms and concepts used in the examples in this document are defined in the PSA Driver Interface, it is recommended that developers read it prior to starting work on implementing drivers.
The PSA Driver [Developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) Guide describes the deliverables for writing a driver that can be used with Mbed TLS, and the PSA Driver [Integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) Guide describes how a driver can be built alongside Mbed TLS.
## Contents:
[Background on how Mbed TLS calls drivers](#background-on-how-mbed-tls-calls-drivers)\
[Process for Entry Points where auto-generation is implemented](#process-for-entry-points-where-auto-generation-is-implemented) \
[Process for Entry Points where auto-generation is not implemented](#process-for-entry-points-where-auto-generation-is-not-implemented) \
[Example: Manually integrating a software accelerator alongside Mbed TLS](#example-manually-integrating-a-software-accelerator-alongside-mbed-tls)
## Background on how Mbed TLS calls drivers
The PSA Driver Interface specification specifies which cryptographic operations can be accelerated by third-party drivers. Operations that are completed within one step (one function call), such as verifying a signature, are called *Single-Part Operations*. On the other hand, operations that consist of multiple steps implemented by different functions called sequentially are called *Multi-Part Operations*. Single-part operations implemented by a driver will have one entry point, while multi-part operations will have multiple: one for each step.
There are two types of drivers: *transparent* or *opaque*. See below an excerpt from the PSA Driver Interface specification defining them:
* **Transparent** drivers implement cryptographic operations on keys that are provided in cleartext at the beginning of each operation. They are typically used for hardware **accelerators**. When a transparent driver is available for a particular combination of parameters (cryptographic algorithm, key type and size, etc.), it is used instead of the default software implementation. Transparent drivers can also be pure software implementations that are distributed as plug-ins to a PSA Cryptography implementation (for example, an alternative implementation with different performance characteristics, or a certified implementation).
* **Opaque** drivers implement cryptographic operations on keys that can only be used inside a protected environment such as a **secure element**, a hardware security module, a smartcard, a secure enclave, etc. An opaque driver is invoked for the specific [key location](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md#lifetimes-and-locations) that the driver is registered for: the dispatch is based on the key's lifetime.
Mbed TLS contains a **driver dispatch layer** (also called a driver wrapper layer). For each cryptographic operation that supports driver acceleration (or sub-part of a multi-part operation), the library calls the corresponding function in the driver wrapper. Using flags set at compile time, the driver wrapper ascertains whether any present drivers support the operation. When no such driver is present, the built-in library implementation is called as a fallback (if allowed). When a compatible driver is present, the driver wrapper calls the driver entry point function provided by the driver author.
The long-term goal is for the driver dispatch layer to be auto-generated using a JSON driver description file provided by the driver author.
For some cryptographic operations, this auto-generation logic has already been implemented. When accelerating these operations, the instructions in the above documents can be followed. For the remaining operations which do not yet support auto-generation of the driver wrapper, developers will have to manually edit the driver dispatch layer and call their driver's entry point functions from there.
Auto-generation of the driver wrapper is supported for the operation entry points specified in the table below. Certain operations are only permitted for opaque drivers. All other operation entry points do not support auto-generation of the driver wrapper.
| Transparent Driver | Opaque Driver |
|---------------------|---------------------|
| `import_key` | `import_key` |
| `export_public_key` | `export_public_key` |
| | `export_key` |
| | `copy_key` |
| | `get_builtin_key` |
### Process for Entry Points where auto-generation is implemented
If the driver is accelerating operations whose entry points are in the above table, the instructions in the driver [developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) and [integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) guides should be followed.
There are three deliverables for creating such a driver. These are:
- A driver description file (in JSON format).
- C header files defining the types required by the driver description. The names of these header files are declared in the driver description file.
- An object file compiled for the target platform defining the functions required by the driver description. Implementations may allow drivers to be provided as source files and compiled with the core instead of being pre-compiled.
The Mbed TLS driver tests for the aforementioned entry points provide examples of how these deliverables can be implemented. For sample driver description JSON files, see [`mbedtls_test_transparent_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json) or [`mbedtls_test_opaque_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json). The header file required by the driver description is [`test_driver.h`](https://github.com/Mbed-TLS/mbedtls/blob/development/tests/include/test/drivers/test_driver.h). As Mbed TLS tests are built from source, there is no object file for the test driver. However, the source for the test driver can be found under `tests/src/drivers`.
### Process for Entry Points where auto-generation is not implemented
If the driver is accelerating operations whose entry points are not present in the table, a different process is followed where the developer manually edits the driver dispatch layer. The following steps describe this process. Steps 1, 2, 3, and 7 only need to be done once *per driver*. Steps 4, 5, and 6 must be done *for each single-part operation* or *for each sub-part of a multi-part operation* implemented by the driver.
**1. Choose a driver prefix and a macro name that indicates whether the driver is enabled** \
A driver prefix is simply a word (often the name of the driver) that all functions/macros associated with the driver should begin with. This is similar to how most functions/macros in Mbed TLS begin with `PSA_XXX/psa_xxx` or `MBEDTLS_XXX/mbedtls_xxx`. The macro name can follow the form `DRIVER_PREFIX_ENABLED` or something similar; it will be used to indicate the driver is available to be called. When building with the driver present, define this macro at compile time.
**2. Include the following in one of the driver header files:**
```
#if defined(DRIVER_PREFIX_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif
// other definitions here
#endif
```
**3. Conditionally include header files required by the driver**
Include any header files required by the driver in `psa_crypto_driver_wrappers.h`, placing the `#include` statements within an `#if defined` block which checks if the driver is available:
```
#if defined(DRIVER_PREFIX_ENABLED)
#include ...
#endif
```
**4. For each operation being accelerated, locate the function in the driver dispatch layer that corresponds to the entry point of that operation.** \
The file `psa_crypto_driver_wrappers.h.jinja` and `psa_crypto_driver_wrappers_no_static.c.jinja` contains the driver wrapper functions. For the entry points that have driver wrapper auto-generation implemented, the functions have been replaced with `jinja` templating logic. While the file has a `.jinja` extension, the driver wrapper functions for the remaining entry points are simple C functions. The names of these functions are of the form `psa_driver_wrapper` followed by the entry point name. So, for example, the function `psa_driver_wrapper_sign_hash()` corresponds to the `sign_hash` entry point.
**5. If a driver entry point function has been provided then ensure it has the same signature as the driver wrapper function.** \
If one has not been provided then write one. Its name should begin with the driver prefix, followed by transparent/opaque (depending on driver type), and end with the entry point name. It should have the same signature as the driver wrapper function. The purpose of the entry point function is to take arguments in PSA format for the implemented operation and return outputs/status codes in PSA format. \
*Return Codes:*
* `PSA_SUCCESS`: Successful Execution
* `PSA_ERROR_NOT_SUPPORTED`: Input arguments are correct, but the driver does not support the operation. If a transparent driver returns this then it allows fallback to another driver or software implementation.
* `PSA_ERROR_XXX`: Any other PSA error code, see API documentation
**6. Modify the driver wrapper function** \
Each driver wrapper function contains a `switch` statement which checks the location of the key. If the key is stored in local storage, then operations are performed by a transparent driver. If it is stored elsewhere, then operations are performed by an opaque driver.
* **Transparent drivers:** Calls to driver entry points go under `case PSA_KEY_LOCATION_LOCAL_STORAGE`.
* **Opaque Drivers** Calls to driver entry points go in a separate `case` block corresponding to the key location.
The diagram below shows the layout of a driver wrapper function which can dispatch to two transparent drivers `Foo` and `Bar`, and one opaque driver `Baz`.
```
psa_driver_wrapper_xxx()
├── switch(location)
| |
| ├── case PSA_KEY_LOCATION_LOCAL_STORAGE //transparent driver
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
| | | ├── #if defined(FOO_DRIVER_PREFIX_ENABLED)
| | | | ├── if(//conditions for foo driver capibilities)
| | | | ├── foo_driver_transparent_xxx() //call to driver entry point
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
| | | ├── #endif
| | | ├── #if defined(BAR_DRIVER_PREFIX_ENABLED)
| | | | ├── if(//conditions for bar driver capibilities)
| | | | ├── bar_driver_transparent_xxx() //call to driver entry point
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
| | | ├── #endif
| | ├── #endif
| |
| ├── case SECURE_ELEMENT_LOCATION //opaque driver
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
| | | ├── #if defined(BAZ_DRIVER_PREFIX_ENABLED)
| | | | ├── if(//conditions for baz driver capibilities)
| | | | ├── baz_driver_opaque_xxx() //call to driver entry point
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
| | | ├── #endif
| | ├── #endif
└── return psa_xxx_builtin() // fall back to built in implementation
```
All code related to driver calls within each `case` must be contained between `#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)` and a corresponding `#endif`. Within this block, each individual driver's compatibility checks and call to the entry point must be contained between `#if defined(DRIVER_PREFIX_ENABLED)` and a corresponding `#endif`. Checks that involve accessing key material using PSA macros, such as determining the key type or number of bits, must be done in the driver wrapper.
**7. Build Mbed TLS with the driver**
This guide assumes you are building Mbed TLS from source alongside your project. If building with a driver present, the chosen driver macro (`DRIVER_PREFIX_ENABLED`) must be defined. This can be done in two ways:
* *At compile time via flags.* This is the preferred option when your project uses Mbed TLS mostly out-of-the-box without significantly modifying the configuration. This can be done by passing the option via `CFLAGS`.
* **Make**:
```
make CFLAGS="-DDRIVER_PREFIX_ENABLED"
```
* **CMake**: CFLAGS must be passed to CMake when it is invoked. Invoke CMake with
```
CFLAGS="-DDRIVER_PREFIX_ENABLED" cmake path/to/source
```
* *Providing a user config file.* This is the preferred option when your project requires a custom configuration that is significantly different to the default. Define the macro for the driver, along with any other custom configurations in a separate header file, then use `config.py`, to set `MBEDTLS_USER_CONFIG_FILE`, providing the path to the defined header file. This will include your custom config file after the default. If you wish to completely replace the default config file, set `MBEDTLS_CONFIG_FILE` instead.
### Example: Manually integrating a software accelerator alongside Mbed TLS
[p256-m](https://github.com/mpg/p256-m) is a minimalistic implementation of ECDH and ECDSA on the NIST P-256 curve, specifically optimized for use in constrained 32-bit environments. It started out as an independent project and has been integrated in Mbed TLS as a PSA transparent driver. The source code of p256-m and the driver entry points is located in the Mbed TLS source tree under `3rdparty/p256-m`. In this section, we will look at how this integration was done.
The Mbed TLS build system includes the instructions needed to build p256-m. To build with and use p256-m, set the macro `MBEDTLS_PSA_P256M_DRIVER_ENABLED` using `config.py`, then build as usual using make/cmake. From the root of the `mbedtls/` directory, run:
python3 scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG
python3 scripts/config.py set MBEDTLS_PSA_P256M_DRIVER_ENABLED
make
(You need extra steps if you want to disable the built-in implementation of ECC algorithms, which includes more features than p256-m. Refer to the documentation of `MBEDTLS_PSA_P256M_DRIVER_ENABLED` and [`driver-only-builds.md`](driver-only-builds.md) for more information.)
The driver prefix for p256-m is `P256`/`p256`.
The p256-m driver implements the following entry points: `"import_key"`, `"export_public_key"`, `"generate_key"`, `"key_agreement"`, `"sign_hash"`, `"verify_hash"`.
There are no entry points for `"sign_message"` and `"verify_message"`, which are not necessary for a sign-and-hash algorithm. The core still implements these functions by doing the hashes and then calling the sign/verify-hash entry points.
The driver entry point functions can be found in `p256m_driver_entrypoints.[hc]`. These functions act as an interface between Mbed TLS and p256-m; converting between PSA and p256-m argument formats and performing sanity checks. If the driver's status codes differ from PSA's, it is recommended to implement a status code translation function. The function `p256_to_psa_error()` converts error codes returned by p256-m into PSA error codes.
The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all four entry points have also been modified. The code block below shows the additions made to `psa_driver_wrapper_sign_hash()`. In adherence to the defined process, all code related to the driver call is placed within a check for `MBEDTLS_PSA_P256M_DRIVER_ENABLED`. p256-m only supports non-deterministic ECDSA using keys based on NIST P256; these constraints are enforced through checks (see the `if` statement). Checks that involve accessing key attributes, (e.g. checking key type or bits) **must** be performed in the driver wrapper. This is because this information is marked private and may not be accessed outside the library. Other checks can be performed here or in the entry point function. The status returned by the driver is propagated up the call hierarchy **unless** the driver does not support the operation (i.e. return `PSA_ERROR_NOT_SUPPORTED`). In that case the next available driver/built-in implementation is called.
```
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,
key_buffer_size,
alg,
hash,
hash_length,
signature,
signature_size,
signature_length );
if( status != PSA_ERROR_NOT_SUPPORTED )
return( status );
}
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
```
Following this, p256-m is now ready to use alongside Mbed TLS as a software accelerator. If `MBEDTLS_PSA_P256M_DRIVER_ENABLED` is set in the config, p256-m's implementations of key generation, ECDH, and ECDSA will be used where applicable.
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
# Readthedocs redirects
# See https://docs.readthedocs.io/en/stable/user-defined-redirects.html
#
# Changes to this file do not take effect until they are merged into the
# 'development' branch. This is because the API token (RTD_TOKEN) is not
# made available in PR jobs - preventing bad actors from crafting PRs to
# expose it.
- type: exact
from_url: /projects/api/en/latest/*
to_url: /projects/api/en/development/:splat
+2 -1
View File
@@ -1,2 +1,3 @@
sphinx-rtd-theme
breathe
readthedocs-cli
sphinx-rtd-theme
+18 -2
View File
@@ -14,6 +14,8 @@ certifi==2022.12.7
# via requests
charset-normalizer==3.1.0
# via requests
click==8.1.3
# via readthedocs-cli
docutils==0.17.1
# via
# breathe
@@ -27,14 +29,28 @@ importlib-metadata==6.0.0
# via sphinx
jinja2==3.1.2
# via sphinx
markdown-it-py==2.2.0
# via rich
markupsafe==2.1.2
# via jinja2
mdurl==0.1.2
# via markdown-it-py
packaging==23.0
# via sphinx
pygments==2.14.0
# via sphinx
# via
# rich
# sphinx
pyyaml==6.0
# via readthedocs-cli
readthedocs-cli==4
# via -r requirements.in
requests==2.28.2
# via sphinx
# via
# readthedocs-cli
# sphinx
rich==13.3.5
# via readthedocs-cli
snowballstemmer==2.2.0
# via sphinx
sphinx==4.5.0
+192
View File
@@ -0,0 +1,192 @@
Writing early data
------------------
An application function to write and send a buffer of data to a server through
TLS may plausibly look like:
```
int write_data(mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written)
{
int ret;
*data_written = 0;
while (*data_written < data_to_write_len) {
ret = mbedtls_ssl_write(ssl, data_to_write + *data_written,
data_to_write_len - *data_written);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
return ret;
}
*data_written += ret;
}
return 0;
}
```
where ssl is the SSL context to use, data_to_write the address of the data
buffer and data_to_write_len the number of data bytes. The handshake may
not be completed, not even started for the SSL context ssl when the function is
called and in that case the mbedtls_ssl_write() API takes care transparently of
completing the handshake before to write and send data to the server. The
mbedtls_ssl_write() may not be able to write and send all data in one go thus
the need for a loop calling it as long as there are still data to write and
send.
An application function to write and send early data and only early data,
data sent during the first flight of client messages while the handshake is in
its initial phase, would look completely similar but the call to
mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
```
int write_early_data(mbedtls_ssl_context *ssl,
const unsigned char *data_to_write,
size_t data_to_write_len,
size_t *data_written)
{
int ret;
*data_written = 0;
while (*data_written < data_to_write_len) {
ret = mbedtls_ssl_write_early_data(ssl, data_to_write + *data_written,
data_to_write_len - *data_written);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
return ret;
}
*data_written += ret;
}
return 0;
}
```
Note that compared to write_data(), write_early_data() can also return
MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
specifically by the user of write_early_data(). A fresh SSL context (typically
just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
be expected when calling `write_early_data`.
All together, code to write and send a buffer of data as long as possible as
early data and then as standard post-handshake application data could
plausibly look like:
```
ret = write_early_data(ssl,
data_to_write,
data_to_write_len,
&early_data_written);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
goto error;
}
ret = write_data(ssl,
data_to_write + early_data_written,
data_to_write_len - early_data_written,
&data_written);
if (ret < 0) {
goto error;
}
data_written += early_data_written;
```
Finally, taking into account that the server may reject early data, application
code to write and send a buffer of data could plausibly look like:
```
ret = write_early_data(ssl,
data_to_write,
data_to_write_len,
&early_data_written);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) {
goto error;
}
/*
* Make sure the handshake is completed as it is a requisite of
* mbedtls_ssl_get_early_data_status().
*/
while (!mbedtls_ssl_is_handshake_over(ssl)) {
ret = mbedtls_ssl_handshake(ssl);
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
goto error;
}
}
ret = mbedtls_ssl_get_early_data_status(ssl);
if (ret < 0) {
goto error;
}
if (ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
early_data_written = 0;
}
ret = write_data(ssl,
data_to_write + early_data_written,
data_to_write_len - early_data_written,
&data_written);
if (ret < 0) {
goto error;
}
data_written += early_data_written;
```
Reading early data
------------------
Mbed TLS provides the mbedtls_ssl_read_early_data() API to read the early data
that a TLS 1.3 server might receive during the TLS 1.3 handshake.
While establishing a TLS 1.3 connection with a client using a combination
of the mbedtls_ssl_handshake(), mbedtls_ssl_read() and mbedtls_ssl_write() APIs,
the reception of early data is signaled by an API returning the
MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA error code. Early data can then be read
with the mbedtls_ssl_read_early_data() API.
For example, a typical code to establish a TLS connection, where ssl is the SSL
context to use:
```
while ((int ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
break;
}
}
```
could be adapted to handle early data in the following way:
```
size_t data_read_len = 0;
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
ret = mbedtls_ssl_read_early_data(&ssl,
buffer + data_read_len,
sizeof(buffer) - data_read_len);
if (ret < 0) {
break;
}
data_read_len += ret;
continue;
}
if (ret < 0 &&
ret != MBEDTLS_ERR_SSL_WANT_READ &&
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
break;
}
}
```
+62 -6
View File
@@ -1,19 +1,47 @@
This document describes the compile-time configuration option
`MBEDTLS_USE_PSA_CRYPTO` from a user's perspective.
This option makes the X.509 and TLS library use PSA for cryptographic
operations, and enables new APIs for using keys handled by PSA Crypto.
This option:
- makes the X.509 and TLS libraries use PSA for cryptographic operations as
much as possible, see "Internal changes" below;
- enables new APIs for using keys handled by PSA Crypto, such as
`mbedtls_pk_setup_opaque()` and `mbedtls_ssl_conf_psk_opaque()`, see
"New APIs / API extensions" below.
General considerations
----------------------
**Application code:** when this option is enabled, you need to call
`psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
module.
modules, except for the various mbedtls_xxx_init() functions which can be called
at any time.
**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on the most of the TLS 1.3
code, which always uses PSA crypto. The parts of the TLS 1.3 code that will
use PSA Crypto or not depending on the value of this option are:
**Why enable this option:** to fully take advantage of PSA drivers in PK,
X.509 and TLS. For example, enabling this option is what allows use of drivers
for ECDSA, ECDH and EC J-PAKE in those modules. However, note that even with
this option disabled, some code in PK, X.509, TLS or the crypto library might
still use PSA drivers, if it can determine it's safe to do so; currently
that's the case for hashes.
**Relationship with other options:** This option depends on
`MBEDTLS_PSA_CRYPTO_C`. These two options differ in the following way:
- `MBEDTLS_PSA_CRYPTO_C` enables the implementation of the PSA Crypto API.
When it is enabled, `psa_xxx()` APIs are available and you must call
`psa_crypto_init()` before you call any other `psa_xxx()` function. Other
modules in the library (non-PSA crypto APIs, X.509, TLS) may or may not use
PSA Crypto but you're not required to call `psa_crypto_init()` before calling
non-PSA functions, unless explicitly documented (TLS 1.3).
- `MBEDTLS_USE_PSA_CRYPTO` means that X.509 and TLS will use PSA Crypto as
much as possible (that is, everywhere except for features that are not
supported by PSA Crypto, see "Internal Changes" below for a complete list of
exceptions). When it is enabled, you need to call `psa_crypto_init()` before
calling any function from PK, X.509 or TLS; however it doesn't change anything
for the rest of the library.
**Scope:** `MBEDTLS_USE_PSA_CRYPTO` has no effect on modules other than PK,
X.509 and TLS. It also has no effect on most of the TLS 1.3 code, which always
uses PSA crypto. The parts of the TLS 1.3 code that will use PSA Crypto or not
depending on this option being set or not are:
- record protection;
- running handshake hash;
- asymmetric signature verification & generation;
@@ -21,6 +49,21 @@ use PSA Crypto or not depending on the value of this option are:
You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you want TLS 1.3 to use PSA
everywhere.
**Historical note:** This option was introduced at a time when PSA Crypto was
still beta and not ready for production, so we made its use in X.509 and TLS
opt-in: by default, these modules would keep using the stable,
production-ready legacy (pre-PSA) crypto APIs. So, the scope of was X.509 and
TLS, as well as some of PK for technical reasons. Nowadays PSA Crypto is no
longer beta, and production quality, so there's no longer any reason to make
its use in other modules opt-in. However, PSA Crypto functions require that
`psa_crypto_init()` has been called before their use, and for backwards
compatibility reasons we can't impose this requirement on non-PSA functions
that didn't have such a requirement before. So, nowadays the main meaning of
`MBEDTLS_USE_PSA_CRYPTO` is that the user promises to call `psa_crypto_init()`
before calling any PK, X.509 or TLS functions. For the same compatibility
reasons, we can't extend its scope. However, new modules in the library, such
as TLS 1.3, can be introduced with a requirement to call `psa_crypto_init()`.
New APIs / API extensions
-------------------------
@@ -63,6 +106,19 @@ register a PSA key for use with a PSK key exchange.
**Use in TLS:** opt-in. The application needs to register the key using one of
the new APIs to get the benefits.
### PSA-held (opaque) keys for TLS 1.2 EC J-PAKE key exchange
**New API function:** `mbedtls_ssl_set_hs_ecjpake_password_opaque()`.
Call this function from an application to register a PSA key for use with the
TLS 1.2 EC J-PAKE key exchange.
**Benefits:** isolation of long-term secrets.
**Limitations:** none.
**Use in TLS:** opt-in. The application needs to register the key using one of
the new APIs to get the benefits.
### PSA-based operations in the Cipher layer
There is a new API function `mbedtls_cipher_setup_psa()` to set up a context
+3 -2
View File
@@ -1,4 +1,4 @@
PROJECT_NAME = "mbed TLS v3.4.1"
PROJECT_NAME = "Mbed TLS v3.6.0"
OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES
@@ -6,7 +6,7 @@ EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = NO
INPUT = ../include input
INPUT = ../include input ../tests/include/alt-dummy
FILE_PATTERNS = *.h
RECURSIVE = YES
EXCLUDE_SYMLINKS = YES
@@ -51,4 +51,5 @@ PREDEFINED = "MBEDTLS_CHECK_RETURN_CRITICAL=" \
"MBEDTLS_CHECK_RETURN_TYPICAL=" \
"MBEDTLS_CHECK_RETURN_OPTIONAL=" \
"MBEDTLS_PRINTF_ATTRIBUTE(a,b)=" \
"__DOXYGEN__" \
+10 -13
View File
@@ -22,19 +22,7 @@
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_AES_H
@@ -76,6 +64,10 @@ typedef struct mbedtls_aes_context {
int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */
size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES
round keys in the buffer. */
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C)
uint32_t MBEDTLS_PRIVATE(buf)[44]; /*!< Aligned data buffer to hold
10 round keys for 128-bit case. */
#else
uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
@@ -84,6 +76,7 @@ typedef struct mbedtls_aes_context {
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH && !MBEDTLS_PADLOCK_C */
}
mbedtls_aes_context;
@@ -162,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.
*
@@ -180,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)
/**
@@ -599,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
@@ -614,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)
/**
+3 -17
View File
@@ -11,19 +11,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ARIA_H
@@ -110,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.
*
@@ -128,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
@@ -259,10 +249,6 @@ int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
* \brief This function performs an ARIA-CTR encryption or decryption
* operation.
*
* This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
*
* Due to the nature of CTR, you must use the same key schedule
* for both encryption and decryption operations. Therefore, you
* must use the context initialized with mbedtls_aria_setkey_enc()
+12 -19
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
@@ -96,15 +84,14 @@
/* Slightly smaller way to check if tag is a string tag
* compared to canonical implementation. */
#define MBEDTLS_ASN1_IS_STRING_TAG(tag) \
((tag) < 32u && ( \
#define MBEDTLS_ASN1_IS_STRING_TAG(tag) \
((unsigned int) (tag) < 32u && ( \
((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING) | \
(1u << MBEDTLS_ASN1_UTF8_STRING) | \
(1u << MBEDTLS_ASN1_T61_STRING) | \
(1u << MBEDTLS_ASN1_IA5_STRING) | \
(1u << MBEDTLS_ASN1_UNIVERSAL_STRING) | \
(1u << MBEDTLS_ASN1_PRINTABLE_STRING) | \
(1u << MBEDTLS_ASN1_BIT_STRING))) != 0))
(1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0))
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
@@ -210,6 +197,8 @@ typedef struct mbedtls_asn1_named_data {
}
mbedtls_asn1_named_data;
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
@@ -256,7 +245,9 @@ int mbedtls_asn1_get_len(unsigned char **p,
int mbedtls_asn1_get_tag(unsigned char **p,
const unsigned char *end,
size_t *len, int tag);
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
@@ -474,7 +465,7 @@ void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq);
* on a successful invocation.
* \param end The end of the ASN.1 SEQUENCE container.
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_must_value.
* the SEQUENCE before comparing to \p tag_must_val.
* \param tag_must_val The required value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_must_mask.
* Mismatching tags lead to an error.
@@ -483,7 +474,7 @@ void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq);
* while a value of \c 0xFF for \p tag_must_mask means
* that \p tag_must_val is the only allowed tag.
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_may_value.
* the SEQUENCE before comparing to \p tag_may_val.
* \param tag_may_val The desired value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_may_mask.
* Mismatching tags will be silently ignored.
@@ -642,6 +633,8 @@ 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
+28 -13
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
@@ -48,6 +36,8 @@
extern "C" {
#endif
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Write a length field in ASN.1 format.
*
@@ -76,7 +66,9 @@ int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start,
*/
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
unsigned char tag);
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA*/
#if defined(MBEDTLS_ASN1_WRITE_C)
/**
* \brief Write raw buffer data.
*
@@ -163,6 +155,27 @@ int mbedtls_asn1_write_algorithm_identifier(unsigned char **p,
const char *oid, size_t oid_len,
size_t par_len);
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID of the algorithm to write.
* \param oid_len The length of the algorithm's OID.
* \param par_len The length of the parameters, which must be already written.
* \param has_par If there are any parameters. If 0, par_len must be 0. If 1
* and \p par_len is 0, NULL parameters are added.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p,
const unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len, int has_par);
/**
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
* in ASN.1 format.
@@ -372,4 +385,6 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data *
}
#endif
#endif /* MBEDTLS_ASN1_WRITE_C */
#endif /* MBEDTLS_ASN1_WRITE_H */
+40 -27
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
@@ -63,15 +51,15 @@
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 2
* Maximum window size used for modular exponentiation. Default: 3
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
* for the sliding window calculation. (So 8 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
@@ -129,6 +117,7 @@
#endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#elif defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
@@ -141,6 +130,7 @@ typedef uint64_t mbedtls_mpi_uint;
#endif /* MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
@@ -156,6 +146,7 @@ typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef __uint128_t mbedtls_t_udbl;
@@ -165,6 +156,7 @@ typedef __uint128_t mbedtls_t_udbl;
/* Force 64-bit integers with unknown compiler */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT64_MAX
#endif
#endif /* !MBEDTLS_HAVE_INT32 */
@@ -175,12 +167,22 @@ typedef uint64_t mbedtls_mpi_uint;
#endif /* !MBEDTLS_HAVE_INT32 */
typedef int32_t mbedtls_mpi_sint;
typedef uint32_t mbedtls_mpi_uint;
#define MBEDTLS_MPI_UINT_MAX UINT32_MAX
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
typedef uint64_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#endif /* !MBEDTLS_HAVE_INT64 */
/*
* Sanity check that exactly one of MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 is defined,
* so that code elsewhere doesn't have to check.
*/
#if (!(defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64))) || \
(defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64))
#error "Only 32-bit or 64-bit limbs are supported in bignum"
#endif
/** \typedef mbedtls_mpi_uint
* \brief The type of machine digits in a bignum, called _limbs_.
*
@@ -203,6 +205,12 @@ extern "C" {
* \brief MPI structure
*/
typedef struct mbedtls_mpi {
/** Pointer to limbs.
*
* This may be \c NULL if \c n is 0.
*/
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p);
/** Sign: -1 if the mpi is negative, 1 otherwise.
*
* The number 0 must be represented with `s = +1`. Although many library
@@ -214,16 +222,19 @@ typedef struct mbedtls_mpi {
* Note that this implies that calloc() or `... = {0}` does not create
* a valid MPI representation. You must call mbedtls_mpi_init().
*/
int MBEDTLS_PRIVATE(s);
signed short MBEDTLS_PRIVATE(s);
/** Total number of limbs in \c p. */
size_t MBEDTLS_PRIVATE(n);
/** Pointer to limbs.
*
* This may be \c NULL if \c n is 0.
unsigned short MBEDTLS_PRIVATE(n);
/* Make sure that MBEDTLS_MPI_MAX_LIMBS fits in n.
* Use the same limit value on all platforms so that we don't have to
* think about different behavior on the rare platforms where
* unsigned short can store values larger than the minimum required by
* the C language, which is 65535.
*/
mbedtls_mpi_uint *MBEDTLS_PRIVATE(p);
#if MBEDTLS_MPI_MAX_LIMBS > 65535
#error "MBEDTLS_MPI_MAX_LIMBS > 65535 is not supported"
#endif
}
mbedtls_mpi;
@@ -530,7 +541,7 @@ int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X,
* \param X The destination MPI. This must point to an initialized MPI.
* \param buf The input buffer. This must be a readable buffer of length
* \p buflen Bytes.
* \param buflen The length of the input buffer \p p in Bytes.
* \param buflen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@@ -545,7 +556,7 @@ int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf,
* \param X The destination MPI. This must point to an initialized MPI.
* \param buf The input buffer. This must be a readable buffer of length
* \p buflen Bytes.
* \param buflen The length of the input buffer \p p in Bytes.
* \param buflen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
@@ -594,6 +605,8 @@ int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,
* \brief Perform a left-shift on an MPI: X <<= count
*
* \param X The MPI to shift. This must point to an initialized MPI.
* The MPI pointed by \p X may be resized to fit
* the resulting number.
* \param count The number of bits to shift by.
*
* \return \c 0 if successful.
@@ -983,8 +996,8 @@ int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A,
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
* or equal to one.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
* with respect to \p N.
* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p A has no modular
* inverse with respect to \p N.
*/
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *N);
+76
View 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 */
+99 -76
View File
@@ -1,5 +1,5 @@
/**
* \file build_info.h
* \file mbedtls/build_info.h
*
* \brief Build-time configuration info
*
@@ -8,19 +8,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_BUILD_INFO_H
@@ -37,17 +25,71 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 4
#define MBEDTLS_VERSION_PATCH 1
#define MBEDTLS_VERSION_MINOR 6
#define MBEDTLS_VERSION_PATCH 0
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x03040100
#define MBEDTLS_VERSION_STRING "3.4.1"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.1"
#define MBEDTLS_VERSION_NUMBER 0x03060000
#define MBEDTLS_VERSION_STRING "3.6.0"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.0"
/* Macros for build-time platform detection */
#if !defined(MBEDTLS_ARCH_IS_ARM64) && \
(defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC))
#define MBEDTLS_ARCH_IS_ARM64
#endif
#if !defined(MBEDTLS_ARCH_IS_ARM32) && \
(defined(__arm__) || defined(_M_ARM) || \
defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__))
#define MBEDTLS_ARCH_IS_ARM32
#endif
#if !defined(MBEDTLS_ARCH_IS_X64) && \
(defined(__amd64__) || defined(__x86_64__) || \
((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC)))
#define MBEDTLS_ARCH_IS_X64
#endif
#if !defined(MBEDTLS_ARCH_IS_X86) && \
(defined(__i386__) || defined(_X86_) || \
(defined(_M_IX86) && !defined(_M_I86)))
#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(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \
&& !defined(__llvm__) && !defined(__INTEL_COMPILER)
/* Defined if the compiler really is gcc and not clang, etc */
#define MBEDTLS_COMPILER_IS_GCC
#define MBEDTLS_GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
@@ -59,6 +101,7 @@
#define inline __inline
#endif
/* X.509, TLS and non-PSA crypto configuration */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/mbedtls_config.h"
#else
@@ -84,74 +127,54 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
* This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
/* PSA crypto configuration */
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
#else
#include "psa/crypto_config.h"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
#endif
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if
* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined
* to ensure a 128-bit key size in CTR_DRBG.
*/
#if defined(MBEDTLS_MD_C)
#define MBEDTLS_MD_LIGHT
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && defined(MBEDTLS_CTR_DRBG_C)
#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
#endif
/* Auto-enable MBEDTLS_MD_LIGHT if some module needs it.
/* Auto-enable MBEDTLS_MD_C if needed by a module that didn't require it
* in a previous release, to ensure backwards compatibility.
*/
#if defined(MBEDTLS_PEM_PARSE_C) || \
defined(MBEDTLS_RSA_C)
#define MBEDTLS_MD_LIGHT
#if defined(MBEDTLS_PKCS5_C)
#define MBEDTLS_MD_C
#endif
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
/* PSA crypto specific configuration options
* - If config_psa.h reads a configuration option in preprocessor directive,
* this symbol should be set before its inclusion. (e.g. MBEDTLS_MD_C)
* - If config_psa.h writes a configuration option in conditional directive,
* this symbol should be consulted after its inclusion.
* (e.g. MBEDTLS_MD_LIGHT)
*/
#if defined(MBEDTLS_PSA_CRYPTO_C)
#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(). */
#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C)
#define MBEDTLS_PK_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PK_PARSE_C
#endif
#if !defined(MBEDTLS_SSL_PROTO_TLS1_2)
#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#endif
#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
#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
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) || \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED
#endif
/* Make sure all configuration symbols are set before including check_config.h,
* even the ones that are calculated programmatically. */
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */
defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */ || \
defined(MBEDTLS_PSA_CRYPTO_CLIENT) /* The same as the previous, but with separation only */
#include "mbedtls/config_psa.h"
#endif
#include "mbedtls/config_adjust_legacy_crypto.h"
#include "mbedtls/config_adjust_x509.h"
#include "mbedtls/config_adjust_ssl.h"
/* Make sure all configuration symbols are set before including check_config.h,
* even the ones that are calculated programmatically. */
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_BUILD_INFO_H */
+4 -14
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CAMELLIA_H
#define MBEDTLS_CAMELLIA_H
@@ -93,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.
*
@@ -108,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.
@@ -220,7 +210,7 @@ int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
* *note Due to the nature of CTR mode, you should use the same
* key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
* mbedtls_camellia_setkey_enc() regardless of whether the mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
+14 -19
View File
@@ -29,19 +29,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CCM_H
@@ -52,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
@@ -77,7 +69,6 @@ extern "C" {
typedef struct mbedtls_ccm_context {
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working buffer */
unsigned char MBEDTLS_PRIVATE(ctr)[16]; /*!< The counter buffer */
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
size_t MBEDTLS_PRIVATE(plaintext_len); /*!< Total plaintext length */
size_t MBEDTLS_PRIVATE(add_len); /*!< Total authentication data length */
size_t MBEDTLS_PRIVATE(tag_len); /*!< Total tag length */
@@ -87,15 +78,19 @@ typedef struct mbedtls_ccm_context {
and plaintext/ciphertext.
This variable is set to zero after
auth data input is finished. */
unsigned char MBEDTLS_PRIVATE(q); /*!< The Q working value */
unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
unsigned int MBEDTLS_PRIVATE(q); /*!< The Q working value */
unsigned int MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
#MBEDTLS_CCM_ENCRYPT or
#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 */
state. Used for chunked data input */
}
mbedtls_ccm_context;
@@ -514,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.
*
+222 -203
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
@@ -30,28 +18,18 @@
*/
#include <limits.h>
#if CHAR_BIT != 8
#error "mbed TLS requires a platform with 8-bit chars"
#error "Mbed TLS requires a platform with 8-bit chars"
#endif
#include <stdint.h>
#if defined(_WIN32)
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in mbedtls_config.h as
* it would confuse config.py. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif
#endif /* _WIN32 */
/* See auto-enabling SNPRINTF_ALT and VSNPRINTF_ALT
* in * config_adjust_legacy_crypto.h */
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
@@ -66,14 +44,49 @@
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(__aarch64__) && defined(__GNUC__)
/* We don't do anything with MBEDTLS_AESCE_C on systems without ^ these two */
#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESCE_C defined, but not all prerequisites"
#endif
#endif
/* Limitations on ECC key types acceleration: if we have any of `PUBLIC_KEY`,
* `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`, `KEY_PAIR_EXPORT` then we must have
* all 4 of them.
*/
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)
#error "Unsupported partial support for ECC key type acceleration, see docs/driver-only-builds.md"
#endif /* not all of public, basic, import, export */
#endif /* one of public, basic, import, export */
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
/* Limitations on ECC curves acceleration: partial curve acceleration is only
* supported with crypto excluding PK, X.509 or TLS.
* Note: no need to check X.509 as it depends on PK. */
#if defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \
defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \
defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \
defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \
defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \
defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)
#if defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#if defined(MBEDTLS_PK_C) || \
defined(MBEDTLS_SSL_TLS_C)
#error "Unsupported partial support for ECC curves acceleration, see docs/driver-only-builds.md"
#endif /* modules beyond what's supported */
#endif /* not all curves accelerated */
#endif /* some curve accelerated */
#if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \
(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_KEY_TYPE_AES) && \
defined(PSA_WANT_ALG_ECB_NO_PADDING)))
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
@@ -91,6 +104,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
@@ -113,9 +156,17 @@
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || \
!( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) )
#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)
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
@@ -139,7 +190,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) && \
@@ -153,76 +204,46 @@
!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_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) || \
!defined(MBEDTLS_CIPHER_C) )
#error "MBEDTLS_PKCS5_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS12_C) && \
!( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) )
#error "MBEDTLS_PKCS12_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS1_V21) && \
!( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) )
#error "MBEDTLS_PKCS1_V21 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#if defined(MBEDTLS_ENTROPY_C) && \
!(defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA256))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
(defined(MBEDTLS_ENTROPY_FORCE_SHA256) || !defined(MBEDTLS_MD_CAN_SHA512)) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_MD_CAN_SHA256)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_HAS_MEMSAN
#define MBEDTLS_HAS_MEMSAN // #undef at the end of this paragraph
#endif
#endif
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
#endif
#undef MBEDTLS_HAS_MEMSAN
#undef MBEDTLS_HAS_MEMSAN // temporary macro defined above
#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
@@ -278,37 +299,15 @@
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
/* Helper for ECDSA dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_HAVE_FULL_ECDSA)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for JPAKE dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_HAVE_FULL_JPAKE)
#define MBEDTLS_PK_HAVE_JPAKE
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECJPAKE_C)
#define MBEDTLS_PK_HAVE_JPAKE
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@@ -318,7 +317,7 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
!defined(MBEDTLS_CAN_ECDH)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
@@ -329,14 +328,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
( !defined(MBEDTLS_CAN_ECDH) || \
!defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
@@ -353,42 +352,52 @@
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_PK_HAVE_JPAKE) || \
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(PSA_WANT_ALG_JPAKE) || \
!defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
!defined(PSA_WANT_ECC_SECP_R1_256) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Use of EC J-PAKE in TLS requires SHA-256.
* This will be taken from MD if it is present, or from PSA if MD is absent.
* Note: MBEDTLS_ECJPAKE_C depends on MBEDTLS_MD_C || MBEDTLS_PSA_CRYPTO_C. */
/* Use of EC J-PAKE in TLS requires SHA-256. */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
!( defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C) ) && \
!( !defined(MBEDTLS_MD_C) && defined(PSA_WANT_ALG_SHA_256) )
!defined(MBEDTLS_MD_CAN_SHA256)
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
( !defined(MBEDTLS_SHA256_C) && \
!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA1_C) )
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
!defined(MBEDTLS_MD_CAN_SHA256) && \
!defined(MBEDTLS_MD_CAN_SHA512) && \
!defined(MBEDTLS_MD_CAN_SHA1)
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires SHA-512, SHA-256 or SHA-1".
#endif
#if defined(MBEDTLS_MD_C) && !( \
defined(MBEDTLS_MD5_C) || \
defined(MBEDTLS_RIPEMD160_C) || \
defined(MBEDTLS_SHA1_C) || \
defined(MBEDTLS_SHA224_C) || \
defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_SHA384_C) || \
defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_MD_C defined, but not all prerequisites"
#if defined(MBEDTLS_MD_C) && \
!defined(MBEDTLS_MD_CAN_MD5) && \
!defined(MBEDTLS_MD_CAN_RIPEMD160) && \
!defined(MBEDTLS_MD_CAN_SHA1) && \
!defined(MBEDTLS_MD_CAN_SHA224) && \
!defined(MBEDTLS_MD_CAN_SHA256) && \
!defined(MBEDTLS_MD_CAN_SHA384) && \
!defined(MBEDTLS_MD_CAN_SHA512) && \
!defined(MBEDTLS_MD_CAN_SHA3_224) && \
!defined(MBEDTLS_MD_CAN_SHA3_256) && \
!defined(MBEDTLS_MD_CAN_SHA3_384) && \
!defined(MBEDTLS_MD_CAN_SHA3_512)
#error "MBEDTLS_MD_C defined, but no hash algorithm"
#endif
#if defined(MBEDTLS_LMS_C) && \
! ( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) )
! ( defined(MBEDTLS_PSA_CRYPTO_CLIENT) && defined(PSA_WANT_ALG_SHA_256) )
#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
#endif
@@ -410,10 +419,6 @@
#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
@@ -423,15 +428,21 @@
#endif
#if defined(MBEDTLS_PK_C) && \
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C)
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_PK_HAVE_ECC_KEYS)
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#if defined(MBEDTLS_PK_PARSE_C) && \
(!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_OID_C) || \
!defined(MBEDTLS_PK_C))
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#if defined(MBEDTLS_PK_WRITE_C) && \
(!defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_OID_C) || \
!defined(MBEDTLS_PK_C))
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
@@ -475,6 +486,16 @@
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_MS_TIME_ALT) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_MS_TIME_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
@@ -659,7 +680,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
@@ -742,64 +764,50 @@
#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
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_USE_PSA_CRYPTO) && \
!( defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
/* TLS 1.3 requires separate HKDF parts from PSA */
/* TLS 1.3 requires separate HKDF parts from PSA,
* and at least one ciphersuite, so at least SHA-256 or SHA-384
* from PSA to use with HKDF.
*
* Note: for dependencies common with TLS 1.2 (running handshake hash),
* see MBEDTLS_SSL_TLS_C. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
!( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_HKDF_EXTRACT) && defined(PSA_WANT_ALG_HKDF_EXPAND) )
!(defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
defined(PSA_WANT_ALG_HKDF_EXTRACT) && \
defined(PSA_WANT_ALG_HKDF_EXPAND) && \
(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)))
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
#endif
/* TLS 1.3 requires at least one ciphersuite, so at least SHA-256 or SHA-384 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* We always need at least one of the hashes via PSA (for use with HKDF) */
#if !( defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384) )
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
#endif /* !(PSA_WANT_ALG_SHA_256 || PSA_WANT_ALG_SHA_384) */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
/* When USE_PSA_CRYPTO is not defined, we also need SHA-256 or SHA-384 via the
* legacy interface, including via the MD layer, for the parts of the code
* that are shared with TLS 1.2 (running handshake hash). */
#if !defined(MBEDTLS_MD_C) || \
!( defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA384_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
#endif /* !MBEDTLS_MD_C || !(MBEDTLS_SHA256_C || MBEDTLS_SHA384_C) */
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
#if !( defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
( defined(MBEDTLS_PK_HAVE_ECDSA) || defined(MBEDTLS_PKCS1_V21) ) )
#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
defined(MBEDTLS_X509_CRT_PARSE_C) && \
( defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || defined(MBEDTLS_PKCS1_V21) ) )
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites"
#endif
#endif
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
#if !( defined(MBEDTLS_ECDH_C) )
#if !( defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) )
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites"
#endif
#endif
@@ -835,10 +843,10 @@
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) && \
( !defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) || \
( MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0 ) || \
( MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX ) )
#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE MUST be defined and in range(0..UINT32_MAX)"
defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) && \
((MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0) || \
(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX))
#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE must be in the range(0..UINT32_MAX)"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
@@ -854,11 +862,25 @@
#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
#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
/* TLS 1.2 and 1.3 require SHA-256 or SHA-384 (running handshake hash) */
#if defined(MBEDTLS_SSL_TLS_C)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if !(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384))
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(MBEDTLS_MD_C) || \
!(defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA384))
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
@@ -933,7 +955,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
@@ -951,22 +974,20 @@
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#define MBEDTLS_THREADING_IMPL // undef at the end of this paragraph
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#undef MBEDTLS_THREADING_IMPL // temporary macro defined above
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
#endif
@@ -974,15 +995,15 @@
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
#if defined(MBEDTLS_X509_USE_C) && \
(!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) || \
( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
#if defined(MBEDTLS_X509_CREATE_C) && \
(!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_PARSE_C) || \
( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
@@ -1034,7 +1055,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
@@ -1087,16 +1110,12 @@
#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \
( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLS_PK_PARSE_C) ) || \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) ||\
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || ( !defined(MBEDTLS_BIGNUM_C) ) || \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || \
( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || \
( !defined(MBEDTLS_MD_C) ) )
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
#endif
/* Undefine helper symbols */
#undef MBEDTLS_PK_HAVE_ECDSA
#undef MBEDTLS_PK_HAVE_JPAKE
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
+54 -62
View File
@@ -9,19 +9,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CIPHER_H
@@ -270,45 +258,58 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
* mbedtls_cipher_info_from_type(),
* mbedtls_cipher_info_from_values(),
* mbedtls_cipher_info_from_psa().
*
* \note Some fields store a value that has been right-shifted to save
* code-size, so should not be used directly. The accessor
* functions adjust for this and return the "natural" value.
*/
typedef struct mbedtls_cipher_info_t {
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
mbedtls_cipher_type_t MBEDTLS_PRIVATE(type);
/** The cipher mode. For example, MBEDTLS_MODE_CBC. */
mbedtls_cipher_mode_t MBEDTLS_PRIVATE(mode);
/** The cipher key length, in bits. This is the
* default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int MBEDTLS_PRIVATE(key_bitlen);
/** Name of the cipher. */
const char *MBEDTLS_PRIVATE(name);
/** IV or nonce size, in Bytes.
/** The block size, in bytes. */
unsigned int MBEDTLS_PRIVATE(block_size) : 5;
/** IV or nonce size, in bytes (right shifted by #MBEDTLS_IV_SIZE_SHIFT).
* For ciphers that accept variable IV sizes,
* this is the recommended size.
*/
unsigned int MBEDTLS_PRIVATE(iv_size);
unsigned int MBEDTLS_PRIVATE(iv_size) : 3;
/** The cipher key length, in bits (right shifted by #MBEDTLS_KEY_BITLEN_SHIFT).
* This is the default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int MBEDTLS_PRIVATE(key_bitlen) : 4;
/** The cipher mode (as per mbedtls_cipher_mode_t).
* For example, MBEDTLS_MODE_CBC.
*/
unsigned int MBEDTLS_PRIVATE(mode) : 4;
/** Full cipher identifier (as per mbedtls_cipher_type_t).
* For example, MBEDTLS_CIPHER_AES_256_CBC.
*
* This could be 7 bits, but 8 bits retains byte alignment for the
* next field, which reduces code size to access that field.
*/
unsigned int MBEDTLS_PRIVATE(type) : 8;
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
* cipher supports variable IV or variable key sizes, respectively.
*/
int MBEDTLS_PRIVATE(flags);
unsigned int MBEDTLS_PRIVATE(flags) : 2;
/** The block size, in Bytes. */
unsigned int MBEDTLS_PRIVATE(block_size);
/** Struct for base cipher information and functions. */
const mbedtls_cipher_base_t *MBEDTLS_PRIVATE(base);
/** Index to LUT for base cipher information and functions. */
unsigned int MBEDTLS_PRIVATE(base_idx) : 5;
} mbedtls_cipher_info_t;
/* For internal use only.
* These are used to more compactly represent the fields above. */
#define MBEDTLS_KEY_BITLEN_SHIFT 6
#define MBEDTLS_IV_SIZE_SHIFT 2
/**
* Generic cipher context.
*/
@@ -353,7 +354,7 @@ typedef struct mbedtls_cipher_context_t {
mbedtls_cmac_context_t *MBEDTLS_PRIVATE(cmac_ctx);
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED)
/** Indicates whether the cipher operations should be performed
* by Mbed TLS' own crypto library or an external implementation
* of the PSA Crypto API.
@@ -362,7 +363,7 @@ typedef struct mbedtls_cipher_context_t {
* mbedtls_cipher_setup_psa().
*/
unsigned char MBEDTLS_PRIVATE(psa_enabled);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */
} mbedtls_cipher_context_t;
@@ -439,7 +440,7 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type(
if (info == NULL) {
return MBEDTLS_CIPHER_NONE;
} else {
return info->MBEDTLS_PRIVATE(type);
return (mbedtls_cipher_type_t) info->MBEDTLS_PRIVATE(type);
}
}
@@ -458,7 +459,7 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode(
if (info == NULL) {
return MBEDTLS_MODE_NONE;
} else {
return info->MBEDTLS_PRIVATE(mode);
return (mbedtls_cipher_mode_t) info->MBEDTLS_PRIVATE(mode);
}
}
@@ -479,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);
return ((size_t) info->MBEDTLS_PRIVATE(key_bitlen)) << MBEDTLS_KEY_BITLEN_SHIFT;
}
}
@@ -492,7 +493,7 @@ static inline size_t mbedtls_cipher_info_get_key_bitlen(
*
* \return The cipher name, which is a human readable string,
* with static storage duration.
* \return \c NULL if \c info is \p NULL.
* \return \c NULL if \p info is \c NULL.
*/
static inline const char *mbedtls_cipher_info_get_name(
const mbedtls_cipher_info_t *info)
@@ -521,7 +522,7 @@ static inline size_t mbedtls_cipher_info_get_iv_size(
return 0;
}
return (size_t) info->MBEDTLS_PRIVATE(iv_size);
return ((size_t) info->MBEDTLS_PRIVATE(iv_size)) << MBEDTLS_IV_SIZE_SHIFT;
}
/**
@@ -541,7 +542,7 @@ static inline size_t mbedtls_cipher_info_get_block_size(
return 0;
}
return (size_t) info->MBEDTLS_PRIVATE(block_size);
return (size_t) (info->MBEDTLS_PRIVATE(block_size));
}
/**
@@ -583,7 +584,7 @@ static inline int mbedtls_cipher_info_has_variable_iv_size(
}
/**
* \brief This function initializes a \p cipher_context as NONE.
* \brief This function initializes a \p ctx as NONE.
*
* \param ctx The context to be initialized. This must not be \c NULL.
*/
@@ -677,12 +678,11 @@ int MBEDTLS_DEPRECATED mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx,
static inline unsigned int mbedtls_cipher_get_block_size(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size);
return (unsigned int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size);
}
/**
@@ -697,12 +697,11 @@ static inline unsigned int mbedtls_cipher_get_block_size(
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, MBEDTLS_MODE_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_MODE_NONE;
}
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode);
return (mbedtls_cipher_mode_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode);
}
/**
@@ -718,7 +717,6 @@ static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
static inline int mbedtls_cipher_get_iv_size(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
@@ -727,7 +725,8 @@ static inline int mbedtls_cipher_get_iv_size(
return (int) ctx->MBEDTLS_PRIVATE(iv_size);
}
return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size);
return (int) (((int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size)) <<
MBEDTLS_IV_SIZE_SHIFT);
}
/**
@@ -741,13 +740,11 @@ static inline int mbedtls_cipher_get_iv_size(
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_CIPHER_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_CIPHER_NONE;
}
return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type);
return (mbedtls_cipher_type_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type);
}
/**
@@ -762,7 +759,6 @@ static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
static inline const char *mbedtls_cipher_get_name(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return 0;
}
@@ -776,19 +772,18 @@ static inline const char *mbedtls_cipher_get_name(
* \param ctx The context of the cipher. This must be initialized.
*
* \return The key length of the cipher in bits.
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* \return #MBEDTLS_KEY_LENGTH_NONE if \p ctx has not been
* initialized.
*/
static inline int mbedtls_cipher_get_key_bitlen(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_KEY_LENGTH_NONE;
}
return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen);
return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen) <<
MBEDTLS_KEY_BITLEN_SHIFT;
}
/**
@@ -802,8 +797,6 @@ static inline int mbedtls_cipher_get_key_bitlen(
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
const mbedtls_cipher_context_t *ctx)
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_OPERATION_NONE);
if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) {
return MBEDTLS_OPERATION_NONE;
}
@@ -837,7 +830,6 @@ int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx,
* \brief This function sets the padding mode, for cipher modes
* that use padding.
*
* The default passing mode is PKCS7 padding.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
@@ -975,7 +967,7 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param output The buffer to write data to. This needs to be a writable
* buffer of at least \p block_size Bytes.
* buffer of at least block_size Bytes.
* \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
*
+24 -17
View File
@@ -5,22 +5,11 @@
*
* The Cipher-based Message Authentication Code (CMAC) Mode for
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
* It is supported with AES and DES.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CMAC_H
@@ -38,12 +27,30 @@ extern "C" {
#define MBEDTLS_AES_BLOCK_SIZE 16
#define MBEDTLS_DES3_BLOCK_SIZE 8
/* We don't support Camellia or ARIA in this module */
#if defined(MBEDTLS_AES_C)
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16 /**< The longest block used by CMAC is that of AES. */
#else
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 8 /**< The longest block used by CMAC is that of 3DES. */
#endif
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/** The longest block supported by the cipher module.
*
* \deprecated
* For the maximum block size of a cipher supported by the CMAC module,
* use #MBEDTLS_CMAC_MAX_BLOCK_SIZE.
* For the maximum block size of a cipher supported by the cipher module,
* use #MBEDTLS_MAX_BLOCK_LENGTH.
*/
/* Before Mbed TLS 3.5, this was the maximum block size supported by the CMAC
* module, so it didn't take Camellia or ARIA into account. Since the name
* of the macro doesn't even convey "CMAC", this was misleading. Now the size
* is sufficient for any cipher, but the name is defined in cmac.h for
* backward compatibility. */
#define MBEDTLS_CIPHER_BLKSIZE_MAX MBEDTLS_MAX_BLOCK_LENGTH
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#if !defined(MBEDTLS_CMAC_ALT)
/**
@@ -51,11 +58,11 @@ extern "C" {
*/
struct mbedtls_cmac_context_t {
/** The internal state of the CMAC algorithm. */
unsigned char MBEDTLS_PRIVATE(state)[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char MBEDTLS_PRIVATE(state)[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
/** Unprocessed data - either data that was not block aligned and is still
* pending processing, or the final block. */
unsigned char MBEDTLS_PRIVATE(unprocessed_block)[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char MBEDTLS_PRIVATE(unprocessed_block)[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
/** The length of data pending processing. */
size_t MBEDTLS_PRIVATE(unprocessed_len);
@@ -0,0 +1,457 @@
/**
* \file mbedtls/config_adjust_legacy_crypto.h
* \brief Adjust legacy configuration configuration
*
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
* configurations need to be explicitly enabled by the user: enabling
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
* compilation error. However, we do automatically enable certain options
* in some circumstances. One case is if MBEDTLS_xxx_B is an internal option
* used to identify parts of a module that are used by other module, and we
* don't want to make the symbol MBEDTLS_xxx_B part of the public API.
* Another case is if A didn't depend on B in earlier versions, and we
* want to use B in A but we need to preserve backward compatibility with
* configurations that explicitly activate MBEDTLS_xxx_A but not
* MBEDTLS_xxx_B.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
/* Ideally, we'd set those as defaults in mbedtls_config.h, but
* putting an #ifdef _WIN32 in mbedtls_config.h would confuse config.py.
*
* So, adjust it here.
* Not related to crypto, but this is the bottom of the stack. */
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
#endif
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
/* 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.
*/
#if defined(MBEDTLS_MD_C)
#define MBEDTLS_MD_LIGHT
#endif
/* Auto-enable MBEDTLS_MD_LIGHT if needed by a module that didn't require it
* in a previous release, to ensure backwards compatibility.
*/
#if defined(MBEDTLS_ECJPAKE_C) || \
defined(MBEDTLS_PEM_PARSE_C) || \
defined(MBEDTLS_ENTROPY_C) || \
defined(MBEDTLS_PK_C) || \
defined(MBEDTLS_PKCS12_C) || \
defined(MBEDTLS_RSA_C) || \
defined(MBEDTLS_SSL_TLS_C) || \
defined(MBEDTLS_X509_USE_C) || \
defined(MBEDTLS_X509_CREATE_C)
#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
* some reason, then MBEDTLS_ECP_LIGHT should be enabled as well.
* - MBEDTLS_PK_PARSE_EC_EXTENDED and MBEDTLS_PK_PARSE_EC_COMPRESSED because
* these features are not supported in PSA so the only way to have them is
* to enable the built-in solution.
* Both of them are temporary dependencies:
* - PK_PARSE_EC_EXTENDED will be removed after #7779 and #7789
* - support for compressed points should also be added to PSA, but in this
* case there is no associated issue to track it yet.
* - PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE because Weierstrass key derivation
* still depends on ECP_LIGHT.
* - PK_C + USE_PSA + PSA_WANT_ALG_ECDSA is a temporary dependency which will
* be fixed by #7453.
*/
#if defined(MBEDTLS_ECP_C) || \
defined(MBEDTLS_PK_PARSE_EC_EXTENDED) || \
defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#define MBEDTLS_ECP_LIGHT
#endif
/* 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
* are met. */
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_PARSE_EC_COMPRESSED
#endif
/* Helper symbol to state that there is support for ECDH, either through
* library implementation (ECDH_C) or through PSA. */
#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \
(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C))
#define MBEDTLS_CAN_ECDH
#endif
/* PK module can achieve ECDSA functionalities by means of either software
* implementations (ECDSA_C) or through a PSA driver. The following defines
* are meant to list these capabilities in a general way which abstracts how
* they are implemented under the hood. */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif /* MBEDTLS_ECDSA_C */
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(PSA_WANT_ALG_ECDSA)
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* PSA_WANT_ALG_ECDSA */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
*/
#if defined(MBEDTLS_PSA_CRYPTO_C)
#define MBEDTLS_PSA_CRYPTO_CLIENT
#endif /* MBEDTLS_PSA_CRYPTO_C */
/* Helpers to state that each key is supported either on the builtin or PSA side. */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
#define MBEDTLS_ECP_HAVE_SECP521R1
#endif
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#define MBEDTLS_ECP_HAVE_BP512R1
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_448)
#define MBEDTLS_ECP_HAVE_CURVE448
#endif
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#define MBEDTLS_ECP_HAVE_BP384R1
#endif
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_384)
#define MBEDTLS_ECP_HAVE_SECP384R1
#endif
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#define MBEDTLS_ECP_HAVE_BP256R1
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_256)
#define MBEDTLS_ECP_HAVE_SECP256K1
#endif
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_256)
#define MBEDTLS_ECP_HAVE_SECP256R1
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_255)
#define MBEDTLS_ECP_HAVE_CURVE25519
#endif
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_224)
#define MBEDTLS_ECP_HAVE_SECP224K1
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_224)
#define MBEDTLS_ECP_HAVE_SECP224R1
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_192)
#define MBEDTLS_ECP_HAVE_SECP192K1
#endif
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_192)
#define MBEDTLS_ECP_HAVE_SECP192R1
#endif
/* Helper symbol to state that the PK module has support for EC keys. This
* can either be provided through the legacy ECP solution or through the
* PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA (see pk.h for its description). */
#if defined(MBEDTLS_ECP_C) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY))
#define MBEDTLS_PK_HAVE_ECC_KEYS
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */
/* Historically pkparse did not check the CBC padding when decrypting
* a key. This was a bug, which is now fixed. As a consequence, pkparse
* now needs PKCS7 padding support, but existing configurations might not
* enable it, so we enable it here. */
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PKCS5_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
#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
/* psa_util file features some ECDSA conversion functions, to convert between
* legacy's ASN.1 DER format and PSA's raw one. */
#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \
(defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)))
#define MBEDTLS_PSA_UTIL_HAVE_ECDSA
#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 */
@@ -0,0 +1,888 @@
/**
* \file mbedtls/config_adjust_legacy_from_psa.h
* \brief Adjust PSA configuration: activate legacy implementations
*
* When MBEDTLS_PSA_CRYPTO_CONFIG is enabled, activate legacy implementations
* of cryptographic mechanisms as needed to fulfill the needs of the PSA
* configuration. Generally speaking, we activate a legacy mechanism if
* it's needed for a requested PSA mechanism and there is no PSA driver
* for it.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
/* Define appropriate ACCEL macros for the p256-m driver.
* In the future, those should be generated from the drivers JSON description.
*/
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
#define MBEDTLS_PSA_ACCEL_ALG_ECDH
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE
#endif
/*
* ECC: support for a feature is controlled by a triplet or a pair:
* (curve, key_type public/basic, alg) or (curve, key_type_<action>).
*
* A triplet/pair is accelerated if all of is components are accelerated;
* otherwise each component needs to be built in.
*
* We proceed in two passes:
* 1. Check if acceleration is complete for curves, key types, algs.
* 2. Then enable built-ins for each thing that's either not accelerated of
* doesn't have complete acceleration of the other triplet/pair components.
*
* Note: this needs psa/crypto_adjust_keypair_types.h to have been included
* already, so that we know the full set of key types that are requested.
*/
/* ECC: curves: is acceleration complete? */
#if (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)) || \
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)) || \
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)) || \
(defined(PSA_WANT_ECC_SECP_R1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)) || \
(defined(PSA_WANT_ECC_SECP_R1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)) || \
(defined(PSA_WANT_ECC_SECP_R1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)) || \
(defined(PSA_WANT_ECC_SECP_R1_384) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)) || \
(defined(PSA_WANT_ECC_SECP_R1_521) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)) || \
(defined(PSA_WANT_ECC_SECP_K1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)) || \
(defined(PSA_WANT_ECC_SECP_K1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224)) || \
(defined(PSA_WANT_ECC_SECP_K1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
#endif
#if (defined(PSA_WANT_ECC_MONTGOMERY_255) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)) || \
(defined(PSA_WANT_ECC_MONTGOMERY_448) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
#endif
/* ECC: algs: is acceleration complete? */
#if (defined(PSA_WANT_ALG_ECDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)) || \
(defined(PSA_WANT_ALG_ECDSA) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)) || \
(defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)) || \
(defined(PSA_WANT_ALG_JPAKE) && !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
#endif
/* ECC: key types: is acceleration complete? */
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC
#endif
/* Special case: we don't support cooked key derivation in drivers yet */
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE
#endif
/* Note: the condition about key derivation is always true as DERIVE can't be
* accelerated yet */
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE)) || \
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE))
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
#endif
/* ECC: curves: enable built-ins as needed.
*
* We need the curve built-in:
* - if it's not accelerated, or
* - if there's a key type with missing acceleration, or
* - if there's a alg with missing acceleration.
*/
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_MONTGOMERY_255 */
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_MONTGOMERY_448 */
#if defined(PSA_WANT_ECC_SECP_R1_192)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_R1_192 */
#if defined(PSA_WANT_ECC_SECP_R1_224)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_R1_224 */
#if defined(PSA_WANT_ECC_SECP_R1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_R1_256 */
#if defined(PSA_WANT_ECC_SECP_R1_384)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_R1_384 */
#if defined(PSA_WANT_ECC_SECP_R1_521)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_R1_521 */
#if defined(PSA_WANT_ECC_SECP_K1_192)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_K1_192 */
#if defined(PSA_WANT_ECC_SECP_K1_224)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
/* https://github.com/Mbed-TLS/mbedtls/issues/3541 */
#error "SECP224K1 is buggy via the PSA API in Mbed TLS."
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_K1_224 */
#if defined(PSA_WANT_ECC_SECP_K1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#endif /* missing accel */
#endif /* PSA_WANT_ECC_SECP_K1_256 */
/* ECC: algs: enable built-ins as needed.
*
* We need the alg built-in:
* - if it's not accelerated, or
* - if there's a relevant curve (see below) with missing acceleration, or
* - if there's a key type among (public, basic) with missing acceleration.
*
* Relevant curves are:
* - all curves for ECDH
* - Weierstrass curves for (deterministic) ECDSA
* - secp256r1 for EC J-PAKE
*/
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
#define MBEDTLS_ECDSA_DETERMINISTIC
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* missing accel */
#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */
#if defined(PSA_WANT_ALG_ECDH)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* missing accel */
#endif /* PSA_WANT_ALG_ECDH */
#if defined(PSA_WANT_ALG_ECDSA)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* missing accel */
#endif /* PSA_WANT_ALG_ECDSA */
#if defined(PSA_WANT_ALG_JPAKE)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE) || \
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
#define MBEDTLS_PSA_BUILTIN_PAKE 1
#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECJPAKE_C
#endif /* missing accel */
#endif /* PSA_WANT_ALG_JPAKE */
/* ECC: key types: enable built-ins as needed.
*
* We need the key type built-in:
* - if it's not accelerated, or
* - if there's a curve with missing acceleration, or
* - only for public/basic: if there's an alg with missing acceleration.
*/
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
#endif /* missing accel */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
/* Note: the condition is always true as DERIVE can't be accelerated yet */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#endif /* missing accel */
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#define MBEDTLS_ECP_LIGHT
#define MBEDTLS_BIGNUM_C
#endif
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif
/* End of ECC section */
/*
* DH key types follow the same pattern used above for EC keys. They are defined
* by a triplet (group, key_type, alg). A triplet is accelerated if all its
* component are accelerated, otherwise each component needs to be builtin.
*/
/* DH: groups: is acceleration complete? */
#if (defined(PSA_WANT_DH_RFC7919_2048) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048)) || \
(defined(PSA_WANT_DH_RFC7919_3072) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072)) || \
(defined(PSA_WANT_DH_RFC7919_4096) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096)) || \
(defined(PSA_WANT_DH_RFC7919_6144) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144)) || \
(defined(PSA_WANT_DH_RFC7919_8192) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192))
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS
#endif
/* DH: algs: is acceleration complete? */
#if defined(PSA_WANT_ALG_FFDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH)
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS
#endif
/* DH: key types: is acceleration complete? */
#if (defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT)) || \
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) && \
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE))
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES
#endif
#if defined(PSA_WANT_DH_RFC7919_2048)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
#endif /* PSA_WANT_DH_RFC7919_2048 */
#if defined(PSA_WANT_DH_RFC7919_3072)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
#endif /* PSA_WANT_DH_RFC7919_3072 */
#if defined(PSA_WANT_DH_RFC7919_4096)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
#endif /* PSA_WANT_DH_RFC7919_4096 */
#if defined(PSA_WANT_DH_RFC7919_6144)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
#endif /* PSA_WANT_DH_RFC7919_6144 */
#if defined(PSA_WANT_DH_RFC7919_8192)
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
#endif /* PSA_WANT_DH_RFC7919_8192 */
#if defined(PSA_WANT_ALG_FFDH)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */
#endif /* PSA_WANT_ALG_FFDH */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */
/* End of DH section */
#if defined(PSA_WANT_ALG_HKDF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
/*
* The PSA implementation has its own implementation of HKDF, separate from
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
*/
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */
#endif /* PSA_WANT_ALG_HKDF */
#if defined(PSA_WANT_ALG_HKDF_EXTRACT)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT)
/*
* The PSA implementation has its own implementation of HKDF, separate from
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
*/
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */
#endif /* PSA_WANT_ALG_HKDF_EXTRACT */
#if defined(PSA_WANT_ALG_HKDF_EXPAND)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND)
/*
* The PSA implementation has its own implementation of HKDF, separate from
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
*/
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */
#endif /* PSA_WANT_ALG_HKDF_EXPAND */
#if defined(PSA_WANT_ALG_HMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
#endif /* PSA_WANT_ALG_HMAC */
#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
#define MBEDTLS_MD5_C
#endif
#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
#define MBEDTLS_RIPEMD160_C
#endif
#if defined(PSA_WANT_ALG_RSA_OAEP)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V21
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */
#endif /* PSA_WANT_ALG_RSA_OAEP */
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V15
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V15
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */
#if defined(PSA_WANT_ALG_RSA_PSS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V21
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */
#endif /* PSA_WANT_ALG_RSA_PSS */
#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
#define MBEDTLS_SHA1_C
#endif
#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
#define MBEDTLS_SHA224_C
#endif
#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
#define MBEDTLS_SHA256_C
#endif
#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
#define MBEDTLS_SHA384_C
#endif
#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
#define MBEDTLS_SHA512_C
#endif
#if defined(PSA_WANT_ALG_SHA3_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1
#define MBEDTLS_SHA3_C
#endif
#if defined(PSA_WANT_ALG_SHA3_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1
#define MBEDTLS_SHA3_C
#endif
#if defined(PSA_WANT_ALG_SHA3_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1
#define MBEDTLS_SHA3_C
#endif
#if defined(PSA_WANT_ALG_SHA3_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1
#define MBEDTLS_SHA3_C
#endif
#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1
#define PSA_HAVE_SOFT_PBKDF2_HMAC 1
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
#if defined(PSA_WANT_ALG_TLS12_PRF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */
#endif /* PSA_WANT_ALG_TLS12_PRF */
#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */
#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS */
#endif /* PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#define MBEDTLS_GENPRIME
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
/* If any of the block modes are requested that don't have an
* associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking
* in the block cipher key types. */
#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(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_PBKDF2_AES_CMAC_PRF_128)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128)
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 1
#define PSA_HAVE_SOFT_PBKDF2_CMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128 */
#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */
#if defined(PSA_WANT_KEY_TYPE_AES)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
#define PSA_HAVE_SOFT_KEY_TYPE_AES 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
defined(PSA_HAVE_SOFT_BLOCK_MODE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
#define MBEDTLS_AES_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_AES */
#if defined(PSA_WANT_KEY_TYPE_ARIA)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
#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)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
#define MBEDTLS_ARIA_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_ARIA */
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
#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)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
#define MBEDTLS_CAMELLIA_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
#if defined(PSA_WANT_KEY_TYPE_DES)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES)
#define PSA_HAVE_SOFT_KEY_TYPE_DES 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
defined(PSA_HAVE_SOFT_BLOCK_MODE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
#define MBEDTLS_DES_C
#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) || \
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 */
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
/* If any of the software block ciphers are selected, define
* PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these
* situations. */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
#define PSA_HAVE_SOFT_BLOCK_CIPHER 1
#endif
#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."
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_MAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CBC_MAC */
#endif /* PSA_WANT_ALG_CBC_MAC */
#if defined(PSA_WANT_ALG_CMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
#define MBEDTLS_CMAC_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */
#endif /* PSA_WANT_ALG_CMAC */
#if defined(PSA_HAVE_SOFT_PBKDF2_HMAC) || \
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
#define PSA_HAVE_SOFT_PBKDF2 1
#endif /* PSA_HAVE_SOFT_PBKDF2_HMAC || PSA_HAVE_SOFT_PBKDF2_CMAC */
#if defined(PSA_WANT_ALG_CTR)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
#define MBEDTLS_CIPHER_MODE_CTR
#endif
#endif /* PSA_WANT_ALG_CTR */
#if defined(PSA_WANT_ALG_CFB)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
#define MBEDTLS_CIPHER_MODE_CFB
#endif
#endif /* PSA_WANT_ALG_CFB */
#if defined(PSA_WANT_ALG_OFB)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
#define MBEDTLS_CIPHER_MODE_OFB
#endif
#endif /* PSA_WANT_ALG_OFB */
#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
#endif
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
#endif
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
#if defined(PSA_WANT_ALG_CBC_PKCS7)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
#define MBEDTLS_CIPHER_PADDING_PKCS7
#endif
#endif /* PSA_WANT_ALG_CBC_PKCS7 */
#if defined(PSA_WANT_ALG_CCM)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \
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 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) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
#define MBEDTLS_GCM_C
#endif
#endif /* PSA_WANT_ALG_GCM */
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305)
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
#define MBEDTLS_CHACHAPOLY_C
#define MBEDTLS_CHACHA20_C
#define MBEDTLS_POLY1305_C
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305 */
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H */
@@ -0,0 +1,349 @@
/**
* \file mbedtls/config_adjust_psa_from_legacy.h
* \brief Adjust PSA configuration: construct PSA configuration from legacy
*
* When MBEDTLS_PSA_CRYPTO_CONFIG is disabled, we automatically enable
* cryptographic mechanisms through the PSA interface when the corresponding
* legacy mechanism is enabled. In many cases, this just enables the PSA
* wrapper code around the legacy implementation, but we also do this for
* some mechanisms where PSA has its own independent implementation so
* that high-level modules that can use either cryptographic API have the
* same feature set in both cases.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H
#define MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H
/*
* Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG
* is not defined
*/
#if defined(MBEDTLS_CCM_C)
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 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)
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
#define PSA_WANT_ALG_CMAC 1
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_ECDH_C)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
#define PSA_WANT_ALG_ECDH 1
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
#define PSA_WANT_ALG_ECDSA 1
#define PSA_WANT_ALG_ECDSA_ANY 1
// Only add in DETERMINISTIC support if ECDSA is also enabled
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_ECP_C)
#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
/* Normally we wouldn't enable this because it's not implemented in ecp.c,
* but since it used to be available any time ECP_C was enabled, let's enable
* it anyway for the sake of backwards compatibility */
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
/* See comment for PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE above. */
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_DHM_C)
#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_PUBLIC_KEY 1
#define PSA_WANT_ALG_FFDH 1
#define PSA_WANT_DH_RFC7919_2048 1
#define PSA_WANT_DH_RFC7919_3072 1
#define PSA_WANT_DH_RFC7919_4096 1
#define PSA_WANT_DH_RFC7919_6144 1
#define PSA_WANT_DH_RFC7919_8192 1
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_GCM_C)
#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
#define PSA_WANT_ALG_GCM 1
#endif /* MBEDTLS_GCM_C */
/* Enable PSA HKDF algorithm if mbedtls HKDF is supported.
* PSA HKDF EXTRACT and PSA HKDF EXPAND have minimal cost when
* PSA HKDF is enabled, so enable both algorithms together
* with PSA HKDF. */
#if defined(MBEDTLS_HKDF_C)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define PSA_WANT_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
#define PSA_WANT_ALG_HKDF 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
#define PSA_WANT_ALG_HKDF_EXTRACT 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
#define PSA_WANT_ALG_HKDF_EXPAND 1
#endif /* MBEDTLS_HKDF_C */
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define PSA_WANT_ALG_HMAC 1
#define PSA_WANT_KEY_TYPE_HMAC 1
#if defined(MBEDTLS_MD_C)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_MD5_C)
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
#define PSA_WANT_ALG_MD5 1
#endif
#if defined(MBEDTLS_ECJPAKE_C)
#define MBEDTLS_PSA_BUILTIN_PAKE 1
#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
#define PSA_WANT_ALG_JPAKE 1
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
#define PSA_WANT_ALG_RIPEMD160 1
#endif
#if defined(MBEDTLS_RSA_C)
#if defined(MBEDTLS_PKCS1_V15)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
#define PSA_WANT_ALG_RSA_OAEP 1
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define PSA_WANT_ALG_RSA_PSS 1
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_GENPRIME)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
#endif /* MBEDTLS_GENPRIME */
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
#define 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 MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SHA1_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
#define PSA_WANT_ALG_SHA_1 1
#endif
#if defined(MBEDTLS_SHA224_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
#define PSA_WANT_ALG_SHA_224 1
#endif
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
#define PSA_WANT_ALG_SHA_256 1
#endif
#if defined(MBEDTLS_SHA384_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
#define PSA_WANT_ALG_SHA_384 1
#endif
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
#define PSA_WANT_ALG_SHA_512 1
#endif
#if defined(MBEDTLS_SHA3_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1
#define PSA_WANT_ALG_SHA3_224 1
#define PSA_WANT_ALG_SHA3_256 1
#define PSA_WANT_ALG_SHA3_384 1
#define PSA_WANT_ALG_SHA3_512 1
#endif
#if defined(MBEDTLS_AES_C)
#define PSA_WANT_KEY_TYPE_AES 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
#endif
#if defined(MBEDTLS_ARIA_C)
#define PSA_WANT_KEY_TYPE_ARIA 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#define PSA_WANT_KEY_TYPE_CAMELLIA 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
#endif
#if defined(MBEDTLS_DES_C)
#define PSA_WANT_KEY_TYPE_DES 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1
#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1
#endif
#if defined(MBEDTLS_CHACHA20_C)
#define PSA_WANT_KEY_TYPE_CHACHA20 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
#endif
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
#define PSA_WANT_ALG_CBC_NO_PADDING 1
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
#define PSA_WANT_ALG_CBC_PKCS7 1
#endif
#endif
#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
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
#define PSA_WANT_ALG_CFB 1
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
#define PSA_WANT_ALG_CTR 1
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
#define PSA_WANT_ALG_OFB 1
#endif
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
#endif
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
#endif
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1
#define PSA_WANT_ECC_MONTGOMERY_255 1
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1
#define PSA_WANT_ECC_MONTGOMERY_448 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1
#define PSA_WANT_ECC_SECP_R1_192 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1
#define PSA_WANT_ECC_SECP_R1_224 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1
#define PSA_WANT_ECC_SECP_R1_256 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1
#define PSA_WANT_ECC_SECP_R1_384 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1
#define PSA_WANT_ECC_SECP_R1_521 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1
#define PSA_WANT_ECC_SECP_K1_192 1
#endif
/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */
#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1
#define PSA_WANT_ECC_SECP_K1_224 1
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1
#define PSA_WANT_ECC_SECP_K1_256 1
#endif
#endif /* MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H */
@@ -0,0 +1,142 @@
/**
* \file mbedtls/config_adjust_psa_superset_legacy.h
* \brief Adjust PSA configuration: automatic enablement from legacy
*
* To simplify some edge cases, we automatically enable certain cryptographic
* mechanisms in the PSA API if they are enabled in the legacy API. The general
* idea is that if legacy module M uses mechanism A internally, and A has
* both a legacy and a PSA implementation, we enable A through PSA whenever
* it's enabled through legacy. This facilitates the transition to PSA
* implementations of A for users of M.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
#define MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
/****************************************************************/
/* Hashes that are built in are also enabled in PSA.
* This simplifies dependency declarations especially
* for modules that obey MBEDTLS_USE_PSA_CRYPTO. */
/****************************************************************/
#if defined(MBEDTLS_MD5_C)
#define PSA_WANT_ALG_MD5 1
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#define PSA_WANT_ALG_RIPEMD160 1
#endif
#if defined(MBEDTLS_SHA1_C)
#define PSA_WANT_ALG_SHA_1 1
#endif
#if defined(MBEDTLS_SHA224_C)
#define PSA_WANT_ALG_SHA_224 1
#endif
#if defined(MBEDTLS_SHA256_C)
#define PSA_WANT_ALG_SHA_256 1
#endif
#if defined(MBEDTLS_SHA384_C)
#define PSA_WANT_ALG_SHA_384 1
#endif
#if defined(MBEDTLS_SHA512_C)
#define PSA_WANT_ALG_SHA_512 1
#endif
#if defined(MBEDTLS_SHA3_C)
#define PSA_WANT_ALG_SHA3_224 1
#define PSA_WANT_ALG_SHA3_256 1
#define PSA_WANT_ALG_SHA3_384 1
#define PSA_WANT_ALG_SHA3_512 1
#endif
/* Ensure that the PSA's supported curves (PSA_WANT_ECC_xxx) are always a
* superset of the builtin ones (MBEDTLS_ECP_DP_xxx). */
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */
#endif /*MBEDTLS_ECP_DP_BP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#if !defined(PSA_WANT_ECC_MONTGOMERY_255)
#define PSA_WANT_ECC_MONTGOMERY_255 1
#endif /* PSA_WANT_ECC_MONTGOMERY_255 */
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#if !defined(PSA_WANT_ECC_MONTGOMERY_448)
#define PSA_WANT_ECC_MONTGOMERY_448 1
#endif /* PSA_WANT_ECC_MONTGOMERY_448 */
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_R1_192)
#define PSA_WANT_ECC_SECP_R1_192 1
#endif /* PSA_WANT_ECC_SECP_R1_192 */
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_R1_224)
#define PSA_WANT_ECC_SECP_R1_224 1
#endif /* PSA_WANT_ECC_SECP_R1_224 */
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_R1_256)
#define PSA_WANT_ECC_SECP_R1_256 1
#endif /* PSA_WANT_ECC_SECP_R1_256 */
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_R1_384)
#define PSA_WANT_ECC_SECP_R1_384 1
#endif /* PSA_WANT_ECC_SECP_R1_384 */
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_R1_521)
#define PSA_WANT_ECC_SECP_R1_521 1
#endif /* PSA_WANT_ECC_SECP_R1_521 */
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_K1_192)
#define PSA_WANT_ECC_SECP_K1_192 1
#endif /* PSA_WANT_ECC_SECP_K1_192 */
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */
#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_K1_224)
#define PSA_WANT_ECC_SECP_K1_224 1
#endif /* PSA_WANT_ECC_SECP_K1_224 */
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#if !defined(PSA_WANT_ECC_SECP_K1_256)
#define PSA_WANT_ECC_SECP_K1_256 1
#endif /* PSA_WANT_ECC_SECP_K1_256 */
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#endif /* MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H */
+81
View File
@@ -0,0 +1,81 @@
/**
* \file mbedtls/config_adjust_ssl.h
* \brief Adjust TLS configuration
*
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
* configurations need to be explicitly enabled by the user: enabling
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
* compilation error. However, we do automatically enable certain options
* in some circumstances. One case is if MBEDTLS_xxx_B is an internal option
* used to identify parts of a module that are used by other module, and we
* don't want to make the symbol MBEDTLS_xxx_B part of the public API.
* Another case is if A didn't depend on B in earlier versions, and we
* want to use B in A but we need to preserve backward compatibility with
* configurations that explicitly activate MBEDTLS_xxx_A but not
* MBEDTLS_xxx_B.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_SSL_H
#define MBEDTLS_CONFIG_ADJUST_SSL_H
/* The following blocks make it easier to disable all of TLS,
* or of TLS 1.2 or 1.3 or DTLS, without having to manually disable all
* key exchanges, options and extensions related to them. */
#if !defined(MBEDTLS_SSL_TLS_C)
#undef MBEDTLS_SSL_CLI_C
#undef MBEDTLS_SSL_SRV_C
#undef MBEDTLS_SSL_PROTO_TLS1_3
#undef MBEDTLS_SSL_PROTO_TLS1_2
#undef MBEDTLS_SSL_PROTO_DTLS
#endif
#if !(defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SESSION_TICKETS))
#undef MBEDTLS_SSL_TICKET_C
#endif
#if !defined(MBEDTLS_SSL_PROTO_DTLS)
#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID
#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY
#undef MBEDTLS_SSL_DTLS_SRTP
#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
#endif
#if !defined(MBEDTLS_SSL_PROTO_TLS1_2)
#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC
#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET
#undef MBEDTLS_SSL_RENEGOTIATION
#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
#undef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#endif
#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
#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) && \
(defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED))
#define MBEDTLS_SSL_TLS1_2_SOME_ECC
#endif
#endif /* MBEDTLS_CONFIG_ADJUST_SSL_H */
+25
View File
@@ -0,0 +1,25 @@
/**
* \file mbedtls/config_adjust_x509.h
* \brief Adjust X.509 configuration
*
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
* configurations need to be explicitly enabled by the user: enabling
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
* compilation error. However, we do automatically enable certain options
* in some circumstances. One case is if MBEDTLS_xxx_B is an internal option
* used to identify parts of a module that are used by other module, and we
* don't want to make the symbol MBEDTLS_xxx_B part of the public API.
* Another case is if A didn't depend on B in earlier versions, and we
* want to use B in A but we need to preserve backward compatibility with
* configurations that explicitly activate MBEDTLS_xxx_A but not
* MBEDTLS_xxx_B.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_ADJUST_X509_H
#define MBEDTLS_CONFIG_ADJUST_X509_H
#endif /* MBEDTLS_CONFIG_ADJUST_X509_H */
+19 -830
View File
@@ -12,855 +12,44 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CONFIG_PSA_H
#define MBEDTLS_CONFIG_PSA_H
#include "psa/crypto_legacy.h"
#include "psa/crypto_adjust_config_synonyms.h"
#include "mbedtls/config_adjust_psa_superset_legacy.h"
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
#else
#include "psa/crypto_config.h"
#endif
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE)
#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
#endif
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************/
/* De facto synonyms */
/****************************************************************/
#if defined(PSA_WANT_ALG_ECDSA_ANY) && !defined(PSA_WANT_ALG_ECDSA)
#define PSA_WANT_ALG_ECDSA PSA_WANT_ALG_ECDSA_ANY
#elif !defined(PSA_WANT_ALG_ECDSA_ANY) && defined(PSA_WANT_ALG_ECDSA)
#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)
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW PSA_WANT_ALG_RSA_PKCS1V15_SIGN
#endif
#if defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && !defined(PSA_WANT_ALG_RSA_PSS)
#define PSA_WANT_ALG_RSA_PSS PSA_WANT_ALG_RSA_PSS_ANY_SALT
#elif !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && defined(PSA_WANT_ALG_RSA_PSS)
#define PSA_WANT_ALG_RSA_PSS_ANY_SALT PSA_WANT_ALG_RSA_PSS
#endif
/****************************************************************/
/* Require built-in implementations based on PSA requirements */
/****************************************************************/
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
/* We need this to have a complete list of requirements
* before we deduce what built-ins are required. */
#include "psa/crypto_adjust_config_key_pair_types.h"
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
#define MBEDTLS_ECDSA_DETERMINISTIC
#define MBEDTLS_ECDSA_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA */
#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */
#if defined(PSA_WANT_ALG_ECDH)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDH */
#endif /* PSA_WANT_ALG_ECDH */
#if defined(PSA_WANT_ALG_ECDSA)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDSA */
#endif /* PSA_WANT_ALG_ECDSA */
#if defined(PSA_WANT_ALG_HKDF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */
#endif /* PSA_WANT_ALG_HKDF */
#if defined(PSA_WANT_ALG_HKDF_EXTRACT)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */
#endif /* PSA_WANT_ALG_HKDF_EXTRACT */
#if defined(PSA_WANT_ALG_HKDF_EXPAND)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */
#endif /* PSA_WANT_ALG_HKDF_EXPAND */
#if defined(PSA_WANT_ALG_HMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
#endif /* PSA_WANT_ALG_HMAC */
#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
#define MBEDTLS_MD5_C
#endif
#if defined(PSA_WANT_ALG_JPAKE)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE)
#define MBEDTLS_PSA_BUILTIN_PAKE 1
#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECJPAKE_C
#endif /* MBEDTLS_PSA_ACCEL_ALG_JPAKE */
#endif /* PSA_WANT_ALG_JPAKE */
#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
#define MBEDTLS_RIPEMD160_C
#endif
#if defined(PSA_WANT_ALG_RSA_OAEP)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V21
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */
#endif /* PSA_WANT_ALG_RSA_OAEP */
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V15
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V15
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */
#if defined(PSA_WANT_ALG_RSA_PSS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS1_V21
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */
#endif /* PSA_WANT_ALG_RSA_PSS */
#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
#define MBEDTLS_SHA1_C
#endif
#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
#define MBEDTLS_SHA224_C
#endif
#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
#define MBEDTLS_SHA256_C
#endif
#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
#define MBEDTLS_SHA384_C
#endif
#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
#define MBEDTLS_SHA512_C
#endif
#if defined(PSA_WANT_ALG_TLS12_PRF)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */
#endif /* PSA_WANT_ALG_TLS12_PRF */
#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */
#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS */
#endif /* PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_GENPRIME
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PK_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR */
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PK_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
/* If any of the block modes are requested that don't have an
* associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking
* in the block cipher key types. */
#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_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_KEY_TYPE_AES)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
#define PSA_HAVE_SOFT_KEY_TYPE_AES 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
defined(PSA_HAVE_SOFT_BLOCK_MODE) || \
defined(PSA_HAVE_SOFT_BLOCK_AEAD)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
#define MBEDTLS_AES_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_AES */
#if defined(PSA_WANT_KEY_TYPE_ARIA)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
#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)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
#define MBEDTLS_ARIA_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_ARIA */
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
#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)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
#define MBEDTLS_CAMELLIA_C
#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
#if defined(PSA_WANT_KEY_TYPE_DES)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES)
#define PSA_HAVE_SOFT_KEY_TYPE_DES 1
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
defined(PSA_HAVE_SOFT_BLOCK_MODE)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
#define MBEDTLS_DES_C
#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */
#endif /* PSA_WANT_KEY_TYPE_DES */
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
#define MBEDTLS_CHACHA20_C
#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
/* If any of the software block ciphers are selected, define
* PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these
* situations. */
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
#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."
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_MAC 1
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CBC_MAC */
#endif /* PSA_WANT_ALG_CBC_MAC */
#if defined(PSA_WANT_ALG_CMAC)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
#define MBEDTLS_CMAC_C
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */
#endif /* PSA_WANT_ALG_CMAC */
#if defined(PSA_WANT_ALG_CTR)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
#define MBEDTLS_CIPHER_MODE_CTR
#endif
#endif /* PSA_WANT_ALG_CTR */
#if defined(PSA_WANT_ALG_CFB)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
#define MBEDTLS_CIPHER_MODE_CFB
#endif
#endif /* PSA_WANT_ALG_CFB */
#if defined(PSA_WANT_ALG_OFB)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
#define MBEDTLS_CIPHER_MODE_OFB
#endif
#endif /* PSA_WANT_ALG_OFB */
#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \
!defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
#endif
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
#endif
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
#if defined(PSA_WANT_ALG_CBC_PKCS7)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
#define MBEDTLS_CIPHER_PADDING_PKCS7
#endif
#endif /* PSA_WANT_ALG_CBC_PKCS7 */
#if defined(PSA_WANT_ALG_CCM)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \
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 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_GCM)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \
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_GCM 1
#define MBEDTLS_GCM_C
#endif
#endif /* PSA_WANT_ALG_GCM */
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305)
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
#define MBEDTLS_CHACHAPOLY_C
#define MBEDTLS_CHACHA20_C
#define MBEDTLS_POLY1305_C
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305 */
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256 */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384 */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512 */
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255 */
#endif /* PSA_WANT_ECC_MONTGOMERY_255 */
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448)
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448 */
#endif /* PSA_WANT_ECC_MONTGOMERY_448 */
#if defined(PSA_WANT_ECC_SECP_R1_192)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192 */
#endif /* PSA_WANT_ECC_SECP_R1_192 */
#if defined(PSA_WANT_ECC_SECP_R1_224)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224 */
#endif /* PSA_WANT_ECC_SECP_R1_224 */
#if defined(PSA_WANT_ECC_SECP_R1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256 */
#endif /* PSA_WANT_ECC_SECP_R1_256 */
#if defined(PSA_WANT_ECC_SECP_R1_384)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384 */
#endif /* PSA_WANT_ECC_SECP_R1_384 */
#if defined(PSA_WANT_ECC_SECP_R1_521)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521 */
#endif /* PSA_WANT_ECC_SECP_R1_521 */
#if defined(PSA_WANT_ECC_SECP_K1_192)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192 */
#endif /* PSA_WANT_ECC_SECP_K1_192 */
#if defined(PSA_WANT_ECC_SECP_K1_224)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224)
/*
* SECP224K1 is buggy via the PSA API in Mbed TLS
* (https://github.com/Mbed-TLS/mbedtls/issues/3541).
*/
#error "SECP224K1 is buggy via the PSA API in Mbed TLS."
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224 */
#endif /* PSA_WANT_ECC_SECP_K1_224 */
#if defined(PSA_WANT_ECC_SECP_K1_256)
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256)
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1
#endif /* !MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256 */
#endif /* PSA_WANT_ECC_SECP_K1_256 */
/****************************************************************/
/* Infer PSA requirements from Mbed TLS capabilities */
/****************************************************************/
#include "mbedtls/config_adjust_legacy_from_psa.h"
#else /* MBEDTLS_PSA_CRYPTO_CONFIG */
/*
* Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG
* is not defined
*/
/* Infer PSA requirements from Mbed TLS capabilities */
#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
#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1
#endif /* MBEDTLS_CCM_C */
#include "mbedtls/config_adjust_psa_from_legacy.h"
#if defined(MBEDTLS_CMAC_C)
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
#define PSA_WANT_ALG_CMAC 1
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_ECDH_C)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
#define PSA_WANT_ALG_ECDH 1
#endif /* MBEDTLS_ECDH_C */
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
#define PSA_WANT_ALG_ECDSA 1
#define PSA_WANT_ALG_ECDSA_ANY 1
// Only add in DETERMINISTIC support if ECDSA is also enabled
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_ECP_C)
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_GCM_C)
#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
#define PSA_WANT_ALG_GCM 1
#endif /* MBEDTLS_GCM_C */
/* Enable PSA HKDF algorithm if mbedtls HKDF is supported.
* PSA HKDF EXTRACT and PSA HKDF EXPAND have minimal cost when
* PSA HKDF is enabled, so enable both algorithms together
* with PSA HKDF. */
#if defined(MBEDTLS_HKDF_C)
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define PSA_WANT_ALG_HMAC 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
#define PSA_WANT_ALG_HKDF 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
#define PSA_WANT_ALG_HKDF_EXTRACT 1
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
#define PSA_WANT_ALG_HKDF_EXPAND 1
#endif /* MBEDTLS_HKDF_C */
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
#define PSA_WANT_ALG_HMAC 1
#define PSA_WANT_KEY_TYPE_HMAC
#if defined(MBEDTLS_MD_C)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
#define PSA_WANT_ALG_TLS12_PRF 1
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_MD5_C)
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
#define PSA_WANT_ALG_MD5 1
#endif
#if defined(MBEDTLS_ECJPAKE_C)
#define MBEDTLS_PSA_BUILTIN_PAKE 1
#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
#define PSA_WANT_ALG_JPAKE 1
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
#define PSA_WANT_ALG_RIPEMD160 1
#endif
#if defined(MBEDTLS_RSA_C)
#if defined(MBEDTLS_PKCS1_V15)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
#define PSA_WANT_ALG_RSA_OAEP 1
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
#define PSA_WANT_ALG_RSA_PSS 1
#endif /* MBEDTLS_PKCS1_V21 */
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1
#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SHA1_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
#define PSA_WANT_ALG_SHA_1 1
#endif
#if defined(MBEDTLS_SHA224_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
#define PSA_WANT_ALG_SHA_224 1
#endif
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
#define PSA_WANT_ALG_SHA_256 1
#endif
#if defined(MBEDTLS_SHA384_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
#define PSA_WANT_ALG_SHA_384 1
#endif
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
#define PSA_WANT_ALG_SHA_512 1
#endif
#if defined(MBEDTLS_AES_C)
#define PSA_WANT_KEY_TYPE_AES 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
#endif
#if defined(MBEDTLS_ARIA_C)
#define PSA_WANT_KEY_TYPE_ARIA 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
#endif
#if defined(MBEDTLS_CAMELLIA_C)
#define PSA_WANT_KEY_TYPE_CAMELLIA 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
#endif
#if defined(MBEDTLS_DES_C)
#define PSA_WANT_KEY_TYPE_DES 1
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
#endif
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1
#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1
#endif
#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
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
#if defined(MBEDTLS_CHACHAPOLY_C)
#define PSA_WANT_ALG_CHACHA20_POLY1305 1
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
#endif
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
#define PSA_WANT_ALG_CBC_NO_PADDING 1
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
#define PSA_WANT_ALG_CBC_PKCS7 1
#endif
#endif
#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \
defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C)
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
#define PSA_WANT_ALG_ECB_NO_PADDING 1
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
#define PSA_WANT_ALG_CFB 1
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
#define PSA_WANT_ALG_CTR 1
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
#define PSA_WANT_ALG_OFB 1
#endif
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256
#endif
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_384
#endif
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1
#define PSA_WANT_ECC_BRAINPOOL_P_R1_512
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1
#define PSA_WANT_ECC_MONTGOMERY_255
#endif
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1
#define PSA_WANT_ECC_MONTGOMERY_448
#endif
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1
#define PSA_WANT_ECC_SECP_R1_192
#endif
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1
#define PSA_WANT_ECC_SECP_R1_224
#endif
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1
#define PSA_WANT_ECC_SECP_R1_256
#endif
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1
#define PSA_WANT_ECC_SECP_R1_384
#endif
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1
#define PSA_WANT_ECC_SECP_R1_521
#endif
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1
#define PSA_WANT_ECC_SECP_K1_192
#endif
/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */
#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1
#define PSA_WANT_ECC_SECP_K1_224
#endif
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1
#define PSA_WANT_ECC_SECP_K1_256
#endif
/* Hopefully the file above will have enabled keypair symbols in a consistent
* way, but including this here fixes them if that wasn't the case. */
#include "psa/crypto_adjust_config_key_pair_types.h"
#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
#if defined(PSA_WANT_ALG_ECDSA) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define PSA_HAVE_FULL_ECDSA 1
#if defined(PSA_WANT_ALG_JPAKE)
#define PSA_WANT_ALG_SOME_PAKE 1
#endif
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define PSA_HAVE_FULL_JPAKE 1
#endif
/* These features are always enabled. */
#define PSA_WANT_KEY_TYPE_DERIVE 1
#define PSA_WANT_KEY_TYPE_PASSWORD 1
#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
#ifdef __cplusplus
}
#endif
#include "psa/crypto_adjust_auto_enabled.h"
#endif /* MBEDTLS_CONFIG_PSA_H */
+25 -21
View File
@@ -23,19 +23,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CTR_DRBG_H
@@ -44,7 +32,15 @@
#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)
#include "mbedtls/threading.h"
@@ -94,17 +90,14 @@
* \brief The amount of entropy used per seed by default, in bytes.
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
/** This is 48 bytes because the entropy module uses SHA-512
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
/** This is 48 bytes because the entropy module uses SHA-512.
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
/** This is 32 bytes because the entropy module uses SHA-256
* (the SHA512 module is disabled or
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
/** This is 32 bytes because the entropy module uses SHA-256.
*/
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
/** \warning To achieve a 256-bit security strength, you must pass a nonce
@@ -112,7 +105,7 @@
*/
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
@@ -164,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.
*/
@@ -189,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)
+11 -167
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_DEBUG_H
#define MBEDTLS_DEBUG_H
@@ -131,6 +119,15 @@
#endif \
/* (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
extern "C" {
#endif
@@ -152,161 +149,8 @@ extern "C" {
*/
void mbedtls_debug_set_threshold(int threshold);
/**
* \brief Print a message to the debug output. This function is always used
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
* context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the message has occurred in
* \param line line number the message has occurred at
* \param format format specifier, in printf format
* \param ... variables used by the format specifier
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
/**
* \brief Print the return value of a function to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text the name of the function that returned the error
* \param ret the return code value
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret);
/**
* \brief Output a buffer of size len bytes to the debug output. This function
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the buffer being dumped. Normally the
* variable or buffer name
* \param buf the buffer to be outputted
* \param len length of the buffer
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Print a MPI variable to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the MPI being output. Normally the
* variable name
* \param X the MPI variable
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X);
#endif
#if defined(MBEDTLS_ECP_C)
/**
* \brief Print an ECP point to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the ECP point being output. Normally the
* variable name
* \param X the ECP point
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X);
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the certificate being output
* \param crt X.509 certificate structure
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt);
#endif
#if defined(MBEDTLS_ECDH_C)
typedef enum {
MBEDTLS_DEBUG_ECDH_Q,
MBEDTLS_DEBUG_ECDH_QP,
MBEDTLS_DEBUG_ECDH_Z,
} mbedtls_debug_ecdh_attr;
/**
* \brief Print a field of the ECDH structure in the SSL context to the debug
* output. This function is always used through the
* MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
* and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param ecdh the ECDH context
* \param attr the identifier of the attribute being output
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const mbedtls_ecdh_context *ecdh,
mbedtls_debug_ecdh_attr attr);
#endif
#ifdef __cplusplus
}
#endif
#endif /* debug.h */
#endif /* MBEDTLS_DEBUG_H */
+14 -13
View File
@@ -14,19 +14,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ECDH_H
@@ -153,6 +141,19 @@ typedef struct mbedtls_ecdh_context {
}
mbedtls_ecdh_context;
/**
* \brief Return the ECP group for provided context.
*
* \note To access group specific fields, users should use
* `mbedtls_ecp_curve_info_from_grp_id` or
* `mbedtls_ecp_group_load` on the extracted `group_id`.
*
* \param ctx The ECDH context to parse. This must not be \c NULL.
*
* \return The \c mbedtls_ecp_group_id of the context.
*/
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
/**
* \brief Check whether a given group can be used for ECDH.
*
+13 -23
View File
@@ -12,19 +12,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ECDSA_H
@@ -207,8 +195,9 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
* \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This
* may be \c NULL if \p f_rng_blind doesn't need a context
* parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
@@ -288,6 +277,8 @@ int mbedtls_ecdsa_sign_restartable(
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx);
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
@@ -321,10 +312,11 @@ int mbedtls_ecdsa_sign_restartable(
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be
* \c NULL if \p f_rng_blind doesn't need a context parameter.
* \param rs_ctx The restart context to use. This may be \c NULL
* to disable restarting. If it is not \c NULL, it
* must point to an initialized restart context.
@@ -348,8 +340,6 @@ int mbedtls_ecdsa_sign_det_restartable(
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message.
@@ -458,7 +448,7 @@ int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* buffer of length \p hlen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
@@ -501,7 +491,7 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* buffer of length \p hlen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
@@ -548,7 +538,7 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* buffer of length \p hlen Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
@@ -578,7 +568,7 @@ int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* buffer of length \p hlen Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
+2 -13
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
@@ -54,6 +42,7 @@ extern "C" {
typedef enum {
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
MBEDTLS_ECJPAKE_SERVER, /**< Server */
MBEDTLS_ECJPAKE_NONE, /**< Undefined */
} mbedtls_ecjpake_role;
#if !defined(MBEDTLS_ECJPAKE_ALT)
+229 -40
View File
@@ -16,19 +16,7 @@
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ECP_H
@@ -36,6 +24,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/bignum.h"
@@ -141,15 +130,6 @@ typedef enum {
MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
} mbedtls_ecp_curve_type;
/*
* Curve modulus types
*/
typedef enum {
MBEDTLS_ECP_MOD_NONE = 0,
MBEDTLS_ECP_MOD_COORDINATE,
MBEDTLS_ECP_MOD_SCALAR
} mbedtls_ecp_modulus_type;
/**
* Curve information, for use by other modules.
*
@@ -184,7 +164,7 @@ mbedtls_ecp_point;
#if !defined(MBEDTLS_ECP_ALT)
/*
* default mbed TLS elliptic curve arithmetic implementation
* default Mbed TLS elliptic curve arithmetic implementation
*
* (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an
* alternative implementation for the whole module and it will replace this
@@ -206,6 +186,27 @@ mbedtls_ecp_point;
* odd prime as mbedtls_ecp_mul() requires an odd number, and
* mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
*
* The default implementation only initializes \p A without setting it to the
* authentic value for curves with <code>A = -3</code>(SECP256R1, etc), in which
* case you need to load \p A by yourself when using domain parameters directly,
* for example:
* \code
* mbedtls_mpi_init(&A);
* mbedtls_ecp_group_init(&grp);
* CHECK_RETURN(mbedtls_ecp_group_load(&grp, grp_id));
* if (mbedtls_ecp_group_a_is_minus_3(&grp)) {
* CHECK_RETURN(mbedtls_mpi_sub_int(&A, &grp.P, 3));
* } else {
* CHECK_RETURN(mbedtls_mpi_copy(&A, &grp.A));
* }
*
* do_something_with_a(&A);
*
* cleanup:
* mbedtls_mpi_free(&A);
* mbedtls_ecp_group_free(&grp);
* \endcode
*
* For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
* which is the quantity used in the formulas. Additionally, \p nbits is
* not the size of \p N but the required size for private keys.
@@ -232,8 +233,11 @@ mbedtls_ecp_point;
typedef struct mbedtls_ecp_group {
mbedtls_ecp_group_id id; /*!< An internal group identifier. */
mbedtls_mpi P; /*!< The prime modulus of the base field. */
mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For
Montgomery curves: <code>(A + 2) / 4</code>. */
mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. Note that
\p A is not set to the authentic value in some cases.
Refer to detailed description of ::mbedtls_ecp_group if
using domain parameters in the structure.
For Montgomery curves: <code>(A + 2) / 4</code>. */
mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation.
For Montgomery curves: unused. */
mbedtls_ecp_point G; /*!< The generator of the subgroup used. */
@@ -312,7 +316,7 @@ mbedtls_ecp_group;
/**
* The maximum size of the groups, that is, of \c N and \c P.
*/
#if !defined(MBEDTLS_ECP_C)
#if !defined(MBEDTLS_ECP_LIGHT)
/* Dummy definition to help code that has optional ECP support and
* defines an MBEDTLS_ECP_MAX_BYTES-sized array unconditionally. */
#define MBEDTLS_ECP_MAX_BITS 1
@@ -343,9 +347,9 @@ mbedtls_ecp_group;
#define MBEDTLS_ECP_MAX_BITS 192
#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
#define MBEDTLS_ECP_MAX_BITS 192
#else
#else /* !MBEDTLS_ECP_LIGHT */
#error "Missing definition of MBEDTLS_ECP_MAX_BITS"
#endif
#endif /* !MBEDTLS_ECP_LIGHT */
#define MBEDTLS_ECP_MAX_BYTES ((MBEDTLS_ECP_MAX_BITS + 7) / 8)
#define MBEDTLS_ECP_MAX_PT_LEN (2 * MBEDTLS_ECP_MAX_BYTES + 1)
@@ -1000,6 +1004,26 @@ int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_restart_ctx *rs_ctx);
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
* \brief This function checks if domain parameter A of the curve is
* \c -3.
*
* \note This function is only defined for short Weierstrass curves.
* It may not be included in builds without any short
* Weierstrass curve.
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
*
* \return \c 1 if <code>A = -3</code>.
* \return \c 0 Otherwise.
*/
static inline int mbedtls_ecp_group_a_is_minus_3(const mbedtls_ecp_group *grp)
{
return grp->A.MBEDTLS_PRIVATE(p) == NULL;
}
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@@ -1092,7 +1116,7 @@ int mbedtls_ecp_muladd_restartable(
*
* It only checks that the point is non-zero, has
* valid coordinates and lies on the curve. It does not verify
* that it is indeed a multiple of \p G. This additional
* that it is indeed a multiple of \c G. This additional
* check is computationally more expensive, is not required
* by standards, and should not be necessary if the group
* used has a small cofactor. In particular, it is useless for
@@ -1117,7 +1141,7 @@ int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *pt);
/**
* \brief This function checks that an \p mbedtls_mpi is a
* \brief This function checks that an \c mbedtls_mpi is a
* valid private key for this curve.
*
* \note This function uses bare components rather than an
@@ -1236,9 +1260,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
@@ -1257,24 +1328,106 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
const unsigned char *buf, size_t buflen);
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief This function exports an elliptic curve private key.
*
* \deprecated Note that although this function accepts an output
* buffer that is smaller or larger than the key, most key
* import interfaces require the output to have exactly
* key's nominal length. It is generally simplest to
* pass the key's nominal length as \c buflen, after
* checking that the output buffer is large enough.
* See the description of the \p buflen parameter for
* how to calculate the nominal length.
* To avoid this difficulty, use mbedtls_ecp_write_key_ext()
* instead.
* mbedtls_ecp_write_key() is deprecated and will be
* removed in a future version of the library.
*
* \note If the private key was not set in \p key,
* the output is unspecified. Future versions
* may return an error in that case.
*
* \param key The private key.
* \param buf The output buffer for containing the binary representation
* of the key.
* For Weierstrass curves, this is the big-endian
* representation, padded with null bytes at the beginning
* to reach \p buflen bytes.
* For Montgomery curves, this is the standard byte string
* representation (which is little-endian), padded with
* null bytes at the end to reach \p buflen bytes.
* \param buflen The total length of the buffer in bytes.
* The length of the output is
* (`grp->nbits` + 7) / 8 bytes
* where `grp->nbits` is the private key size in bits.
* For Weierstrass keys, if the output buffer is smaller,
* leading zeros are trimmed to fit if possible. For
* Montgomery keys, the output buffer must always be large
* enough for the nominal length.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL or
* #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the \p key
* representation is larger than the available space in \p buf.
* \return Another negative error code on different kinds of failure.
*/
int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function exports an elliptic curve private key.
*
* \param key The private key.
* \param olen On success, the length of the private key.
* This is always (`grp->nbits` + 7) / 8 bytes
* where `grp->nbits` is the private key size in bits.
* \param buf The output buffer for containing the binary representation
* of the key. (Big endian integer for Weierstrass curves, byte
* string for Montgomery curves.)
* of the key.
* \param buflen The total length of the buffer in bytes.
* #MBEDTLS_ECP_MAX_BYTES is always sufficient.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
representation is larger than the available space in \p buf.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
* the group is not implemented.
* representation is larger than the available space in \p buf.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is
* set in \p key.
* \return Another negative error code on different kinds of failure.
*/
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen);
int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
size_t *olen, unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
*
* \note If the public key was not set in \p key,
* the output is unspecified. Future versions
* may return an error in that case.
*
* \param key The public key.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
* (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
@@ -1300,16 +1453,52 @@ 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.
*
* \note If the private key or the public key was not set in \p key,
* the corresponding output is unspecified. Future versions
* may return an error in that case.
*
* \param key The key pair to export from.
* \param grp Slot for exported ECP group.
* It must 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.
+10 -28
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
@@ -27,13 +15,17 @@
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "mbedtls/sha512.h"
#include "md.h"
#if defined(MBEDTLS_MD_CAN_SHA512) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA512
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_MD_CAN_SHA256)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "mbedtls/sha256.h"
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA256
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#endif
@@ -71,12 +63,6 @@
/** \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
@@ -117,14 +103,10 @@ mbedtls_entropy_source_state;
* \brief Entropy context structure
*/
typedef struct mbedtls_entropy_context {
mbedtls_md_context_t MBEDTLS_PRIVATE(accumulator);
int MBEDTLS_PRIVATE(accumulator_started); /* 0 after init.
* 1 after the first update.
* -1 after free. */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context MBEDTLS_PRIVATE(accumulator);
#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
mbedtls_sha256_context MBEDTLS_PRIVATE(accumulator);
#endif
int MBEDTLS_PRIVATE(source_count); /* Number of entries used in source. */
mbedtls_entropy_source_state MBEDTLS_PRIVATE(source)[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_THREADING_C)
+26 -24
View File
@@ -13,19 +13,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_GCM_H
@@ -36,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
@@ -54,21 +46,31 @@ extern "C" {
#if !defined(MBEDTLS_GCM_ALT)
#if defined(MBEDTLS_GCM_LARGE_TABLE)
#define MBEDTLS_GCM_HTABLE_SIZE 256
#else
#define MBEDTLS_GCM_HTABLE_SIZE 16
#endif
/**
* \brief The GCM context structure.
*/
typedef struct mbedtls_gcm_context {
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */
uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
int MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
#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(H)[MBEDTLS_GCM_HTABLE_SIZE][2]; /*!< Precalculated HTable. */
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
unsigned char MBEDTLS_PRIVATE(acceleration); /*!< The acceleration to use. */
}
mbedtls_gcm_context;
File diff suppressed because it is too large Load Diff
+52 -114
View File
@@ -8,19 +8,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_MD_H
@@ -32,93 +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
#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_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. */
@@ -140,36 +41,59 @@ extern "C" {
* stronger message digests instead.
*
*/
/* Note: these are aligned with the definitions of PSA_ALG_ macros for hashes,
* in order to enable an efficient implementation of conversion functions.
* This is tested by md_to_from_psa() in test_suite_md. */
typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */
#ifdef USE_HISI_MBED
MBEDTLS_MD_MD5 = 3, /**< The MD5 message digest. */
MBEDTLS_MD_MD5 =0x03, /**< The MD5 message digest. */
#else
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
#endif
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */
MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */
MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */
MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */
MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */
MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */
} mbedtls_md_type_t;
#if defined(MBEDTLS_MD_CAN_SHA512)
/* Note: this should always be >= PSA_HASH_MAX_SIZE
* in all builds with both CRYPTO_C and MD_LIGHT.
*
* This is to make things easier for modules such as TLS that may define a
* buffer size using MD_MAX_SIZE in a part of the code that's common to PSA
* and legacy, then assume the buffer's size is PSA_HASH_MAX_SIZE in another
* part of the code based on PSA.
*/
#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA3_512)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#elif defined(MBEDTLS_MD_CAN_SHA384)
#elif defined(MBEDTLS_MD_CAN_SHA384) || defined(MBEDTLS_MD_CAN_SHA3_384)
#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */
#elif defined(MBEDTLS_MD_CAN_SHA256)
#elif defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA3_256)
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */
#elif defined(MBEDTLS_MD_CAN_SHA224)
#elif defined(MBEDTLS_MD_CAN_SHA224) || defined(MBEDTLS_MD_CAN_SHA3_224)
#define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */
#else
#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160
or smaller (MD5 and earlier) */
#endif
#if defined(MBEDTLS_MD_CAN_SHA512)
#if defined(MBEDTLS_MD_CAN_SHA3_224)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */
#elif defined(MBEDTLS_MD_CAN_SHA3_256)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 136
#elif defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA384)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
#elif defined(MBEDTLS_MD_CAN_SHA3_384)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 104
#elif defined(MBEDTLS_MD_CAN_SHA3_512)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 72
#else
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
#endif
@@ -314,6 +238,20 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst,
*/
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info);
/**
* \brief This function gives the message-digest size associated to
* message-digest type.
*
* \param md_type The message-digest type.
*
* \return The size of the message-digest output in Bytes,
* or 0 if the message-digest type is not known.
*/
static inline unsigned char mbedtls_md_get_size_from_type(mbedtls_md_type_t md_type)
{
return mbedtls_md_get_size(mbedtls_md_info_from_type(md_type));
}
/**
* \brief This function extracts the message-digest type from the
* message-digest information structure.
@@ -428,8 +366,8 @@ const int *mbedtls_md_list(void);
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
/**
* \brief This function extracts the message-digest name from the
* message-digest information structure.
* \brief This function returns the name of the message digest for
* the message-digest information structure given.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
+11 -15
View File
@@ -21,19 +21,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_NET_SOCKETS_H
#define MBEDTLS_NET_SOCKETS_H
@@ -155,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
@@ -168,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
@@ -286,6 +274,10 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len,
* \brief Closes down the connection and free associated data
*
* \param ctx The context to close
*
* \note This function frees and clears data associated with the
* context but does not free the memory pointed to by \p ctx.
* This memory is the responsibility of the caller.
*/
void mbedtls_net_close(mbedtls_net_context *ctx);
@@ -293,6 +285,10 @@ void mbedtls_net_close(mbedtls_net_context *ctx);
* \brief Gracefully shutdown the connection and free associated data
*
* \param ctx The context to free
*
* \note This function frees and clears data associated with the
* context but does not free the memory pointed to by \p ctx.
* This memory is the responsibility of the caller.
*/
void mbedtls_net_free(mbedtls_net_context *ctx);
+89 -17
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_OID_H
#define MBEDTLS_OID_H
@@ -63,6 +51,11 @@
#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
/*
* Maximum number of OID components allowed
*/
#define MBEDTLS_OID_MAX_COMPONENTS 128
/*
* Top level OID tuples
*/
@@ -90,6 +83,9 @@
#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03"
#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02"
#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a"
#define MBEDTLS_OID_ORG_THAWTE "\x65" /* thawte(101) */
#define MBEDTLS_OID_THAWTE MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_ORG_THAWTE
#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */
#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_ORG_CERTICOM
@@ -262,6 +258,15 @@
#define MBEDTLS_OID_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
#define MBEDTLS_OID_DIGEST_ALG_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x07" /**< id-sha3-224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-224(7) } */
#define MBEDTLS_OID_DIGEST_ALG_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x08" /**< id-sha3-256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-256(8) } */
#define MBEDTLS_OID_DIGEST_ALG_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x09" /**< id-sha3-384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-384(9) } */
#define MBEDTLS_OID_DIGEST_ALG_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x0a" /**< id-sha3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-512(10) } */
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
@@ -272,13 +277,28 @@
#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
#define MBEDTLS_OID_HMAC_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x0d" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-224(13) } */
#define MBEDTLS_OID_HMAC_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x0e" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-256(14) } */
#define MBEDTLS_OID_HMAC_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x0f" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-384(15) } */
#define MBEDTLS_OID_HMAC_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x10" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-512(16) } */
#define MBEDTLS_OID_HMAC_RIPEMD160 MBEDTLS_OID_INTERNET "\x05\x05\x08\x01\x04" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) iso-identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1) hmacRIPEMD160(4)} */
/*
* Encryption algorithms
* Encryption algorithms,
* the following standardized object identifiers are specified at
* https://datatracker.ietf.org/doc/html/rfc8018#appendix-C.
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
#define MBEDTLS_OID_AES_128_CBC MBEDTLS_OID_AES "\x02" /** aes128-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes128-CBC-PAD(2) } */
#define MBEDTLS_OID_AES_192_CBC MBEDTLS_OID_AES "\x16" /** aes192-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes192-CBC-PAD(22) } */
#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a" /** aes256-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes256-CBC-PAD(42) } */
/*
* Key Wrapping algorithms
@@ -437,6 +457,15 @@
* ecdsa-with-SHA2(3) 4 } */
#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04"
/*
* EC key algorithms from RFC 8410
*/
#define MBEDTLS_OID_X25519 MBEDTLS_OID_THAWTE "\x6e" /**< id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 } */
#define MBEDTLS_OID_X448 MBEDTLS_OID_THAWTE "\x6f" /**< id-X448 OBJECT IDENTIFIER ::= { 1 3 101 111 } */
#define MBEDTLS_OID_ED25519 MBEDTLS_OID_THAWTE "\x70" /**< id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } */
#define MBEDTLS_OID_ED448 MBEDTLS_OID_THAWTE "\x71" /**< id-Ed448 OBJECT IDENTIFIER ::= { 1 3 101 113 } */
#ifdef __cplusplus
extern "C" {
#endif
@@ -466,6 +495,25 @@ typedef struct mbedtls_oid_descriptor_t {
*/
int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid);
/**
* \brief Translate a string containing a dotted-decimal
* representation of an ASN.1 OID into its encoded form
* (e.g. "1.2.840.113549" into "\x2A\x86\x48\x86\xF7\x0D").
* On success, this function allocates oid->buf from the
* heap. It must be freed by the caller using mbedtls_free().
*
* \param oid #mbedtls_asn1_buf to populate with the DER-encoded OID
* \param oid_str string representation of the OID to parse
* \param size length of the OID string, not including any null terminator
*
* \return 0 if successful
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if \p oid_str does not
* represent a valid OID
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if the function fails to
* allocate oid->buf
*/
int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *oid_str, size_t size);
/**
* \brief Translate an X.509 extension OID into local values
*
@@ -509,7 +557,7 @@ int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_al
int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg,
const char **oid, size_t *olen);
#if defined(MBEDTLS_ECP_C)
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/**
* \brief Translate NamedCurve OID into an EC group identifier
*
@@ -531,7 +579,31 @@ int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *gr
*/
int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id,
const char **oid, size_t *olen);
#endif /* MBEDTLS_ECP_C */
/**
* \brief Translate AlgorithmIdentifier OID into an EC group identifier,
* for curves that are directly encoded at this level
*
* \param oid OID to use
* \param grp_id place to store group id
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_ec_grp_algid(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id);
/**
* \brief Translate EC group identifier into AlgorithmIdentifier OID,
* for curves that are directly encoded at this level
*
* \param grp_id EC group identifier
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_oid_by_ec_grp_algid(mbedtls_ecp_group_id grp_id,
const char **oid, size_t *olen);
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
/**
* \brief Translate SignatureAlgorithm OID into md_type and pk_type
@@ -631,7 +703,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)
/**
@@ -647,6 +718,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
}
+324 -88
View File
@@ -5,19 +5,7 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_PK_H
@@ -40,7 +28,7 @@
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include "psa/crypto.h"
#endif
@@ -171,30 +159,26 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#endif
#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
/**
* \brief The following defines are meant to list ECDSA capabilities of the
* PK module in a general way (without any reference to how this
* is achieved, which can be either through PSA driver or
* MBEDTLS_ECDSA_C)
/* Internal helper to define which fields in the pk_context structure below
* should be used for EC keys: legacy ecp_keypair or the raw (PSA friendly)
* format. It should be noted that this only affects how data is stored, not
* which functions are used for various operations. The overall picture looks
* like this:
* - if USE_PSA is not defined and ECP_C is defined then use ecp_keypair data
* structure and legacy functions
* - if USE_PSA is defined and
* - if ECP_C then use ecp_keypair structure, convert data to a PSA friendly
* format and use PSA functions
* - if !ECP_C then use new raw data and PSA functions directly.
*
* The main reason for the "intermediate" (USE_PSA + ECP_C) above is that as long
* as ECP_C is defined mbedtls_pk_ec() gives the user a read/write access to the
* ecp_keypair structure inside the pk_context so they can modify it using
* ECP functions which are not under PK module's control.
*/
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(PSA_WANT_ALG_ECDSA)
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#endif
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
#define MBEDTLS_PK_CAN_ECDSA_VERIFY
#endif
#endif /* PSA_WANT_ALG_ECDSA */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#define MBEDTLS_PK_CAN_ECDSA_SOME
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
!defined(MBEDTLS_ECP_C)
#define MBEDTLS_PK_USE_PSA_EC_DATA
#endif
/**
@@ -204,6 +188,7 @@ typedef enum {
MBEDTLS_PK_DEBUG_NONE = 0,
MBEDTLS_PK_DEBUG_MPI,
MBEDTLS_PK_DEBUG_ECP,
MBEDTLS_PK_DEBUG_PSA_EC,
} mbedtls_pk_debug_type;
/**
@@ -227,12 +212,56 @@ typedef struct mbedtls_pk_debug_item {
*/
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
#define MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN \
PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
/**
* \brief Public key container
*/
typedef struct mbedtls_pk_context {
const mbedtls_pk_info_t *MBEDTLS_PRIVATE(pk_info); /**< Public key information */
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_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
* the public key will be stored in raw format as explained below
* - this ID is used for all private key operations (ex: sign, check
* key pair, key write, etc) using PSA functions
*
* 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. */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id); /**< Key ID for opaque keys */
#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
* - reducing the ECP module dependencies in the PK one.
*
* When MBEDTLS_PK_USE_PSA_EC_DATA is enabled:
* - the pk_ctx above is not used anymore for storing the public key
* inside the ecp_keypair structure
* - the following fields are used for all public key operations: signature
* verify, key pair check and key write.
* - For a key pair, priv_id contains the private key. For a public key,
* priv_id is null.
* Of course, when MBEDTLS_PK_USE_PSA_EC_DATA is not enabled, the legacy
* ecp_keypair structure is used for storing the public key and performing
* all the operations.
*
* Note: This new public key storing solution only works for EC keys, not
* other ones. The latters still use pk_ctx to store their own
* context.
*/
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
uint8_t MBEDTLS_PRIVATE(pub_raw)[MBEDTLS_PK_MAX_EC_PUBKEY_RAW_LEN]; /**< Raw public key */
size_t MBEDTLS_PRIVATE(pub_raw_len); /**< Valid bytes in "pub_raw" */
psa_ecc_family_t MBEDTLS_PRIVATE(ec_family); /**< EC family of pk */
size_t MBEDTLS_PRIVATE(ec_bits); /**< Curve's bits of pk */
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
} mbedtls_pk_context;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
@@ -429,7 +458,7 @@ int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type);
* PSA_ALG_RSA_PKCS1V15_CRYPT,
* PSA_ALG_ECDSA(hash),
* PSA_ALG_ECDH, where hash is a specific hash.
* \param usage PSA usage flag to check against, must be composed of:
* \param usage PSA usage flag to check against, must be composed of:
* PSA_KEY_USAGE_SIGN_HASH
* PSA_KEY_USAGE_DECRYPT
* PSA_KEY_USAGE_DERIVE.
@@ -450,6 +479,237 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
psa_key_usage_t usage);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/**
* \brief Determine valid PSA attributes that can be used to
* import a key into PSA.
*
* The attributes determined by this function are suitable
* for calling mbedtls_pk_import_into_psa() to create
* a PSA key with the same key material.
*
* The typical flow of operations involving this function is
* ```
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* int ret = mbedtls_pk_get_psa_attributes(pk, &attributes);
* if (ret != 0) ...; // error handling omitted
* // Tweak attributes if desired
* psa_key_id_t key_id = 0;
* ret = mbedtls_pk_import_into_psa(pk, &attributes, &key_id);
* if (ret != 0) ...; // error handling omitted
* ```
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
*
* \param[in] pk The PK context to use. It must have been set up.
* It can either contain a key pair or just a public key.
* \param usage A single `PSA_KEY_USAGE_xxx` flag among the following:
* - #PSA_KEY_USAGE_DECRYPT: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_ENCRYPT as well as
* #PSA_KEY_USAGE_DECRYPT.
* - #PSA_KEY_USAGE_DERIVE: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type.
* - #PSA_KEY_USAGE_ENCRYPT: The output
* \p attributes will contain a public key type.
* - #PSA_KEY_USAGE_SIGN_HASH: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_VERIFY_HASH as well as
* #PSA_KEY_USAGE_SIGN_HASH.
* - #PSA_KEY_USAGE_SIGN_MESSAGE: \p pk must contain a
* key pair. The output \p attributes will contain a
* key pair type, and the usage policy will allow
* #PSA_KEY_USAGE_VERIFY_MESSAGE as well as
* #PSA_KEY_USAGE_SIGN_MESSAGE.
* - #PSA_KEY_USAGE_VERIFY_HASH: The output
* \p attributes will contain a public key type.
* - #PSA_KEY_USAGE_VERIFY_MESSAGE: The output
* \p attributes will contain a public key type.
* \param[out] attributes
* On success, valid attributes to import the key into PSA.
* - The lifetime and key identifier are unchanged. If the
* attribute structure was initialized or reset before
* calling this function, this will result in a volatile
* key. Call psa_set_key_identifier() before or after this
* function if you wish to create a persistent key. Call
* psa_set_key_lifetime() before or after this function if
* you wish to import the key in a secure element.
* - The key type and bit-size are determined by the contents
* of the PK context. If the PK context contains a key
* pair, the key type can be either a key pair type or
* the corresponding public key type, depending on
* \p usage. If the PK context contains a public key,
* the key type is a public key type.
* - The key's policy is determined by the key type and
* the \p usage parameter. The usage always allows
* \p usage, exporting and copying the key, and
* possibly other permissions as documented for the
* \p usage parameter.
* The permitted algorithm policy is determined as follows
* based on the #mbedtls_pk_type_t type of \p pk,
* the chosen \p usage and other factors:
* - #MBEDTLS_PK_RSA whose underlying
* #mbedtls_rsa_context has the padding mode
* #MBEDTLS_RSA_PKCS_V15:
* #PSA_ALG_RSA_PKCS1V15_SIGN(#PSA_ALG_ANY_HASH)
* if \p usage is SIGN/VERIFY, and
* #PSA_ALG_RSA_PKCS1V15_CRYPT
* if \p usage is ENCRYPT/DECRYPT.
* - #MBEDTLS_PK_RSA whose underlying
* #mbedtls_rsa_context has the padding mode
* #MBEDTLS_RSA_PKCS_V21 and the digest type
* corresponding to the PSA algorithm \c hash:
* #PSA_ALG_RSA_PSS_ANY_SALT(#PSA_ALG_ANY_HASH)
* if \p usage is SIGN/VERIFY, and
* #PSA_ALG_RSA_OAEP(\c hash)
* if \p usage is ENCRYPT/DECRYPT.
* - #MBEDTLS_PK_RSA_ALT: not supported.
* - #MBEDTLS_PK_ECDSA or #MBEDTLS_PK_ECKEY
* if \p usage is SIGN/VERIFY:
* #PSA_ALG_DETERMINISTIC_ECDSA(#PSA_ALG_ANY_HASH)
* if #MBEDTLS_ECDSA_DETERMINISTIC is enabled,
* otherwise #PSA_ALG_ECDSA(#PSA_ALG_ANY_HASH).
* - #MBEDTLS_PK_ECKEY_DH or #MBEDTLS_PK_ECKEY
* if \p usage is DERIVE:
* #PSA_ALG_ECDH.
* - #MBEDTLS_PK_OPAQUE: same as the primary algorithm
* set for the underlying PSA key, except that
* sign/decrypt flags are removed if the type is
* set to a public key type.
* The underlying key must allow \p usage.
* Note that the enrollment algorithm set with
* psa_set_key_enrollment_algorithm() is not copied.
*
* \return 0 on success.
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain
* a key of the type identified in \p attributes.
* Another error code on other failures.
*/
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
psa_key_usage_t usage,
psa_key_attributes_t *attributes);
/**
* \brief Import a key into the PSA key store.
*
* This function is equivalent to calling psa_import_key()
* with the key material from \p pk.
*
* The typical way to use this function is:
* -# Call mbedtls_pk_get_psa_attributes() to obtain
* attributes for the given key.
* -# If desired, modify the attributes, for example:
* - To create a persistent key, call
* psa_set_key_identifier() and optionally
* psa_set_key_lifetime().
* - To import only the public part of a key pair:
*
* psa_set_key_type(&attributes,
* PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
* psa_get_key_type(&attributes)));
* - Restrict the key usage if desired.
* -# Call mbedtls_pk_import_into_psa().
*
* \note This function does not support RSA-alt contexts
* (set up with mbedtls_pk_setup_rsa_alt()).
*
* \param[in] pk The PK context to use. It must have been set up.
* It can either contain a key pair or just a public key.
* \param[in] attributes
* The attributes to use for the new key. They must be
* compatible with \p pk. In particular, the key type
* must match the content of \p pk.
* If \p pk contains a key pair, the key type in
* attributes can be either the key pair type or the
* corresponding public key type (to import only the
* public part).
* \param[out] key_id
* On success, the identifier of the newly created key.
* On error, this is #MBEDTLS_SVC_KEY_ID_INIT.
*
* \return 0 on success.
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if \p pk does not contain
* a key of the type identified in \p attributes.
* Another error code on other failures.
*/
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
const psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t *key_id);
/**
* \brief Create a PK context starting from a key stored in PSA.
* This key:
* - must be exportable and
* - must be an RSA or EC key pair or public key (FFDH is not supported in PK).
*
* The resulting PK object will be a transparent type:
* - #MBEDTLS_PK_RSA for RSA keys or
* - #MBEDTLS_PK_ECKEY for EC keys.
*
* Once this functions returns the PK object will be completely
* independent from the original PSA key that it was generated
* from.
* Calling mbedtls_pk_sign(), mbedtls_pk_verify(),
* mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting
* PK context will perform the corresponding algorithm for that
* PK context type.
* * For ECDSA, the choice of deterministic vs randomized will
* be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC.
* * For an RSA key, the output PK context will allow both
* encrypt/decrypt and sign/verify regardless of the original
* key's policy.
* The original key's policy determines the output key's padding
* mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
* otherwise PKCS1 v1.5 is set.
*
* \param key_id The key identifier of the key stored in PSA.
* \param pk The PK context that will be filled. It must be initialized,
* but not set up.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
* parameters are not correct.
*/
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
/**
* \brief Create a PK context for the public key of a PSA key.
*
* The key must be an RSA or ECC key. It can be either a
* public key or a key pair, and only the public key is copied.
* The resulting PK object will be a transparent type:
* - #MBEDTLS_PK_RSA for RSA keys or
* - #MBEDTLS_PK_ECKEY for EC keys.
*
* Once this functions returns the PK object will be completely
* independent from the original PSA key that it was generated
* from.
* Calling mbedtls_pk_verify() or
* mbedtls_pk_encrypt() on the resulting
* PK context will perform the corresponding algorithm for that
* PK context type.
*
* For an RSA key, the output PK context will allow both
* encrypt and verify regardless of the original key's policy.
* The original key's policy determines the output key's padding
* mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS,
* otherwise PKCS1 v1.5 is set.
*
* \param key_id The key identifier of the key stored in PSA.
* \param pk The PK context that will be filled. It must be initialized,
* but not set up.
*
* \return 0 on success.
* \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input
* parameters are not correct.
*/
int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk);
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
/**
* \brief Verify signature (including padding if relevant).
*
@@ -468,14 +728,17 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg,
* \param sig Signature to verify
* \param sig_len Signature length
*
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or PSS (accepting any salt length),
* depending on the padding mode in the underlying RSA context.
* For a pk object constructed by parsing, this is PKCS#1 v1.5
* by default. Use mbedtls_pk_verify_ext() to explicitly select
* a different algorithm.
*
* \return 0 on success (signature is valid),
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen,
* signature in \p sig but its length is less than \p sig_len,
* or a specific error code.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
* to verify RSASSA_PSS signatures.
*/
int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@@ -524,7 +787,7 @@ int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx,
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
* used for this type of signatures,
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen,
* signature in \p sig but its length is less than \p sig_len,
* or a specific error code.
*
* \note If hash_len is 0, then the length associated with md_alg
@@ -562,11 +825,15 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \return 0 on success, or a specific error code.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or PSS (using the largest possible salt
* length up to the hash length), depending on the padding mode
* in the underlying RSA context. For a pk object constructed
* by parsing, this is PKCS#1 v1.5 by default. Use
* mbedtls_pk_verify_ext() to explicitly select a different
* algorithm.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* There is no interface in the PK module to make RSASSA-PSS
* signatures yet.
* \return 0 on success, or a specific error code.
*
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
@@ -576,7 +843,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.
*
@@ -613,7 +879,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()
@@ -664,7 +929,10 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
* the underlying RSA context. For a pk object constructed by
* parsing, this is PKCS#1 v1.5 by default.
*
* \return 0 on success, or a specific error code.
*/
@@ -685,9 +953,12 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
* \param f_rng RNG function, must not be \c NULL.
* \param p_rng RNG parameter
*
* \note \p f_rng is used for padding generation.
* \note For keys of type #MBEDTLS_PK_RSA, the signature algorithm is
* either PKCS#1 v1.5 or OAEP, depending on the padding mode in
* the underlying RSA context. For a pk object constructed by
* parsing, this is PKCS#1 v1.5 by default.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* \note \p f_rng is used for padding generation.
*
* \return 0 on success, or a specific error code.
*/
@@ -1010,41 +1281,6 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key);
#endif /* MBEDTLS_PK_WRITE_C */
/*
* Internal module functions. You probably do not want to use these unless you
* know you do.
*/
#if defined(MBEDTLS_FS_IO)
int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n);
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Turn an EC or RSA key into an opaque one.
*
* \warning This is a temporary utility function for tests. It might
* change or be removed at any time without notice.
*
* \param pk Input: the EC or RSA key to import to a PSA key.
* Output: a PK context wrapping that PSA key.
* \param key Output: a PSA key identifier.
* It's the caller's responsibility to call
* psa_destroy_key() on that key identifier after calling
* mbedtls_pk_free() on the PK context.
* \param alg The algorithm to allow for use with that key.
* \param usage The usage to allow for use with that key.
* \param alg2 The secondary algorithm to allow for use with that key.
*
* \return \c 0 if successful.
* \return An Mbed TLS error code otherwise.
*/
int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk,
mbedtls_svc_key_id_t *key,
psa_algorithm_t alg,
psa_key_usage_t usage,
psa_algorithm_t alg2);
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
}
#endif
+85 -23
View File
@@ -7,27 +7,17 @@
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_PKCS5_H
#define MBEDTLS_PKCS5_H
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/asn1.h"
#include "mbedtls/md.h"
#include "mbedtls/cipher.h"
#include <stddef.h>
#include <stdint.h>
@@ -41,34 +31,106 @@
/** 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)
/**
* \brief PKCS#5 PBES2 function
*
* \note When encrypting, #MBEDTLS_CIPHER_PADDING_PKCS7 must
* be enabled at compile time.
*
* \deprecated This function is deprecated and will be removed in a
* future version of the library.
* Please use mbedtls_pkcs5_pbes2_ext() instead.
*
* \warning When decrypting:
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is enabled at compile
* time, this function validates the CBC padding and returns
* #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is
* invalid. Note that this can help active adversaries
* attempting to brute-forcing the password. Note also that
* there is no guarantee that an invalid password will be
* detected (the chances of a valid padding with a random
* password are about 1/255).
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is disabled at compile
* time, this function does not validate the CBC padding.
*
* \param pbe_params the ASN.1 algorithm parameters
* \param mode either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT
* \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT
* \param pwd password to use when generating key
* \param pwdlen length of password
* \param data data to process
* \param datalen length of data
* \param output output buffer
* \param output Output buffer.
* On success, it contains the encrypted or decrypted data,
* possibly followed by the CBC padding.
* On failure, the content is indeterminate.
* For decryption, there must be enough room for \p datalen
* bytes.
* For encryption, there must be enough room for
* \p datalen + 1 bytes, rounded up to the block size of
* the block cipher identified by \p pbe_params.
*
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
*/
int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output);
int MBEDTLS_DEPRECATED mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output);
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
/**
* \brief PKCS#5 PBES2 function
*
* \warning When decrypting:
* - This function validates the CBC padding and returns
* #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is
* invalid. Note that this can help active adversaries
* attempting to brute-forcing the password. Note also that
* there is no guarantee that an invalid password will be
* detected (the chances of a valid padding with a random
* password are about 1/255).
*
* \param pbe_params the ASN.1 algorithm parameters
* \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT
* \param pwd password to use when generating key
* \param pwdlen length of password
* \param data data to process
* \param datalen length of data
* \param output Output buffer.
* On success, it contains the decrypted data.
* On failure, the content is indetermidate.
* For decryption, there must be enough room for \p datalen
* bytes.
* For encryption, there must be enough room for
* \p datalen + 1 bytes, rounded up to the block size of
* the block cipher identified by \p pbe_params.
* \param output_size size of output buffer.
* This must be big enough to accommodate for output plus
* padding data.
* \param output_len On success, length of actual data written to the output buffer.
*
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if parsing or decryption fails.
*/
int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output, size_t output_size,
size_t *output_len);
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C*/
/**
* \brief PKCS#5 PBKDF2 using HMAC without using the HMAC context

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