Merge branch 'development' into sha3

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2023-05-05 16:01:18 +02:00
commit d06c6fc45b
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
405 changed files with 28422 additions and 16737 deletions

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
@ -16,4 +18,3 @@ 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.

26
.readthedocs.yaml Normal file
View file

@ -0,0 +1,26 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.9"
jobs:
pre_build:
- make apidoc
- breathe-apidoc -o docs/api apidoc/xml
# Build documentation in the docs/ directory with Sphinx
sphinx:
builder: dirhtml
configuration: docs/conf.py
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt

View file

@ -79,6 +79,7 @@ jobs:
# 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
@ -89,16 +90,14 @@ jobs:
packages:
- gcc
script:
# Do a manual build+test sequence rather than using all.sh, because
# there's no all.sh component that does what we want. We should set
# CFLAGS for arm64 host CC.
# 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
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
- make generated_files
- make CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
- 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
@ -117,16 +116,14 @@ jobs:
- clang
- 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. We should set
# CFLAGS for arm64 host CC.
# 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
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT
- scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY
- make generated_files
- make CC=clang CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
- 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

View file

@ -1,5 +1,10 @@
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)
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 everest_result)
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_P256M_EXAMPLE_DRIVER_ENABLED RESULT_VARIABLE p256m_result)
if(${result} EQUAL 0)
if(${everest_result} EQUAL 0)
add_subdirectory(everest)
endif()
if(${p256m_result} EQUAL 0)
add_subdirectory(p256-m)
endif()

View file

@ -1,2 +1,3 @@
THIRDPARTY_DIR = $(dir $(lastword $(MAKEFILE_LIST)))
THIRDPARTY_DIR = $(dir $(word 2, $(MAKEFILE_LIST)))
include $(THIRDPARTY_DIR)/everest/Makefile.inc
include $(THIRDPARTY_DIR)/p256-m/Makefile.inc

25
3rdparty/p256-m/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,25 @@
add_library(p256m
p256-m_driver_entrypoints.c
p256-m/p256-m.c)
target_include_directories(p256m
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/)
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
EXPORT MbedTLSTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)

5
3rdparty/p256-m/Makefile.inc vendored Normal file
View file

@ -0,0 +1,5 @@
THIRDPARTY_INCLUDES+=-I../3rdparty/p256-m/p256-m/include -I../3rdparty/p256-m/p256-m/include/p256-m -I../3rdparty/p256-m/p256-m_driver_interface
THIRDPARTY_CRYPTO_OBJECTS+= \
../3rdparty/p256-m//p256-m_driver_entrypoints.o \
../3rdparty/p256-m//p256-m/p256-m.o

4
3rdparty/p256-m/README.md vendored Normal file
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), which is distributed under the Apache 2.0 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` and `.h`, along with the license, 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()`.

202
3rdparty/p256-m/p256-m/LICENSE vendored Normal file
View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"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.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"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.
"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).
"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.
"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."
"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.
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.
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.
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:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(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
(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.

544
3rdparty/p256-m/p256-m/README.md vendored Normal file
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).

1470
3rdparty/p256-m/p256-m/p256-m.c vendored Normal file

File diff suppressed because it is too large Load diff

95
3rdparty/p256-m/p256-m/p256-m.h vendored Normal file
View file

@ -0,0 +1,95 @@
/*
* Interface of curve P-256 (ECDH and ECDSA)
*
* Author: Manuel Pégourié-Gonnard.
* SPDX-License-Identifier: Apache-2.0
*/
#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);
#ifdef __cplusplus
}
#endif
#endif /* P256_M_H */

View file

@ -0,0 +1,242 @@
/*
* Driver entry points for p256-m
*/
/*
* 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.
*/
#include "mbedtls/platform.h"
#include "p256-m_driver_entrypoints.h"
#include "p256-m/p256-m.h"
#include "psa/crypto.h"
#include "psa_crypto_driver_wrappers.h"
#include <stddef.h>
#if defined(MBEDTLS_P256M_EXAMPLE_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.
*/
/* 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_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;
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
/*
* p256-m generates a 32 byte private key, and expects to write to a buffer
* that is of that size. */
if (key_buffer_size != 32) {
return status;
}
/*
* 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[64];
status = p256_to_psa_error(
p256_gen_keypair(key_buffer, public_key_buffer));
if (status == PSA_SUCCESS) {
*key_buffer_length = 32;
}
return status;
}
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;
/*
* Check that private key = 32 bytes, peer public key = 65 bytes,
* and that the shared secret buffer is big enough. */
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if (key_buffer_size != 32 || shared_secret_size < 32 ||
peer_key_length != 65) {
return status;
}
/* We add 1 to peer_key pointer to omit the leading byte of the public key
* representation (0x04). See information about PSA key formats at the top
* of the file. */
status = p256_to_psa_error(
p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key+1));
if (status == PSA_SUCCESS) {
*shared_secret_length = 32;
}
return status;
}
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;
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if (key_buffer_size != 32 || signature_size != 64) {
return status;
}
status = p256_to_psa_error(
p256_ecdsa_sign(signature, key_buffer, hash, hash_length));
if (status == PSA_SUCCESS) {
*signature_length = 64;
}
return status;
}
/* This function expects the key buffer to contain a 65 byte 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)
{
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if (key_buffer_size != 65 || signature_length != 64 || *key_buffer != 0x04) {
return status;
}
/* We add 1 to public_key_buffer pointer to omit the leading byte of the
* public key representation (0x04). See information about PSA key formats
* at the top of the file. */
const uint8_t *public_key_buffer = key_buffer + 1;
status = p256_to_psa_error(
p256_ecdsa_verify(signature, public_key_buffer, hash, hash_length));
return status;
}
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[65];
size_t public_key_buffer_size = 65;
size_t public_key_length = 65;
/* 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_P256M_EXAMPLE_DRIVER_ENABLED */

View file

@ -0,0 +1,162 @@
/*
* Driver entry points for p256-m
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef P256M_DRIVER_ENTRYPOINTS_H
#define P256M_DRIVER_ENTRYPOINTS_H
#if defined(MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED)
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
#endif /* MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED */
#include "psa/crypto_types.h"
/** 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_NOT_SUPPORTED
* \retval #PSA_ERROR_GENERIC_ERROR
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
*/
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_NOT_SUPPORTED
*/
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.
* respectively of the key.
* \retval #PSA_ERROR_NOT_SUPPORTED
*/
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_NOT_SUPPORTED
*/
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 */

View file

@ -23,6 +23,11 @@ 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.
Every major version will become an LTS branch when the next major version is
released. We may occasionally create LTS branches from other releases at our
discretion.
When a new LTS branch is created, it usually remains supported for three years.
## Backwards Compatibility for application code
We maintain API compatibility in released versions of Mbed TLS. If you have
@ -101,6 +106,6 @@ The following branches are currently maintained:
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
- [`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.2>.
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.3>.
Users are urged to always use the latest version of a maintained branch.

View file

@ -280,12 +280,23 @@ add_subdirectory(library)
# to define the test executables.
#
if(ENABLE_TESTING OR ENABLE_PROGRAMS)
file(GLOB MBEDTLS_TEST_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/drivers/*.c)
file(GLOB MBEDTLS_TEST_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/tests/src/drivers/*.c)
add_library(mbedtls_test OBJECT ${MBEDTLS_TEST_FILES})
target_include_directories(mbedtls_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library)
file(GLOB MBEDTLS_TEST_HELPER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tests/src/test_helpers/*.c)
add_library(mbedtls_test_helpers OBJECT ${MBEDTLS_TEST_HELPER_FILES})
target_include_directories(mbedtls_test_helpers
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/everest/include)
endif()
if(ENABLE_PROGRAMS)
@ -343,7 +354,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
write_basic_package_version_file(
"cmake/MbedTLSConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
VERSION 3.3.0)
VERSION 3.4.0)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"

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

240
ChangeLog
View file

@ -1,5 +1,216 @@
Mbed TLS ChangeLog (Sorted per branch, date)
= Mbed TLS 3.4.0 branch released 2023-03-28
Default behavior changes
* The default priority order of TLS 1.3 cipher suites has been modified to
follow the same rules as the TLS 1.2 cipher suites (see
ssl_ciphersuites.c). The preferred cipher suite is now
TLS_CHACHA20_POLY1305_SHA256.
New deprecations
* mbedtls_x509write_crt_set_serial() is now being deprecated in favor of
mbedtls_x509write_crt_set_serial_raw(). The goal here is to remove any
direct dependency of X509 on BIGNUM_C.
* PSA to mbedtls error translation is now unified in psa_util.h,
deprecating mbedtls_md_error_from_psa. Each file that performs error
translation should define its own version of PSA_TO_MBEDTLS_ERR,
optionally providing file-specific error pairs. Please see psa_util.h for
more details.
Features
* Added partial support for parsing the PKCS #7 Cryptographic Message
Syntax, as defined in RFC 2315. Currently, support is limited to the
following:
- Only the signed-data content type, version 1 is supported.
- Only DER encoding is supported.
- Only a single digest algorithm per message is supported.
- Certificates must be in X.509 format. A message must have either 0
or 1 certificates.
- There is no support for certificate revocation lists.
- The authenticated and unauthenticated attribute fields of SignerInfo
must be empty.
Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
contributing this feature, and to Demi-Marie Obenour for contributing
various improvements, tests and bug fixes.
* General performance improvements by accessing multiple bytes at a time.
Fixes #1666.
* Improvements to use of unaligned and byte-swapped memory, reducing code
size and improving performance (depending on compiler and target
architecture).
* Add support for reading points in compressed format
(MBEDTLS_ECP_PF_COMPRESSED) with mbedtls_ecp_point_read_binary()
(and callers) for Short Weierstrass curves with prime p where p = 3 mod 4
(all mbedtls MBEDTLS_ECP_DP_SECP* and MBEDTLS_ECP_DP_BP* curves
except MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1)
* SHA224_C/SHA384_C are now independent from SHA384_C/SHA512_C respectively.
This helps in saving code size when some of the above hashes are not
required.
* Add parsing of V3 extensions (key usage, Netscape cert-type,
Subject Alternative Names) in x509 Certificate Sign Requests.
* Use HOSTCC (if it is set) when compiling C code during generation of the
configuration-independent files. This allows them to be generated when
CC is set for cross compilation.
* Add parsing of uniformResourceIdentifier subtype for subjectAltName
extension in x509 certificates.
* Add an interruptible version of sign and verify hash to the PSA interface,
backed by internal library support for ECDSA signing and verification.
* Add parsing of rfc822Name subtype for subjectAltName
extension in x509 certificates.
* The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and
MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for
the headers "psa/crypto_platform.h" and "psa/crypto_struct.h".
* When a PSA driver for ECDSA is present, it is now possible to disable
MBEDTLS_ECDSA_C in the build in order to save code size. For PK, X.509
and TLS to fully work, this requires MBEDTLS_USE_PSA_CRYPTO to be enabled.
Restartable/interruptible ECDSA operations in PK, X.509 and TLS are not
supported in those builds yet, as driver support for interruptible ECDSA
operations is not present yet.
* Add a driver dispatch layer for EC J-PAKE, enabling alternative
implementations of EC J-PAKE through the driver entry points.
* Add new API mbedtls_ssl_cache_remove for cache entry removal by
its session id.
* Add support to include the SubjectAltName extension to a CSR.
* Add support for AES with the Armv8-A Cryptographic Extension on
64-bit Arm. A new configuration option, MBEDTLS_AESCE_C, can
be used to enable this feature. Run-time detection is supported
under Linux only.
* When a PSA driver for EC J-PAKE is present, it is now possible to disable
MBEDTLS_ECJPAKE_C in the build in order to save code size. For the
corresponding TLS 1.2 key exchange to work, MBEDTLS_USE_PSA_CRYPTO needs
to be enabled.
* Add functions mbedtls_rsa_get_padding_mode() and mbedtls_rsa_get_md_alg()
to read non-public fields for padding mode and hash id from
an mbedtls_rsa_context, as requested in #6917.
* AES-NI is now supported with Visual Studio.
* AES-NI is now supported in 32-bit builds, or when MBEDTLS_HAVE_ASM
is disabled, when compiling with GCC or Clang or a compatible compiler
for a target CPU that supports the requisite instructions (for example
gcc -m32 -msse2 -maes -mpclmul). (Generic x86 builds with GCC-like
compilers still require MBEDTLS_HAVE_ASM and a 64-bit target.)
* It is now possible to use a PSA-held (opaque) password with the TLS 1.2
ECJPAKE key exchange, using the new API function
mbedtls_ssl_set_hs_ecjpake_password_opaque().
Security
* Use platform-provided secure zeroization function where possible, such as
explicit_bzero().
* Zeroize SSL cache entries when they are freed.
* Fix a potential heap buffer overread in TLS 1.3 client-side when
MBEDTLS_DEBUG_C is enabled. This may result in an application crash.
* Add support for AES with the Armv8-A Cryptographic Extension on 64-bit
Arm, so that these systems are no longer vulnerable to timing side-channel
attacks. This is configured by MBEDTLS_AESCE_C, which is on by default.
Reported by Demi Marie Obenour.
* MBEDTLS_AESNI_C, which is enabled by default, was silently ignored on
builds that couldn't compile the GCC-style assembly implementation
(most notably builds with Visual Studio), leaving them vulnerable to
timing side-channel attacks. There is now an intrinsics-based AES-NI
implementation as a fallback for when the assembly one cannot be used.
Bugfix
* Fix possible integer overflow in mbedtls_timing_hardclock(), which
could cause a crash in programs/test/benchmark.
* Fix IAR compiler warnings. Fixes #6924.
* Fix a bug in the build where directory names containing spaces were
causing generate_errors.pl to error out resulting in a build failure.
Fixes issue #6879.
* In TLS 1.3, when using a ticket for session resumption, tweak its age
calculation on the client side. It prevents a server with more accurate
ticket timestamps (typically timestamps in milliseconds) compared to the
Mbed TLS ticket timestamps (in seconds) to compute a ticket age smaller
than the age computed and transmitted by the client and thus potentially
reject the ticket. Fix #6623.
* Fix compile error where MBEDTLS_RSA_C and MBEDTLS_X509_CRT_WRITE_C are
defined, but MBEDTLS_PK_RSA_ALT_SUPPORT is not defined. Fixes #3174.
* List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
be toggled with config.py.
* The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
used on a shared secret from a key agreement since its input must be
an ECC public key. Reject this properly.
* mbedtls_x509write_crt_set_serial() now explicitly rejects serial numbers
whose binary representation is longer than 20 bytes. This was already
forbidden by the standard (RFC5280 - section 4.1.2.2) and now it's being
enforced also at code level.
* Fix potential undefined behavior in mbedtls_mpi_sub_abs(). Reported by
Pascal Cuoq using TrustInSoft Analyzer in #6701; observed independently by
Aaron Ucko under Valgrind.
* Fix behavior of certain sample programs which could, when run with no
arguments, access uninitialized memory in some cases. Fixes #6700 (which
was found by TrustInSoft Analyzer during REDOCS'22) and #1120.
* Fix parsing of X.509 SubjectAlternativeName extension. Previously,
malformed alternative name components were not caught during initial
certificate parsing, but only on subsequent calls to
mbedtls_x509_parse_subject_alt_name(). Fixes #2838.
* Make the fields of mbedtls_pk_rsassa_pss_options public. This makes it
possible to verify RSA PSS signatures with the pk module, which was
inadvertently broken since Mbed TLS 3.0.
* Fix bug in conversion from OID to string in
mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed
correctly.
* Reject OIDs with overlong-encoded subidentifiers when converting
them to a string.
* Reject OIDs with subidentifier values exceeding UINT_MAX. Such
subidentifiers can be valid, but Mbed TLS cannot currently handle them.
* Reject OIDs that have unterminated subidentifiers, or (equivalently)
have the most-significant bit set in their last byte.
* Silence warnings from clang -Wdocumentation about empty \retval
descriptions, which started appearing with Clang 15. Fixes #6960.
* Fix the handling of renegotiation attempts in TLS 1.3. They are now
systematically rejected.
* Fix an unused-variable warning in TLS 1.3-only builds if
MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200.
* Fix undefined behavior in mbedtls_ssl_read() and mbedtls_ssl_write() if
len argument is 0 and buffer is NULL.
* Allow setting user and peer identifiers for EC J-PAKE operation
instead of role in PAKE PSA Crypto API as described in the specification.
This is a partial fix that allows only "client" and "server" identifiers.
* Fix a compilation error when PSA Crypto is built with support for
TLS12_PRF but not TLS12_PSK_TO_MS. Reported by joerchan in #7125.
* In the TLS 1.3 server, select the preferred client cipher suite, not the
least preferred. The selection error was introduced in Mbed TLS 3.3.0.
* Fix TLS 1.3 session resumption when the established pre-shared key is
384 bits long. That is the length of pre-shared keys created under a
session where the cipher suite is TLS_AES_256_GCM_SHA384.
* Fix an issue when compiling with MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
enabled, which required specifying compiler flags enabling SHA3 Crypto
Extensions, where some compilers would emit EOR3 instructions in other
modules, which would then fail if run on a CPU without the SHA3
extensions. Fixes #5758.
Changes
* Install the .cmake files into CMAKE_INSTALL_LIBDIR/cmake/MbedTLS,
typically /usr/lib/cmake/MbedTLS.
* Mixed-endian systems are explicitly not supported any more.
* When MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_ECDSA_DETERMINISTIC are both
defined, mbedtls_pk_sign() now use deterministic ECDSA for ECDSA
signatures. This aligns the behaviour with MBEDTLS_USE_PSA_CRYPTO to
the behaviour without it, where deterministic ECDSA was already used.
* Visual Studio: Rename the directory containing Visual Studio files from
visualc/VS2010 to visualc/VS2013 as we do not support building with versions
older than 2013. Update the solution file to specify VS2013 as a minimum.
* programs/x509/cert_write:
- now it accepts the serial number in 2 different formats: decimal and
hex. They cannot be used simultaneously
- "serial" is used for the decimal format and it's limted in size to
unsigned long long int
- "serial_hex" is used for the hex format; max length here is
MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN*2
* The C code follows a new coding style. This is transparent for users but
affects contributors and maintainers of local patches. For more
information, see
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/rewrite-branch-for-coding-style/
* Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2.
As tested in issue 6790, the correlation between this define and
RSA decryption performance has changed lately due to security fixes.
To fix the performance degradation when using default values the
window was reduced from 6 to 2, a value that gives the best or close
to best results when tested on Cortex-M4 and Intel i7.
* When enabling MBEDTLS_SHA256_USE_A64_CRYPTO_* or
MBEDTLS_SHA512_USE_A64_CRYPTO_*, it is no longer necessary to specify
compiler target flags on the command line; the library now sets target
options within the appropriate modules.
= Mbed TLS 3.3.0 branch released 2022-12-14
Default behavior changes
@ -106,11 +317,11 @@ Security
* Fix potential heap buffer overread and overwrite in DTLS if
MBEDTLS_SSL_DTLS_CONNECTION_ID is enabled and
MBEDTLS_SSL_CID_IN_LEN_MAX > 2 * MBEDTLS_SSL_CID_OUT_LEN_MAX.
* An adversary with access to precise enough information about memory
accesses (typically, an untrusted operating system attacking a secure
enclave) could recover an RSA private key after observing the victim
performing a single private-key operation if the window size used for the
exponentiation was 3 or smaller. Found and reported by Zili KOU,
* Fix an issue where an adversary with access to precise enough information
about memory accesses (typically, an untrusted operating system attacking
a secure enclave) could recover an RSA private key after observing the
victim performing a single private-key operation if the window size used
for the exponentiation was 3 or smaller. Found and reported by Zili KOU,
Wenjian HE, Sharad Sinha, and Wei ZHANG. See "Cache Side-channel Attacks
and Defenses of the Sliding Window Algorithm in TEEs" - Design, Automation
and Test in Europe 2023.
@ -969,16 +1180,17 @@ Security
signature, allowing the recovery of the private key after observing a
large number of signature operations. This completes a partial fix in
Mbed TLS 2.20.0.
* An adversary with access to precise enough information about memory
accesses (typically, an untrusted operating system attacking a secure
enclave) could recover an RSA private key after observing the victim
performing a single private-key operation. Found and reported by
* Fix an issue where an adversary with access to precise enough information
about memory accesses (typically, an untrusted operating system attacking
a secure enclave) could recover an RSA private key after observing the
victim performing a single private-key operation. Found and reported by
Zili KOU, Wenjian HE, Sharad Sinha, and Wei ZHANG.
* An adversary with access to precise enough timing information (typically, a
co-located process) could recover a Curve25519 or Curve448 static ECDH key
after inputting a chosen public key and observing the victim performing the
corresponding private-key operation. Found and reported by Leila Batina,
Lukas Chmielewski, Björn Haase, Niels Samwel and Peter Schwabe.
* Fix an issue where an adversary with access to precise enough timing
information (typically, a co-located process) could recover a Curve25519
or Curve448 static ECDH key after inputting a chosen public key and
observing the victim performing the corresponding private-key operation.
Found and reported by Leila Batina, Lukas Chmielewski, Björn Haase, Niels
Samwel and Peter Schwabe.
Bugfix
* Fix premature fopen() call in mbedtls_entropy_write_seed_file which may

View file

@ -0,0 +1,3 @@
Features
* Add parsing of directoryName subtype for subjectAltName extension in
x509 certificates.

View file

@ -0,0 +1,5 @@
API changes
* 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.

View file

@ -0,0 +1,5 @@
Bugfix
* 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.

View file

@ -1,3 +0,0 @@
Features
* Add parsing of uniformResourceIdentifier subtype for subjectAltName
extension in x509 certificates.

View file

@ -1,5 +0,0 @@
Features
* Add an interruptible version of sign and verify hash to the PSA interface,
backed by internal library support for ECDSA signing and verification.

View file

@ -1,8 +0,0 @@
Features
* General performance improvements by accessing multiple bytes at a time.
Fixes #1666.
* Improvements to use of unaligned and byte-swapped memory, reducing code
size and improving performance (depending on compiler and target
architecture).
Changes
* Mixed-endian systems are explicitly not supported any more.

View file

@ -1,4 +0,0 @@
Features
* Use HOSTCC (if it is set) when compiling C code during generation of the
configuration-independent files. This allows them to be generated when
CC is set for cross compilation.

View file

@ -1,3 +0,0 @@
Changes
* Install the .cmake files into CMAKE_INSTALL_LIBDIR/cmake/MbedTLS,
typically /usr/lib/cmake/MbedTLS.

View file

@ -1,5 +0,0 @@
Changes
* The C code follows a new coding style. This is transparent for users but
affects contributors and maintainers of local patches. For more
information, see
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/rewrite-branch-for-coding-style/

View file

@ -1,4 +0,0 @@
Bugfix
* Fix potential undefined behavior in mbedtls_mpi_sub_abs(). Reported by
Pascal Cuoq using TrustInSoft Analyzer in #6701; observed independently by
Aaron Ucko under Valgrind.

View file

@ -1,3 +0,0 @@
Bugfix
* List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
be toggled with config.py.

View file

@ -1,3 +0,0 @@
Features
* Add parsing of V3 extensions (key usage, Netscape cert-type,
Subject Alternative Names) in x509 Certificate Sign Requests.

View file

@ -0,0 +1,7 @@
Features
* 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.

View file

@ -0,0 +1,10 @@
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.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix the J-PAKE driver interface for user and peer to accept any values
(previously accepted values were limited to "client" or "server").

View file

@ -1,3 +0,0 @@
Bugfix
* Silence warnings from clang -Wdocumentation about empty \retval
descriptions, which started appearing with Clang 15. Fixes #6960.

View file

@ -0,0 +1,5 @@
Bugfix
* 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.

View file

@ -1,4 +0,0 @@
Bugfix
* Fix behavior of certain sample programs which could, when run with no
arguments, access uninitialized memory in some cases. Fixes #6700 (which
was found by TrustInSoft Analyzer during REDOCS'22) and #1120.

View file

@ -1,3 +0,0 @@
Bugfix
* Fix possible integer overflow in mbedtls_timing_hardclock(), which
could cause a crash in programs/test/benchmark.

View file

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

View file

@ -1,6 +0,0 @@
Bugfix
* Fix bug in conversion from OID to string in
mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed
correctly.
* Reject OIDs with overlong-encoded subidentifiers when converting
OID-to-string.

View file

@ -1,3 +0,0 @@
Bugfix
* Fix compile error where MBEDTLS_RSA_C and MBEDTLS_X509_CRT_WRITE_C are
defined, but MBEDTLS_PK_RSA_ALT_SUPPORT is not defined. Fixes #3174.

View file

@ -1,4 +0,0 @@
Bugfix
* Fix a bug in the build where directory names containing spaces were
causing generate_errors.pl to error out resulting in a build failure.
Fixes issue #6879.

View file

@ -1,19 +0,0 @@
Bugfix
* mbedtls_x509write_crt_set_serial() now explicitly rejects serial numbers
whose binary representation is longer than 20 bytes. This was already
forbidden by the standard (RFC5280 - section 4.1.2.2) and now it's being
enforced also at code level.
New deprecations
* mbedtls_x509write_crt_set_serial() is now being deprecated in favor of
mbedtls_x509write_crt_set_serial_raw(). The goal here is to remove any
direct dependency of X509 on BIGNUM_C.
Changes
* programs/x509/cert_write:
- now it accepts the serial number in 2 different formats: decimal and
hex. They cannot be used simultaneously
- "serial" is used for the decimal format and it's limted in size to
unsigned long long int
- "serial_hex" is used for the hex format; max length here is
MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN*2

View file

@ -1,4 +0,0 @@
Features
* SHA224_C/SHA384_C are now independent from SHA384_C/SHA512_C respectively.
This helps in saving code size when some of the above hashes are not
required.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix an error when MBEDTLS_ECDSA_SIGN_ALT is defined but not
MBEDTLS_ECDSA_VERIFY_ALT, causing ecdsa verify to fail. Fixes #7498.

View file

@ -1,6 +0,0 @@
Features
* Add support for reading points in compressed format
(MBEDTLS_ECP_PF_COMPRESSED) with mbedtls_ecp_point_read_binary()
(and callers) for Short Weierstrass curves with prime p where p = 3 mod 4
(all mbedtls MBEDTLS_ECP_DP_SECP* and MBEDTLS_ECP_DP_BP* curves
except MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1)

View file

@ -1,7 +0,0 @@
Changes
* Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2.
As tested in issue 6790, the correlation between this define and
RSA decryption performance has changed lately due to security fixes.
To fix the performance degradation when using default values the
window was reduced from 6 to 2, a value that gives the best or close
to best results when tested on Cortex-M4 and Intel i7.

View file

@ -1,5 +0,0 @@
Changes
* When MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_ECDSA_DETERMINISTIC are both
defined, mbedtls_pk_sign() now use deterministic ECDSA for ECDSA
signatures. This aligns the behaviour with MBEDTLS_USE_PSA_CRYPTO to
the behaviour without it, where deterministic ECDSA was already used.

View file

@ -1,4 +0,0 @@
Bugfix
* Make the fields of mbedtls_pk_rsassa_pss_options public. This makes it
possible to verify RSA PSS signatures with the pk module, which was
inadvertently broken since Mbed TLS 3.0.

View file

@ -0,0 +1,3 @@
Bugfix
* Fix missing PSA initialization in sample programs when
MBEDTLS_USE_PSA_CRYPTO is enabled.

View file

@ -1,4 +0,0 @@
Features
* The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and
MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for
the headers "psa/crypto_platform.h" and "psa/crypto_struct.h".

View file

@ -1,4 +0,0 @@
Bugfix
* The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
used on a shared secret from a key agreement since its input must be
an ECC public key. Reject this properly.

3
ChangeLog.d/rfc8410.txt Normal file
View file

@ -0,0 +1,3 @@
Features
* Add support for reading and writing X25519 and X448
public and private keys in RFC 8410 format using the existing PK APIs.

View file

@ -1,3 +0,0 @@
Features
* Add parsing of rfc822Name subtype for subjectAltName
extension in x509 certificates.

View file

@ -0,0 +1,5 @@
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.

View file

@ -1,5 +0,0 @@
Bugfix
* Fix the handling of renegotiation attempts in TLS 1.3. They are now
systematically rejected.
* Fix an unused-variable warning in TLS 1.3-only builds if
MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200.

View file

@ -0,0 +1,5 @@
Features
* 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.

View file

@ -0,0 +1,2 @@
Features
* X.509 hostname verification now supports IPAddress Subject Alternate Names.

View file

@ -1,4 +0,0 @@
Changes
* Visual Studio: Rename the directory containing Visual Studio files from
visualc/VS2010 to visualc/VS2013 as we do not support building with versions
older than 2013. Update the solution file to specify VS2013 as a minimum.

View file

@ -1,7 +0,0 @@
Bugfix
* In TLS 1.3, when using a ticket for session resumption, tweak its age
calculation on the client side. It prevents a server with more accurate
ticket timestamps (typically timestamps in milliseconds) compared to the
Mbed TLS ticket timestamps (in seconds) to compute a ticket age smaller
than the age computed and transmitted by the client and thus potentially
reject the ticket. Fix #6623.

View file

@ -1,5 +0,0 @@
Bugfix
* Fix parsing of X.509 SubjectAlternativeName extension. Previously,
malformed alternative name components were not caught during initial
certificate parsing, but only on subsequent calls to
mbedtls_x509_parse_subject_alt_name(). Fixes #2838.

View file

@ -61,10 +61,11 @@ 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 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
```
python -m pip install -r scripts/basic.requirements.txt
python3 -m pip install --user -r scripts/basic.requirements.txt
```
Depending on your Python installation, you may need to invoke `python` instead of `python3`. To install the packages system-wide, omit the `--user` option.
* A C compiler for the host platform, for some test data.
If you are cross-compiling, you must set the `CC` environment variable to a C compiler for the host platform when generating the configuration-independent files.
@ -306,6 +307,12 @@ 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.
### Third-party code included in Mbed TLS
This project contains code from other projects. This code is located within the `3rdparty/` directory. The original license text is included within project subdirectories, and in source files. The projects are listed below:
* `3rdparty/everest/`: Files stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is also used by the project under the Apache 2.0 license. We do not plan to regularly update these files, so they may not contain fixes and improvements present in the upstream project.
Contributing
------------

View file

@ -18,3 +18,120 @@ goes public.
Only the maintained branches, as listed in [`BRANCHES.md`](BRANCHES.md),
get security fixes.
Users are urged to always use the latest version of a maintained branch.
## Threat model
We classify attacks based on the capabilities of the attacker.
### Remote attacks
In this section, we consider an attacker who can observe and modify data sent
over the network. This includes observing the content and timing of individual
packets, as well as suppressing or delaying legitimate messages, and injecting
messages.
Mbed TLS aims to fully protect against remote attacks and to enable the user
application in providing full protection against remote attacks. Said
protection is limited to providing security guarantees offered by the protocol
being implemented. (For example Mbed TLS alone won't guarantee that the
messages will arrive without delay, as the TLS protocol doesn't guarantee that
either.)
**Warning!** Block ciphers do not yet achieve full protection against attackers
who can measure the timing of packets with sufficient precision. For details
and workarounds see the [Block Ciphers](#block-ciphers) section.
### Local attacks
In this section, we consider an attacker who can run software on the same
machine. The attacker has insufficient privileges to directly access Mbed TLS
assets such as memory and files.
#### Timing attacks
The attacker is able to observe the timing of instructions executed by Mbed TLS
by leveraging shared hardware that both Mbed TLS and the attacker have access
to. Typical attack vectors include cache timings, memory bus contention and
branch prediction.
Mbed TLS provides limited protection against timing attacks. The cost of
protecting against timing attacks widely varies depending on the granularity of
the measurements and the noise present. Therefore the protection in Mbed TLS is
limited. We are only aiming to provide protection against **publicly
documented attack techniques**.
As attacks keep improving, so does Mbed TLS's protection. Mbed TLS is moving
towards a model of fully timing-invariant code, but has not reached this point
yet.
**Remark:** Timing information can be observed over the network or through
physical side channels as well. Remote and physical timing attacks are covered
in the [Remote attacks](remote-attacks) and [Physical
attacks](physical-attacks) sections respectively.
**Warning!** Block ciphers do not yet achieve full protection. For
details and workarounds see the [Block Ciphers](#block-ciphers) section.
#### Local non-timing side channels
The attacker code running on the platform has access to some sensor capable of
picking up information on the physical state of the hardware while Mbed TLS is
running. This could for example be an analogue-to-digital converter on the
platform that is located unfortunately enough to pick up the CPU noise.
Mbed TLS doesn't make any security guarantees against local non-timing-based
side channel attacks. If local non-timing attacks are present in a use case or
a user application's threat model, they need to be mitigated by the platform.
#### Local fault injection attacks
Software running on the same hardware can affect the physical state of the
device and introduce faults.
Mbed TLS doesn't make any security guarantees against local fault injection
attacks. If local fault injection attacks are present in a use case or a user
application's threat model, they need to be mitigated by the platform.
### Physical attacks
In this section, we consider an attacker who has access to physical information
about the hardware Mbed TLS is running on and/or can alter the physical state
of the hardware (e.g. power analysis, radio emissions or fault injection).
Mbed TLS doesn't make any security guarantees against physical attacks. If
physical attacks are present in a use case or a user application's threat
model, they need to be mitigated by physical countermeasures.
### Caveats
#### Out-of-scope countermeasures
Mbed TLS has evolved organically and a well defined threat model hasn't always
been present. Therefore, Mbed TLS might have countermeasures against attacks
outside the above defined threat model.
The presence of such countermeasures don't mean that Mbed TLS provides
protection against a class of attacks outside of the above described threat
model. Neither does it mean that the failure of such a countermeasure is
considered a vulnerability.
#### Block ciphers
Currently there are four block ciphers in Mbed TLS: AES, CAMELLIA, ARIA and
DES. The pure software implementation in Mbed TLS implementation uses lookup
tables, which are vulnerable to timing attacks.
These timing attacks can be physical, local or depending on network latency
even a remote. The attacks can result in key recovery.
**Workarounds:**
- Turn on hardware acceleration for AES. This is supported only on selected
architectures and currently only available for AES. See configuration options
`MBEDTLS_AESCE_C`, `MBEDTLS_AESNI_C` and `MBEDTLS_PADLOCK_C` for details.
- Add a secure alternative implementation (typically hardware acceleration) for
the vulnerable cipher. See the [Alternative Implementations
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.

2
docs/.gitignore vendored
View file

@ -1,2 +1,4 @@
*.html
*.pdf
_build/
api/

40
docs/Makefile Normal file
View file

@ -0,0 +1,40 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help clean apidoc breathe_apidoc Makefile
# Intercept the 'clean' target so we can do the right thing for apidoc as well
clean:
@# Clean the apidoc
$(MAKE) -C .. apidoc_clean
@# Clean the breathe-apidoc generated files
rm -rf ./api
@# Clean the sphinx docs
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
apidoc:
@# Generate doxygen from source using the main Makefile
$(MAKE) -C .. apidoc
breathe_apidoc: apidoc
@# Remove existing files - breathe-apidoc skips them if they're present
rm -rf ./api
@# Generate RST file structure with breathe-apidoc
breathe-apidoc -o ./api ../apidoc/xml
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile breathe_apidoc
@# Build the relevant target with sphinx
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View file

@ -354,7 +354,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.

View file

@ -312,13 +312,16 @@ Note that some algorithms have different spellings in legacy and PSA. Since MD i
```
#if defined(MBEDTLS_MD_LIGHT)
#if defined(MBEDTLS_SHA256_C) || \
((defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)) && \
PSA_WANT_ALG_SHA_256)
(defined(MBEDTLS_PSA_CRYPTO_C) && PSA_WANT_ALG_SHA_256)
#define MBEDTLS_MD_CAN_SHA256
#endif
#endif
```
Note: in the future, we may want to replace `defined(MBEDTLS_PSA_CRYPTO_C)`
with `defined(MBEDTLS_PSA_CRYTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)` but
for now this is out of scope.
#### MD light internal support macros
* If at least one hash has a PSA driver, define `MBEDTLS_MD_SOME_PSA`.
@ -337,16 +340,11 @@ enum {
} mbedtls_md_engine_t; // private type
typedef struct mbedtls_md_context_t {
const mbedtls_md_type_t type;
const mbedtls_md_engine_t engine;
union {
#if defined(MBEDTLS_MD_SOME_LEGACY)
void *legacy; // used if engine == LEGACY
#endif
mbedtls_md_type_t type;
#if defined(MBEDTLS_MD_SOME_PSA)
psa_hash_operation_t *psa; // used if engine == PSA
mbedtls_md_engine_t engine;
#endif
} digest;
void *md_ctx; // mbedtls_xxx_context or psa_hash_operation
#if defined(MBEDTLS_MD_C)
void *hmac_ctx;
#endif

View file

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

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,8 +247,9 @@ 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
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.)
@ -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).

View file

@ -17,13 +17,20 @@
#
# 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 +42,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 +72,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

View file

@ -86,17 +86,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

34
docs/conf.py Normal file
View file

@ -0,0 +1,34 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
import glob
project = 'Mbed TLS Versioned'
copyright = '2023, Mbed TLS Contributors'
author = 'Mbed TLS Contributors'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = ['breathe', 'sphinx.ext.graphviz']
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
breathe_projects = {
'mbedtls-versioned': '../apidoc/xml'
}
breathe_default_project = 'mbedtls-versioned'
primary_domain = 'c'
highlight_language = 'c'
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']

View file

@ -1,962 +0,0 @@
## Getting started with Mbed TLS
### What is Mbed TLS?
Mbed TLS is an open source cryptographic library that supports a wide range of
cryptographic operations, including:
* Key management
* Hashing
* Symmetric cryptography
* Asymmetric cryptography
* Message authentication (MAC)
* Key generation and derivation
* Authenticated encryption with associated data (AEAD)
Mbed TLS provides a reference implementation of the cryptography interface of
the Arm Platform Security Architecture (PSA). It is written in portable C.
Mbed TLS is distributed under the Apache License, version 2.0.
#### Platform Security Architecture (PSA)
Arm's Platform Security Architecture (PSA) is a holistic set of threat models,
security analyses, hardware and firmware architecture specifications, and an
open source firmware reference implementation. PSA provides a recipe, based on
industry best practice, that enables you to design security into both hardware
and firmware consistently. Part of the API provided by PSA is the cryptography
interface, which provides access to a set of primitives.
### Using Mbed TLS
* [Getting the Mbed TLS library](#getting-the-mbed-tls-library)
* [Building the Mbed TLS library](#building-the-mbed-tls-library)
* [Using the PSA Crypto API](#using-the-psa-crypto-api)
* [Importing a key](#importing-a-key)
* [Signing a message using RSA](#signing-a-message-using-RSA)
* [Encrypting or decrypting using symmetric ciphers](#encrypting-or-decrypting-using-symmetric-ciphers)
* [Hashing a message](#hashing-a-message)
* [Deriving a new key from an existing key](#deriving-a-new-key-from-an-existing-key)
* [Generating a random value](#generating-a-random-value)
* [Authenticating and encrypting or decrypting a message](#authenticating-and-encrypting-or-decrypting-a-message)
* [Generating and exporting keys](#generating-and-exporting-keys)
* [More about the PSA Crypto API](#more-about-the-psa-crypto-api)
### Getting the Mbed TLS library
Mbed TLS releases are available in the [public GitHub repository](https://github.com/Mbed-TLS/mbedtls).
### Building the Mbed TLS library
**Prerequisites to building the library with the provided makefiles:**
* GNU Make.
* A C toolchain (compiler, linker, archiver) that supports C99.
* Python 3.6 to generate the test code.
* Perl to run the tests.
If you have a C compiler such as GCC or Clang, just run `make` in the top-level
directory to build the library, a set of unit tests and some sample programs.
To select a different compiler, set the `CC` variable to the name or path of the
compiler and linker (default: `cc`) and set `AR` to a compatible archiver
(default: `ar`); for example:
```
make CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar
```
The provided makefiles pass options to the compiler that assume a GCC-like
command line syntax. To use a different compiler, you may need to pass different
values for `CFLAGS`, `WARNINGS_CFLAGS` and `LDFLAGS`.
To run the unit tests on the host machine, run `make test` from the top-level
directory. If you are cross-compiling, copy the test executable from the `tests`
directory to the target machine.
### Using the PSA Crypto API
If using PSA Crypto, you must initialize the library by calling
`psa_crypto_init()` before any other PSA API.
### Importing a key
To use a key for cryptography operations in PSA, you need to first
import it. The import operation returns the identifier of the key for use
with other function calls.
**Prerequisites to importing keys:**
* Initialize the library with a successful call to `psa_crypto_init()`.
This example shows how to import a key:
```C
void import_a_key(const uint8_t *key, size_t key_len)
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id;
printf("Import an AES key...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Set key attributes */
psa_set_key_usage_flags(&attributes, 0);
psa_set_key_algorithm(&attributes, 0);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
/* Import the key */
status = psa_import_key(&attributes, key, key_len, &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to import key\n");
return;
}
printf("Imported a key\n");
/* Free the attributes */
psa_reset_key_attributes(&attributes);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
}
```
### Signing a message using RSA
The PSA Crypto API supports encrypting, decrypting, signing and verifying
messages using public key signature algorithms, such as RSA or ECDSA.
**Prerequisites to performing asymmetric signature operations:**
* Initialize the library with a successful call to `psa_crypto_init()`.
* Have a valid key with appropriate attributes set:
* Usage flag `PSA_KEY_USAGE_SIGN_HASH` to allow signing.
* Usage flag `PSA_KEY_USAGE_VERIFY_HASH` to allow signature verification.
* Algorithm set to the desired signature algorithm.
This example shows how to sign a hash that has already been calculated:
```C
void sign_a_message_using_rsa(const uint8_t *key, size_t key_len)
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t hash[32] = {0x50, 0xd8, 0x58, 0xe0, 0x98, 0x5e, 0xcc, 0x7f,
0x60, 0x41, 0x8a, 0xaf, 0x0c, 0xc5, 0xab, 0x58,
0x7f, 0x42, 0xc2, 0x57, 0x0a, 0x88, 0x40, 0x95,
0xa9, 0xe8, 0xcc, 0xac, 0xd0, 0xf6, 0x54, 0x5c};
uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = {0};
size_t signature_length;
psa_key_id_t key_id;
printf("Sign a message...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Set key attributes */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_bits(&attributes, 1024);
/* Import the key */
status = psa_import_key(&attributes, key, key_len, &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to import key\n");
return;
}
/* Sign message using the key */
status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
hash, sizeof(hash),
signature, sizeof(signature),
&signature_length);
if (status != PSA_SUCCESS) {
printf("Failed to sign\n");
return;
}
printf("Signed a message\n");
/* Free the attributes */
psa_reset_key_attributes(&attributes);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
}
```
### Using symmetric ciphers
The PSA Crypto API supports encrypting and decrypting messages using various
symmetric cipher algorithms (both block and stream ciphers).
**Prerequisites to working with the symmetric cipher API:**
* Initialize the library with a successful call to `psa_crypto_init()`.
* Have a symmetric key. This key's usage flags must include
`PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to
allow decryption.
**To encrypt a message with a symmetric cipher:**
1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the
cipher functions.
1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
1. Call `psa_cipher_encrypt_setup()` to specify the algorithm and the key to be
used.
1. Call either `psa_cipher_generate_iv()` or `psa_cipher_set_iv()` to generate
or set the initialization vector (IV). We recommend calling
`psa_cipher_generate_iv()`, unless you require a specific IV value.
1. Call `psa_cipher_update()` with the message to encrypt. You may call this
function multiple times, passing successive fragments of the message on
successive calls.
1. Call `psa_cipher_finish()` to end the operation and output the encrypted
message.
This example shows how to encrypt data using an AES (Advanced Encryption
Standard) key in CBC (Cipher Block Chaining) mode with no padding (assuming all
prerequisites have been fulfilled):
```c
void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
{
enum {
block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
};
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
uint8_t plaintext[block_size] = SOME_PLAINTEXT;
uint8_t iv[block_size];
size_t iv_len;
uint8_t output[block_size];
size_t output_len;
psa_key_id_t key_id;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
printf("Encrypt with cipher...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS)
{
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Import a key */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, key_len, &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Encrypt the plaintext */
status = psa_cipher_encrypt_setup(&operation, key_id, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin cipher operation\n");
return;
}
status = psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_len);
if (status != PSA_SUCCESS) {
printf("Failed to generate IV\n");
return;
}
status = psa_cipher_update(&operation, plaintext, sizeof(plaintext),
output, sizeof(output), &output_len);
if (status != PSA_SUCCESS) {
printf("Failed to update cipher operation\n");
return;
}
status = psa_cipher_finish(&operation, output + output_len,
sizeof(output) - output_len, &output_len);
if (status != PSA_SUCCESS) {
printf("Failed to finish cipher operation\n");
return;
}
printf("Encrypted plaintext\n");
/* Clean up cipher operation context */
psa_cipher_abort(&operation);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
}
```
**To decrypt a message with a symmetric cipher:**
1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the
cipher functions.
1. Initialize the operation structure to zero or to `PSA_CIPHER_OPERATION_INIT`.
1. Call `psa_cipher_decrypt_setup()` to specify the algorithm and the key to be
used.
1. Call `psa_cipher_set_iv()` with the IV for the decryption.
1. Call `psa_cipher_update()` with the message to encrypt. You may call this
function multiple times, passing successive fragments of the message on
successive calls.
1. Call `psa_cipher_finish()` to end the operation and output the decrypted
message.
This example shows how to decrypt encrypted data using an AES key in CBC mode
with no padding (assuming all prerequisites have been fulfilled):
```c
void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
{
enum {
block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES),
};
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
uint8_t ciphertext[block_size] = SOME_CIPHERTEXT;
uint8_t iv[block_size] = ENCRYPTED_WITH_IV;
uint8_t output[block_size];
size_t output_len;
psa_key_id_t key_id;
printf("Decrypt with cipher...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS)
{
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Import a key */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, key_len, &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Decrypt the ciphertext */
status = psa_cipher_decrypt_setup(&operation, key_id, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin cipher operation\n");
return;
}
status = psa_cipher_set_iv(&operation, iv, sizeof(iv));
if (status != PSA_SUCCESS) {
printf("Failed to set IV\n");
return;
}
status = psa_cipher_update(&operation, ciphertext, sizeof(ciphertext),
output, sizeof(output), &output_len);
if (status != PSA_SUCCESS) {
printf("Failed to update cipher operation\n");
return;
}
status = psa_cipher_finish(&operation, output + output_len,
sizeof(output) - output_len, &output_len);
if (status != PSA_SUCCESS) {
printf("Failed to finish cipher operation\n");
return;
}
printf("Decrypted ciphertext\n");
/* Clean up cipher operation context */
psa_cipher_abort(&operation);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
}
```
#### Handling cipher operation contexts
After you've initialized the operation structure with a successful call to
`psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()`, you can terminate
the operation at any time by calling `psa_cipher_abort()`.
The call to `psa_cipher_abort()` frees any resources associated with the
operation, except for the operation structure itself.
The PSA Crypto API implicitly calls `psa_cipher_abort()` when:
* A call to `psa_cipher_generate_iv()`, `psa_cipher_set_iv()` or
`psa_cipher_update()` fails (returning any status other than `PSA_SUCCESS`).
* A call to `psa_cipher_finish()` succeeds or fails.
After an implicit or explicit call to `psa_cipher_abort()`, the operation
structure is invalidated; in other words, you cannot reuse the operation
structure for the same operation. You can, however, reuse the operation
structure for a different operation by calling either
`psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()` again.
You must call `psa_cipher_abort()` at some point for any operation that is
initialized successfully (by a successful call to `psa_cipher_encrypt_setup()`
or `psa_cipher_decrypt_setup()`).
Making multiple sequential calls to `psa_cipher_abort()` on an operation that
is terminated (either implicitly or explicitly) is safe and has no effect.
### Hashing a message
The PSA Crypto API lets you compute and verify hashes using various hashing
algorithms.
**Prerequisites to working with the hash APIs:**
* Initialize the library with a successful call to `psa_crypto_init()`.
**To calculate a hash:**
1. Allocate an operation structure (`psa_hash_operation_t`) to pass to the hash
functions.
1. Initialize the operation structure to zero or to `PSA_HASH_OPERATION_INIT`.
1. Call `psa_hash_setup()` to specify the hash algorithm.
1. Call `psa_hash_update()` with the message to encrypt. You may call this
function multiple times, passing successive fragments of the message on
successive calls.
1. Call `psa_hash_finish()` to calculate the hash, or `psa_hash_verify()` to
compare the computed hash with an expected hash value.
This example shows how to calculate the SHA-256 hash of a message:
```c
psa_status_t status;
psa_algorithm_t alg = PSA_ALG_SHA_256;
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
unsigned char input[] = { 'a', 'b', 'c' };
unsigned char actual_hash[PSA_HASH_MAX_SIZE];
size_t actual_hash_len;
printf("Hash a message...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Compute hash of message */
status = psa_hash_setup(&operation, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin hash operation\n");
return;
}
status = psa_hash_update(&operation, input, sizeof(input));
if (status != PSA_SUCCESS) {
printf("Failed to update hash operation\n");
return;
}
status = psa_hash_finish(&operation, actual_hash, sizeof(actual_hash),
&actual_hash_len);
if (status != PSA_SUCCESS) {
printf("Failed to finish hash operation\n");
return;
}
printf("Hashed a message\n");
/* Clean up hash operation context */
psa_hash_abort(&operation);
mbedtls_psa_crypto_free();
```
This example shows how to verify the SHA-256 hash of a message:
```c
psa_status_t status;
psa_algorithm_t alg = PSA_ALG_SHA_256;
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
unsigned char input[] = { 'a', 'b', 'c' };
unsigned char expected_hash[] = {
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
};
size_t expected_hash_len = PSA_HASH_LENGTH(alg);
printf("Verify a hash...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Verify message hash */
status = psa_hash_setup(&operation, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin hash operation\n");
return;
}
status = psa_hash_update(&operation, input, sizeof(input));
if (status != PSA_SUCCESS) {
printf("Failed to update hash operation\n");
return;
}
status = psa_hash_verify(&operation, expected_hash, expected_hash_len);
if (status != PSA_SUCCESS) {
printf("Failed to verify hash\n");
return;
}
printf("Verified a hash\n");
/* Clean up hash operation context */
psa_hash_abort(&operation);
mbedtls_psa_crypto_free();
```
The API provides the macro `PSA_HASH_LENGTH`, which returns the expected hash
length (in bytes) for the specified algorithm.
#### Handling hash operation contexts
After a successful call to `psa_hash_setup()`, you can terminate the operation
at any time by calling `psa_hash_abort()`. The call to `psa_hash_abort()` frees
any resources associated with the operation, except for the operation structure
itself.
The PSA Crypto API implicitly calls `psa_hash_abort()` when:
1. A call to `psa_hash_update()` fails (returning any status other than
`PSA_SUCCESS`).
1. A call to `psa_hash_finish()` succeeds or fails.
1. A call to `psa_hash_verify()` succeeds or fails.
After an implicit or explicit call to `psa_hash_abort()`, the operation
structure is invalidated; in other words, you cannot reuse the operation
structure for the same operation. You can, however, reuse the operation
structure for a different operation by calling `psa_hash_setup()` again.
You must call `psa_hash_abort()` at some point for any operation that is
initialized successfully (by a successful call to `psa_hash_setup()`) .
Making multiple sequential calls to `psa_hash_abort()` on an operation that has
already been terminated (either implicitly or explicitly) is safe and has no
effect.
### Generating a random value
The PSA Crypto API can generate random data.
**Prerequisites to generating random data:**
* Initialize the library with a successful call to `psa_crypto_init()`.
<span class="notes">**Note:** To generate a random key, use `psa_generate_key()`
instead of `psa_generate_random()`.</span>
This example shows how to generate ten bytes of random data by calling
`psa_generate_random()`:
```C
psa_status_t status;
uint8_t random[10] = { 0 };
printf("Generate random...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
status = psa_generate_random(random, sizeof(random));
if (status != PSA_SUCCESS) {
printf("Failed to generate a random value\n");
return;
}
printf("Generated random data\n");
/* Clean up */
mbedtls_psa_crypto_free();
```
### Deriving a new key from an existing key
The PSA Crypto API provides a key derivation API that lets you derive new keys
from existing ones. The key derivation API has functions to take inputs,
including other keys and data, and functions to generate outputs, such as
new keys or other data.
You must first initialize and set up a key derivation context,
provided with a key and, optionally, other data. Then, use the key derivation
context to either read derived data to a buffer or send derived data directly
to a key slot.
See the documentation for the particular algorithm (such as HKDF or the
TLS 1.2 PRF) for information about which inputs to pass when, and when you can
obtain which outputs.
**Prerequisites to working with the key derivation APIs:**
* Initialize the library with a successful call to `psa_crypto_init()`.
* Use a key with the appropriate attributes set:
* Usage flags set for key derivation (`PSA_KEY_USAGE_DERIVE`)
* Key type set to `PSA_KEY_TYPE_DERIVE`.
* Algorithm set to a key derivation algorithm
(for example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)`).
**To derive a new AES-CTR 128-bit encryption key into a given key slot using HKDF
with a given key, salt and info:**
1. Set up the key derivation context using the `psa_key_derivation_setup()`
function, specifying the derivation algorithm `PSA_ALG_HKDF(PSA_ALG_SHA_256)`.
1. Provide an optional salt with `psa_key_derivation_input_bytes()`.
1. Provide info with `psa_key_derivation_input_bytes()`.
1. Provide a secret with `psa_key_derivation_input_key()`, referencing a key
that can be used for key derivation.
1. Set the key attributes desired for the new derived key. We'll set
the `PSA_KEY_USAGE_ENCRYPT` usage flag and the `PSA_ALG_CTR` algorithm for
this example.
1. Derive the key by calling `psa_key_derivation_output_key()`.
1. Clean up the key derivation context.
At this point, the derived key slot holds a new 128-bit AES-CTR encryption key
derived from the key, salt and info provided:
```C
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
static const unsigned char key[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b };
static const unsigned char salt[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
static const unsigned char info[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
0xf7, 0xf8, 0xf9 };
psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
psa_key_derivation_operation_t operation =
PSA_KEY_DERIVATION_OPERATION_INIT;
size_t derived_bits = 128;
size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
psa_key_id_t base_key;
psa_key_id_t derived_key;
printf("Derive a key (HKDF)...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Import a key for use in key derivation. If such a key has already been
* generated or imported, you can skip this part. */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE);
status = psa_import_key(&attributes, key, sizeof(key), &base_key);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Derive a key */
status = psa_key_derivation_setup(&operation, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin key derivation\n");
return;
}
status = psa_key_derivation_set_capacity(&operation, capacity);
if (status != PSA_SUCCESS) {
printf("Failed to set capacity\n");
return;
}
status = psa_key_derivation_input_bytes(&operation,
PSA_KEY_DERIVATION_INPUT_SALT,
salt, sizeof(salt));
if (status != PSA_SUCCESS) {
printf("Failed to input salt (extract)\n");
return;
}
status = psa_key_derivation_input_key(&operation,
PSA_KEY_DERIVATION_INPUT_SECRET,
base_key);
if (status != PSA_SUCCESS) {
printf("Failed to input key (extract)\n");
return;
}
status = psa_key_derivation_input_bytes(&operation,
PSA_KEY_DERIVATION_INPUT_INFO,
info, sizeof(info));
if (status != PSA_SUCCESS) {
printf("Failed to input info (expand)\n");
return;
}
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_CTR);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_key_derivation_output_key(&attributes, &operation,
&derived_key);
if (status != PSA_SUCCESS) {
printf("Failed to derive key\n");
return;
}
psa_reset_key_attributes(&attributes);
printf("Derived key\n");
/* Clean up key derivation operation */
psa_key_derivation_abort(&operation);
/* Destroy the keys */
psa_destroy_key(derived_key);
psa_destroy_key(base_key);
mbedtls_psa_crypto_free();
```
### Authenticating and encrypting or decrypting a message
The PSA Crypto API provides a simple way to authenticate and encrypt with
associated data (AEAD), supporting the `PSA_ALG_CCM` algorithm.
**Prerequisites to working with the AEAD cipher APIs:**
* Initialize the library with a successful call to `psa_crypto_init()`.
* The key attributes for the key used for derivation must have the
`PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT` usage flags.
This example shows how to authenticate and encrypt a message:
```C
psa_status_t status;
static const uint8_t key[] = {
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
static const uint8_t nonce[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B };
static const uint8_t additional_data[] = {
0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25,
0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
static const uint8_t input_data[] = {
0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
0xD2, 0xD7, 0xC2 };
uint8_t *output_data = NULL;
size_t output_size = 0;
size_t output_length = 0;
size_t tag_length = 16;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id;
printf("Authenticate encrypt...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
output_size = sizeof(input_data) + tag_length;
output_data = (uint8_t *)malloc(output_size);
if (!output_data) {
printf("Out of memory\n");
return;
}
/* Import a key */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, sizeof(key), &key_id);
psa_reset_key_attributes(&attributes);
/* Authenticate and encrypt */
status = psa_aead_encrypt(key_id, PSA_ALG_CCM,
nonce, sizeof(nonce),
additional_data, sizeof(additional_data),
input_data, sizeof(input_data),
output_data, output_size,
&output_length);
if (status != PSA_SUCCESS) {
printf("Failed to authenticate and encrypt\n");
return;
}
printf("Authenticated and encrypted\n");
/* Clean up */
free(output_data);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
```
This example shows how to authenticate and decrypt a message:
```C
psa_status_t status;
static const uint8_t key_data[] = {
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
static const uint8_t nonce[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B };
static const uint8_t additional_data[] = {
0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25,
0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70 };
static const uint8_t input_data[] = {
0x20, 0x30, 0xE0, 0x36, 0xED, 0x09, 0xA0, 0x45, 0xAF, 0x3C, 0xBA, 0xEE,
0x0F, 0xC8, 0x48, 0xAF, 0xCD, 0x89, 0x54, 0xF4, 0xF6, 0x3F, 0x28, 0x9A,
0xA1, 0xDD, 0xB2, 0xB8, 0x09, 0xCD, 0x7C, 0xE1, 0x46, 0xE9, 0x98 };
uint8_t *output_data = NULL;
size_t output_size = 0;
size_t output_length = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id;
printf("Authenticate decrypt...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
output_size = sizeof(input_data);
output_data = (uint8_t *)malloc(output_size);
if (!output_data) {
printf("Out of memory\n");
return;
}
/* Import a key */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key_data, sizeof(key_data), &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Authenticate and decrypt */
status = psa_aead_decrypt(key_id, PSA_ALG_CCM,
nonce, sizeof(nonce),
additional_data, sizeof(additional_data),
input_data, sizeof(input_data),
output_data, output_size,
&output_length);
if (status != PSA_SUCCESS) {
printf("Failed to authenticate and decrypt %ld\n", status);
return;
}
printf("Authenticated and decrypted\n");
/* Clean up */
free(output_data);
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
```
### Generating and exporting keys
The PSA Crypto API provides a simple way to generate a key or key pair.
**Prerequisites to using key generation and export APIs:**
* Initialize the library with a successful call to `psa_crypto_init()`.
**To generate an ECDSA key:**
1. Set the desired key attributes for key generation by calling
`psa_set_key_algorithm()` with the chosen ECDSA algorithm (such as
`PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)`). You only want to export the
public key, not the key pair (or private key); therefore, do not
set `PSA_KEY_USAGE_EXPORT`.
1. Generate a key by calling `psa_generate_key()`.
1. Export the generated public key by calling `psa_export_public_key()`:
```C
enum {
key_bits = 256,
};
psa_status_t status;
size_t exported_length = 0;
static uint8_t exported[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits)];
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id;
printf("Generate a key pair...\t");
fflush(stdout);
/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
printf("Failed to initialize PSA Crypto\n");
return;
}
/* Generate a key */
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_algorithm(&attributes,
PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
psa_set_key_type(&attributes,
PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attributes, key_bits);
status = psa_generate_key(&attributes, &key_id);
if (status != PSA_SUCCESS) {
printf("Failed to generate key\n");
return;
}
psa_reset_key_attributes(&attributes);
status = psa_export_public_key(key_id, exported, sizeof(exported),
&exported_length);
if (status != PSA_SUCCESS) {
printf("Failed to export public key %ld\n", status);
return;
}
printf("Exported a public key\n");
/* Destroy the key */
psa_destroy_key(key_id);
mbedtls_psa_crypto_free();
```
### More about the PSA Crypto API
For more information about the PSA Crypto API, please see the
[PSA Cryptography API Specification](https://arm-software.github.io/psa-api/crypto/).

20
docs/index.rst Normal file
View file

@ -0,0 +1,20 @@
.. Mbed TLS Versioned documentation master file, created by
sphinx-quickstart on Thu Feb 23 18:13:44 2023.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Mbed TLS API documentation
==========================
.. doxygenpage:: index
:project: mbedtls-versioned
.. toctree::
:caption: Contents
:maxdepth: 1
Home <self>
api/grouplist.rst
api/filelist.rst
api/structlist.rst
api/unionlist.rst

View file

@ -7,7 +7,7 @@ This document describes how to write drivers of cryptoprocessors such as acceler
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

View file

@ -5,7 +5,7 @@ Building Mbed TLS with PSA cryptoprocessor drivers
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 +19,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

View file

@ -321,6 +321,172 @@ TODO: key input and output for opaque drivers; deterministic key generation for
TODO
### Driver entry points for PAKE
A PAKE operation is divided into two stages: collecting inputs and computation. Core side is responsible for keeping inputs and core set-data functions do not have driver entry points. Collected inputs are available for drivers via get-data functions for `password`, `role` and `cipher_suite`.
### PAKE driver dispatch logic
The core decides whether to dispatch a PAKE operation to a driver based on the location of the provided password.
When all inputs are collected and `"psa_pake_output"` or `"psa_pake_input"` is called for the first time `"pake_setup"` driver entry point is invoked.
1. If the location of the `password` is the local storage
- if there is a transparent driver for the specified ciphersuite, the core calls that driver's `"pake_setup"` and subsequent entry points.
- otherwise, or on fallback, the core uses its built-in implementation.
2. If the location of the `password` is the location of a secure element
- the core calls the `"pake_setup"` entry point of the secure element driver and subsequent entry points.
### Summary of entry points for PAKE
A PAKE driver has the following entry points:
* `"pake_setup"` (mandatory): always the first entry point to be called. It is called when all inputs are collected and the computation stage starts.
* `"pake_output"` (mandatory): derive cryptographic material for the specified step and output it.
* `"pake_input"` (mandatory): provides cryptographic material in the format appropriate for the specified step.
* `"pake_get_implicit_key"` (mandatory): returns implicitly confirmed shared secret from a PAKE.
* `"pake_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 PAKE 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_pake_operation_t;
psa_status_t acme_pake_abort( acme_pake_operation_t *operation );
```
#### PAKE driver inputs
The core conveys the initial inputs for a PAKE operation via an opaque data structure of type `psa_crypto_driver_pake_inputs_t`.
```
typedef ... psa_crypto_driver_pake_inputs_t; // implementation-specific type
```
A driver receiving an argument that points to a `psa_crypto_driver_pake_inputs_t` can retrieve its contents by calling one of the get-data functions below.
```
psa_status_t psa_crypto_driver_pake_get_password_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *password_len);
psa_status_t psa_crypto_driver_pake_get_password_bytes(
    const psa_crypto_driver_pake_inputs_t *inputs,
    uint8_t *buffer, size_t buffer_size, size_t *buffer_length);
psa_status_t psa_crypto_driver_pake_get_password_key(
    const psa_crypto_driver_pake_inputs_t *inputs,
    uint8_t** p_key_buffer, size_t *key_buffer_size,
const psa_key_attributes_t *attributes);
psa_status_t psa_crypto_driver_pake_get_user_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *user_len);
psa_status_t psa_crypto_driver_pake_get_user(
const psa_crypto_driver_pake_inputs_t *inputs,
uint8_t *user_id, size_t user_id_size, size_t *user_id_len);
psa_status_t psa_crypto_driver_pake_get_peer_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *peer_len);
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_cipher_suite(
    const psa_crypto_driver_pake_inputs_t *inputs,
    psa_pake_cipher_suite_t *cipher_suite);
```
The get-data functions take the following parameters:
The first parameter `inputs` must be a pointer passed by the core to a PAKE driver setup entry point.
Next parameters are return buffers (must not be null pointers).
These functions can return the following statuses:
* `PSA_SUCCESS`: value has been successfully obtained
* `PSA_ERROR_BAD_STATE`: the inputs are not ready
* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_pake_get_password_bytes` and `psa_crypto_driver_pake_get_password_key` 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_pake_get_password_len` to obtain the required size.
#### PAKE driver setup
```
psa_status_t acme_pake_setup( acme_pake_operation_t *operation,
                              const psa_crypto_driver_pake_inputs_t *inputs );
```
* `operation` is a zero-initialized operation object.
* `inputs` is an opaque pointer to the [inputs](#pake-driver-inputs) for the PAKE operation.
The setup driver function should preserve the inputs using get-data functions.
The pointer output by `psa_crypto_driver_pake_get_password_key` is only valid until the "pake_setup" entry point returns. Opaque drivers must copy all relevant data from the key buffer during the "pake_setup" entry point and must not store the pointer itself.
#### PAKE driver output
```
psa_status_t acme_pake_output(acme_pake_operation_t *operation,
                              psa_crypto_driver_pake_step_t step,
                              uint8_t *output,
                              size_t output_size,
                              size_t *output_length);
```
* `operation` is an operation object.
* `step` computation step based on which driver should perform an action.
* `output` buffer where the output is to be written.
* `output_size` size of the output buffer in bytes.
* `output_length` the number of bytes of the returned output.
For `PSA_ALG_JPAKE` the following steps are available for output operation:
`step` can be one of the following values:
* `PSA_JPAKE_X1_STEP_KEY_SHARE`     Round 1: output our key share (for ephemeral private key X1)
* `PSA_JPAKE_X1_STEP_ZK_PUBLIC`     Round 1: output Schnorr NIZKP public key for the X1 key
* `PSA_JPAKE_X1_STEP_ZK_PROOF`      Round 1: output Schnorr NIZKP proof for the X1 key
* `PSA_JPAKE_X2_STEP_KEY_SHARE`     Round 1: output our key share (for ephemeral private key X2)
* `PSA_JPAKE_X2_STEP_ZK_PUBLIC`     Round 1: output Schnorr NIZKP public key for the X2 key
* `PSA_JPAKE_X2_STEP_ZK_PROOF`      Round 1: output Schnorr NIZKP proof for the X2 key
* `PSA_JPAKE_X2S_STEP_KEY_SHARE`    Round 2: output our X2S key
* `PSA_JPAKE_X2S_STEP_ZK_PUBLIC`    Round 2: output Schnorr NIZKP public key for the X2S key
* `PSA_JPAKE_X2S_STEP_ZK_PROOF`     Round 2: output Schnorr NIZKP proof for the X2S key
#### PAKE driver input
```
psa_status_t acme_pake_input(acme_pake_operation_t *operation,
                            psa_crypto_driver_pake_step_t step,
                             uint8_t *input,
                             size_t input_size);
```
* `operation` is an operation object.
* `step` computation step based on which driver should perform an action.
* `input` buffer containing the input.
* `input_length` length of the input in bytes.
For `PSA_ALG_JPAKE` the following steps are available for input operation:
* `PSA_JPAKE_X1_STEP_KEY_SHARE`     Round 1: input key share from peer (for ephemeral private key X1)
* `PSA_JPAKE_X1_STEP_ZK_PUBLIC`     Round 1: input Schnorr NIZKP public key for the X1 key
* `PSA_JPAKE_X1_STEP_ZK_PROOF`      Round 1: input Schnorr NIZKP proof for the X1 key
* `PSA_JPAKE_X2_STEP_KEY_SHARE`     Round 1: input key share from peer (for ephemeral private key X2)
* `PSA_JPAKE_X2_STEP_ZK_PUBLIC`     Round 1: input Schnorr NIZKP public key for the X2 key
* `PSA_JPAKE_X2_STEP_ZK_PROOF`      Round 1: input Schnorr NIZKP proof for the X2 key
* `PSA_JPAKE_X4S_STEP_KEY_SHARE`    Round 2: input X4S key from peer
* `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 not greater than `PSA_PAKE_INPUT_SIZE(alg, prim, step)` and
the driver can rely on that.
### PAKE driver get implicit key
```
psa_status_t acme_pake_get_implicit_key(
                            acme_pake_operation_t *operation,
                            uint8_t *output, size_t output_size,
size_t *output_length );
```
* `operation` The driver PAKE operation object to use.
* `output` Buffer where the implicit key is to be written.
* `output_size` Size of the output buffer in bytes.
* `output_length` On success, the number of bytes of the implicit key.
### Driver entry points for key management
The driver entry points for key management differ significantly between [transparent drivers](#key-management-with-transparent-drivers) and [opaque drivers](#key-management-with-opaque-drivers). This section describes common elements. Refer to the applicable section for each driver type for more information.

View file

@ -0,0 +1,175 @@
# 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_key` | `export_key` |
| `export_public_key` | `export_public_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.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. As such, it serves as a software accelerator. This section demonstrates the integration of `p256-m` as a transparent driver alongside Mbed TLS, serving as a guide for implementation.
The code for p256-m can be found in `3rdparty/p256-m/p256m`. In this demonstration, p256-m is built from source alongside Mbed TLS.
The driver prefix for p256-m is `P256`/`p256`. The driver macro is `MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED`. To build with and use p256-m, set the macro using `config.py`, then build as usual using make/cmake. From the root of the `mbedtls/` directory, run:
python3 scripts/config.py set MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
make
p256-m implements four entry points: `generate_key`, `key_agreement`, `sign_hash`, `verify_hash`. The `sign/verify_hash` entry points are used instead of `sign/verify_message` as messages must be hashed prior to any operation, and p256-m does not implement this. 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.c.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_P256M_EXAMPLE_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_P256M_EXAMPLE_DRIVER_ENABLED)
if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
attributes->core.bits == 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_P256M_EXAMPLE_DRIVER_ENABLED */
```
Following this, p256-m is now ready to use alongside Mbed TLS as a software accelerator. If `MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED` is set in the config, p256-m's implementations of key generation, ECDH, and ECDSA will be used where applicable.

2
docs/requirements.in Normal file
View file

@ -0,0 +1,2 @@
sphinx-rtd-theme
breathe

66
docs/requirements.txt Normal file
View file

@ -0,0 +1,66 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile requirements.in
#
alabaster==0.7.13
# via sphinx
babel==2.12.1
# via sphinx
breathe==4.35.0
# via -r requirements.in
certifi==2022.12.7
# via requests
charset-normalizer==3.1.0
# via requests
docutils==0.17.1
# via
# breathe
# sphinx
# sphinx-rtd-theme
idna==3.4
# via requests
imagesize==1.4.1
# via sphinx
importlib-metadata==6.0.0
# via sphinx
jinja2==3.1.2
# via sphinx
markupsafe==2.1.2
# via jinja2
packaging==23.0
# via sphinx
pygments==2.14.0
# via sphinx
requests==2.28.2
# via sphinx
snowballstemmer==2.2.0
# via sphinx
sphinx==4.5.0
# via
# breathe
# sphinx-rtd-theme
sphinx-rtd-theme==1.2.0
# via -r requirements.in
sphinxcontrib-applehelp==1.0.4
# via sphinx
sphinxcontrib-devhelp==1.0.2
# via sphinx
sphinxcontrib-htmlhelp==2.0.1
# via sphinx
sphinxcontrib-jquery==2.0.0
# via sphinx-rtd-theme
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
urllib3==1.26.15
# via requests
zipp==3.15.0
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# setuptools

View file

@ -1,22 +1,68 @@
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 parts of the code that
are specific to TLS 1.3; those parts always use PSA Crypto. The parts of the
TLS 1.3 code that are common with TLS 1.2, however, follow this option;
currently this is the record protection code, computation of the running
handshake hash, and X.509. You need to enable `MBEDTLS_USE_PSA_CRYPTO` if you
want TLS 1.3 to use PSA everywhere.
**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;
- X.509 certificate chain verification.
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
-------------------------
@ -60,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

View file

@ -22,7 +22,7 @@
*/
/**
* @mainpage mbed TLS v3.3.0 source code documentation
* @mainpage mbed TLS v3.4.0 source code documentation
*
* This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in

View file

@ -1,4 +1,4 @@
PROJECT_NAME = "mbed TLS v3.3.0"
PROJECT_NAME = "mbed TLS v3.4.0"
OUTPUT_DIRECTORY = ../apidoc/
FULL_PATH_NAMES = NO
OPTIMIZE_OUTPUT_FOR_C = YES
@ -18,6 +18,7 @@ HTML_OUTPUT = .
HTML_TIMESTAMP = YES
SEARCHENGINE = YES
GENERATE_LATEX = NO
GENERATE_XML = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
INCLUDE_PATH = ../include
@ -42,3 +43,12 @@ DOT_TRANSPARENT = YES
# \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
# This avoids writing redundant text and keeps Clang happy.
ALIASES += emptydescription=""
# Define away Mbed TLS macros that make parsing definitions difficult.
# MBEDTLS_DEPRECATED is not included in this list as it's important to
# display deprecated status in the documentation.
PREDEFINED = "MBEDTLS_CHECK_RETURN_CRITICAL=" \
"MBEDTLS_CHECK_RETURN_TYPICAL=" \
"MBEDTLS_CHECK_RETURN_OPTIONAL=" \
"MBEDTLS_PRINTF_ATTRIBUTE(a,b)=" \

View file

@ -35,6 +35,15 @@
(g) += ret; \
} while (0)
#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f) \
do \
{ \
if ((ret = (f)) < 0) \
goto cleanup; \
else \
(g) += ret; \
} while (0)
#ifdef __cplusplus
extern "C" {
#endif
@ -154,6 +163,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.

View file

@ -1,5 +1,5 @@
/**
* \file build_info.h
* \file mbedtls/build_info.h
*
* \brief Build-time configuration info
*
@ -37,7 +37,7 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 3
#define MBEDTLS_VERSION_MINOR 4
#define MBEDTLS_VERSION_PATCH 0
/**
@ -45,9 +45,9 @@
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x03030000
#define MBEDTLS_VERSION_STRING "3.3.0"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.3.0"
#define MBEDTLS_VERSION_NUMBER 0x03040000
#define MBEDTLS_VERSION_STRING "3.4.0"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.0"
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
@ -80,6 +80,38 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
/* 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_PKCS5_C)
#define MBEDTLS_MD_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_PKCS12_C) || \
defined(MBEDTLS_RSA_C)
#define MBEDTLS_MD_LIGHT
#endif
/* MBEDTLS_ECP_C now 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. */
#if defined(MBEDTLS_ECP_C)
#define MBEDTLS_ECP_LIGHT
#endif
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
* is defined as well to include all PSA code.
*/
@ -96,7 +128,31 @@
#define MBEDTLS_PK_PARSE_C
#endif
/* 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_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

View file

@ -66,14 +66,6 @@
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESCE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
@ -166,36 +158,40 @@
#endif
#if defined(MBEDTLS_PKCS5_C) && \
( !( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) || \
!defined(MBEDTLS_CIPHER_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"
/* Helpers for hash dependencies, will be undefined at the end of the file */
/* Do SHA-256, 384, 512 to cover Entropy and TLS. */
#if defined(MBEDTLS_SHA256_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256))
#define MBEDTLS_MD_HAVE_SHA256
#endif
#if defined(MBEDTLS_SHA384_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384))
#define MBEDTLS_MD_HAVE_SHA384
#endif
#if defined(MBEDTLS_SHA512_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512))
#define MBEDTLS_MD_HAVE_SHA512
#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_HAVE_SHA512) || defined(MBEDTLS_MD_HAVE_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_HAVE_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_HAVE_SHA256)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
@ -279,14 +275,61 @@
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
/* Helper for ECDSA dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if (defined(PSA_WANT_ALG_ECDSA) || \
defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECDSA_C)
#define MBEDTLS_PK_HAVE_ECDSA
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for JPAKE dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#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 */
/* Helper for ECDH dependencies, will be undefined at the end of the file */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_ECDH) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
#define MBEDTLS_PK_HAVE_ECDH
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECDH_C)
#define MBEDTLS_PK_HAVE_ECDH
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Helper for curve SECP256R1 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ECC_SECP_R1_256)
#define MBEDTLS_PK_HAVE_CURVE_SECP256R1
#endif
#else /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#define MBEDTLS_PK_HAVE_CURVE_SECP256R1
#endif
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
!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_PK_HAVE_ECDH) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@ -296,7 +339,7 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
!defined(MBEDTLS_PK_HAVE_ECDH)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
@ -307,13 +350,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
( !defined(MBEDTLS_PK_HAVE_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_ECDSA_C) || \
( !defined(MBEDTLS_PK_HAVE_ECDH) || \
!defined(MBEDTLS_PK_HAVE_ECDSA) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
@ -331,17 +375,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
( !defined(MBEDTLS_PK_HAVE_JPAKE) || \
!defined(MBEDTLS_PK_HAVE_CURVE_SECP256R1) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
/* 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_HAVE_SHA256)
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
@ -360,7 +401,15 @@
defined(MBEDTLS_SHA224_C) || \
defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_SHA384_C) || \
defined(MBEDTLS_SHA512_C) )
defined(MBEDTLS_SHA512_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && \
(defined(PSA_WANT_ALG_MD5) || \
defined(PSA_WANT_ALG_RIPEMD160) || \
defined(PSA_WANT_ALG_SHA_1) || \
defined(PSA_WANT_ALG_SHA_224) || \
defined(PSA_WANT_ALG_SHA_256) || \
defined(PSA_WANT_ALG_SHA_384) || \
defined(PSA_WANT_ALG_SHA_512))))
#error "MBEDTLS_MD_C defined, but not all prerequisites"
#endif
@ -400,7 +449,7 @@
#endif
#if defined(MBEDTLS_PK_C) && \
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C)
!defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_LIGHT)
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
@ -452,6 +501,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) )
@ -740,43 +799,29 @@
#error "MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY defined on non-Aarch64 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_C) && \
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_ECDSA_C) || defined(MBEDTLS_PKCS1_V21) ) )
#if !( defined(PSA_WANT_ALG_ECDH) && defined(MBEDTLS_X509_CRT_PARSE_C) && \
( defined(MBEDTLS_PK_HAVE_ECDSA) || 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) )
#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites"
#endif
#endif
@ -831,11 +876,24 @@
#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)
#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_HAVE_SHA256) || defined(MBEDTLS_MD_HAVE_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
@ -1007,6 +1065,10 @@
#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && ( !defined(MBEDTLS_SSL_PROTO_TLS1_3) )
#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) )
#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites"
#endif
@ -1066,6 +1128,15 @@
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
#endif
/* Undefine helper symbols */
#undef MBEDTLS_PK_HAVE_ECDSA
#undef MBEDTLS_PK_HAVE_JPAKE
#undef MBEDTLS_PK_HAVE_ECDH
#undef MBEDTLS_MD_HAVE_SHA256
#undef MBEDTLS_MD_HAVE_SHA384
#undef MBEDTLS_MD_HAVE_SHA512
#undef MBEDTLS_PK_HAVE_CURVE_SECP256R1
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the

View file

@ -77,6 +77,40 @@ extern "C" {
#endif
/****************************************************************/
/* 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
/****************************************************************/
/* Require built-in implementations based on PSA requirements */
@ -147,12 +181,14 @@ extern "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)

View file

@ -45,6 +45,7 @@
#include "mbedtls/build_info.h"
#include "mbedtls/aes.h"
#include "entropy.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
@ -94,17 +95,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 +110,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)

View file

@ -131,6 +131,10 @@
#endif \
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
#if !defined(MBEDTLS_PRINTF_MS_TIME)
#define MBEDTLS_PRINTF_MS_TIME PRId64
#endif /* MBEDTLS_PRINTF_MS_TIME */
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -288,6 +288,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,6 +323,7 @@ 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
@ -348,8 +351,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.

View file

@ -54,6 +54,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)

View file

@ -312,7 +312,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 +343,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)

View file

@ -27,13 +27,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 +75,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
@ -120,11 +118,7 @@ typedef struct mbedtls_entropy_context {
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
mbedtls_md_context_t MBEDTLS_PRIVATE(accumulator);
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)

View file

@ -1,215 +0,0 @@
/**
* Macros to express dependencies for code and tests that may use either the
* legacy API or PSA in various builds. This whole header file is currently
* for internal use only and both the header file and the macros it defines
* may change or be removed without notice.
*/
/*
* 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.
*/
/*
* Note: applications that are targeting a specific configuration do not need
* to use these macros; instead they should directly use the functions they
* know are available in their configuration.
*
* Note: code that is purely based on PSA Crypto (psa_xxx() functions)
* does not need to use these macros; instead it should use the relevant
* PSA_WANT_xxx macros.
*
* Note: code that is purely based on the legacy crypto APIs (mbedtls_xxx())
* does not need to use these macros; instead it should use the relevant
* MBEDTLS_xxx macros.
*
* These macros are for code that wants to use <crypto feature> and will do so
* using <legacy API> or PSA depending on <condition>, where:
* - <crypto feature> will generally be an algorithm (SHA-256, ECDH) but may
* also be a key type (AES, RSA, EC) or domain parameters (elliptic curve);
* - <legacy API> will be either:
* - low-level module API (aes.h, sha256.h), or
* - an abstraction layer (md.h, cipher.h);
* - <condition> will be either:
* - depending on what's available in the build:
* legacy API used if available, PSA otherwise
* (this is done to ensure backwards compatibility); or
* - depending on whether MBEDTLS_USE_PSA_CRYPTO is defined.
*
* Examples:
* - TLS 1.2 will compute hashes using either mbedtls_md_xxx() (and
* mbedtls_sha256_xxx()) or psa_aead_xxx() depending on whether
* MBEDTLS_USE_PSA_CRYPTO is defined;
* - RSA PKCS#1 v2.1 will compute hashes (for padding) using either
* `mbedtls_md()` if it's available, or `psa_hash_compute()` otherwise;
* - PEM decoding of PEM-encrypted keys will compute MD5 hashes using either
* `mbedtls_md5_xxx()` if it's available, or `psa_hash_xxx()` otherwise.
*
* Note: the macros are essential to express test dependencies. Inside code,
* we could instead just use the equivalent pre-processor condition, but
* that's not possible in test dependencies where we need a single macro.
* Hopefully, using these macros in code will also help with consistency.
*
* The naming scheme for these macros is:
* MBEDTLS_HAS_feature_VIA_legacy_OR_PSA(_condition)
* where:
* - feature is expressed the same way as in PSA_WANT_xxx macros, for example:
* KEY_TYPE_AES, ALG_SHA_256, ECC_SECP_R1_256;
* - legacy is either LOWLEVEL or the name of the layer: MD, CIPHER;
* - condition is omitted if it's based on availability, else it's
* BASED_ON_USE_PSA.
*
* Coming back to the examples above:
* - TLS 1.2 will determine if it can use SHA-256 using
* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
* for the purposes of negotiation, and in test dependencies;
* - RSA PKCS#1 v2.1 tests that used SHA-256 will depend on
* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA
* - PEM decoding code and its associated tests will depend on
* MBEDTLS_HAS_ALG_MD5_VIA_LOWLEVEL_OR_PSA
*
* Note: every time it's possible to use, say SHA-256, via the MD API, then
* it's also possible to use it via the low-level API. So, code that wants to
* use SHA-256 via both APIs only needs to depend on the MD macro. Also, it
* just so happens that all the code choosing which API to use based on
* MBEDTLS_USE_PSA_CRYPTO (X.509, TLS 1.2/shared), always uses the abstraction
* layer (sometimes in addition to the low-level API), so we don't need the
* MBEDTLS_HAS_feature_VIA_LOWLEVEL_OR_PSA_BASED_ON_USE_PSA macros.
* (PK, while obeying MBEDTLS_USE_PSA_CRYPTO, doesn't compute hashes itself,
* even less makes use of ciphers.)
*
* Note: the macros MBEDTLS_HAS_feature_VIA_LOWLEVEL_OR_PSA are the minimal
* condition for being able to use <feature> at all. As such, they should be
* used for guarding data about <feature>, such as OIDs or size. For example,
* OID values related to SHA-256 are only useful when SHA-256 can be used at
* least in some way.
*/
#ifndef MBEDTLS_OR_PSA_HELPERS_H
#define MBEDTLS_OR_PSA_HELPERS_H
#include "mbedtls/build_info.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "psa/crypto.h"
#endif /* MBEDTLS_PSA_CRYPTO_C */
/*
* Hashes
*/
/* Hashes using low-level or PSA based on availability */
#if defined(MBEDTLS_MD5_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_MD5))
#define MBEDTLS_HAS_ALG_MD5_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_RIPEMD160_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_RIPEMD160))
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_SHA1_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_1))
#define MBEDTLS_HAS_ALG_SHA_1_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_SHA224_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_224))
#define MBEDTLS_HAS_ALG_SHA_224_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_SHA256_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256))
#define MBEDTLS_HAS_ALG_SHA_256_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_SHA384_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384))
#define MBEDTLS_HAS_ALG_SHA_384_VIA_LOWLEVEL_OR_PSA
#endif
#if defined(MBEDTLS_SHA512_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512))
#define MBEDTLS_HAS_ALG_SHA_512_VIA_LOWLEVEL_OR_PSA
#endif
/* Hashes using MD or PSA based on availability */
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_MD5_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_MD5))
#define MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_RIPEMD160_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_RIPEMD160))
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA1_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_1))
#define MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA224_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_224))
#define MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256))
#define MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA384_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384))
#define MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA
#endif
#if (defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA512_C)) || \
(!defined(MBEDTLS_MD_C) && \
defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512))
#define MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA
#endif
/* Hashes using MD or PSA based on MBEDTLS_USE_PSA_CRYPTO */
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_MD5_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_MD5))
#define MBEDTLS_HAS_ALG_MD5_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_RIPEMD160_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_RIPEMD160))
#define MBEDTLS_HAS_ALG_RIPEMD160_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA1_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_1))
#define MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA224_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_224))
#define MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_256))
#define MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA384_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_384))
#define MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA512_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_SHA_512))
#define MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA
#endif
#endif /* MBEDTLS_OR_PSA_HELPERS_H */

View file

@ -55,7 +55,8 @@
* library/padlock.h
*
* Required by:
* MBEDTLS_AESNI_C
* MBEDTLS_AESCE_C
* MBEDTLS_AESNI_C (on some platforms)
* MBEDTLS_PADLOCK_C
*
* Comment to disable the use of assembly code.
@ -237,6 +238,7 @@
//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
//#define MBEDTLS_PLATFORM_NV_SEED_ALT
//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
//#define MBEDTLS_PLATFORM_MS_TIME_ALT
/**
* \def MBEDTLS_DEPRECATED_WARNING
@ -705,7 +707,7 @@
* - Changes the behaviour of TLS 1.2 clients (not servers) when using the
* ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC
* computations restartable:
* - ECDH operations from the key exchange, only for Short Weierstass
* - ECDH operations from the key exchange, only for Short Weierstrass
* curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled.
* - verification of the server's key exchange signature;
* - verification of the server's certificate chain;
@ -800,7 +802,7 @@
*
* Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C
* Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH)
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -898,7 +900,9 @@
*
* Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
* Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH)
* MBEDTLS_RSA_C
* MBEDTLS_PKCS1_V15
* MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
@ -921,7 +925,9 @@
*
* Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
* Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH)
* MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA)
* MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -943,7 +949,9 @@
*
* Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C
* Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH)
* MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA)
* MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -965,7 +973,9 @@
*
* Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C
* Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH)
* MBEDTLS_RSA_C
* MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -991,10 +1001,14 @@
* Thread v1.0.0 specification; incompatible changes to the specification
* might still happen. For this reason, this is disabled by default.
*
* Requires: MBEDTLS_ECJPAKE_C
* SHA-256 (via MD if present, or via PSA, see MBEDTLS_ECJPAKE_C)
* Requires: MBEDTLS_ECJPAKE_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_JPAKE)
* SHA-256 (via MBEDTLS_SHA256_C or a PSA driver)
* MBEDTLS_ECP_DP_SECP256R1_ENABLED
*
* \warning If SHA-256 is provided only by a PSA driver, you must call
* psa_crypto_init() before the first hanshake (even if
* MBEDTLS_USE_PSA_CRYPTO is disabled).
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
* MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
@ -1175,15 +1189,10 @@
*
* Enable support for PKCS#1 v2.1 encoding.
*
* Requires: MBEDTLS_RSA_C and (MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C).
* Requires: MBEDTLS_RSA_C
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS#1 v2.1 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
* \warning If using a hash that is only provided by PSA drivers, you must
* call psa_crypto_init() before doing any PKCS#1 v2.1 operation.
*
* This enables support for RSAES-OAEP and RSASSA-PSS operations.
*/
@ -1221,18 +1230,6 @@
*/
//#define MBEDTLS_PSA_CRYPTO_CLIENT
/** \def MBEDTLS_PSA_CRYPTO_DRIVERS
*
* Enable support for the experimental PSA crypto driver interface.
*
* Requires: MBEDTLS_PSA_CRYPTO_C
*
* \warning This interface is experimental. We intend to maintain backward
* compatibility with application code that relies on drivers,
* but the driver interfaces may change without notice.
*/
//#define MBEDTLS_PSA_CRYPTO_DRIVERS
/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
*
* Make the PSA Crypto module use an external random generator provided
@ -1547,19 +1544,34 @@
*/
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
/**
* \def MBEDTLS_SSL_RECORD_SIZE_LIMIT
*
* Enable support for RFC 8449 record_size_limit extension in SSL (TLS 1.3 only).
*
* \warning This extension is currently in development and must NOT be used except
* for testing purposes.
*
* Requires: MBEDTLS_SSL_PROTO_TLS1_3
*
* Uncomment this macro to enable support for the record_size_limit extension
*/
//#define MBEDTLS_SSL_RECORD_SIZE_LIMIT
/**
* \def MBEDTLS_SSL_PROTO_TLS1_2
*
* Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
*
* Requires: Without MBEDTLS_USE_PSA_CRYPTO: MBEDTLS_MD_C and
* (MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C)
* (MBEDTLS_SHA256_C or MBEDTLS_SHA384_C or
* SHA-256 or SHA-512 provided by a PSA driver)
* With MBEDTLS_USE_PSA_CRYPTO:
* PSA_WANT_ALG_SHA_1 or PSA_WANT_ALG_SHA_256 or
* PSA_WANT_ALG_SHA_512
* PSA_WANT_ALG_SHA_256 or PSA_WANT_ALG_SHA_384
*
* \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call
* psa_crypto_init() before doing any TLS operations.
* \warning If building with MBEDTLS_USE_PSA_CRYPTO, or if the hash(es) used
* are only provided by PSA drivers, you must call psa_crypto_init() before
* doing any TLS operations.
*
* Comment this macro to disable support for TLS 1.2 / DTLS 1.2
*/
@ -1578,11 +1590,14 @@
* Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
* Requires: MBEDTLS_PSA_CRYPTO_C
*
* Note: even though TLS 1.3 depends on PSA Crypto, and uses it unconditionally
* for most operations, if you want it to only use PSA for all crypto
* operations, you need to also enable MBEDTLS_USE_PSA_CRYPTO; otherwise X.509
* operations, and functions that are common with TLS 1.2 (record protection,
* running handshake hash) will still use non-PSA crypto.
* \note TLS 1.3 uses PSA crypto for cryptographic operations that are
* directly performed by TLS 1.3 code. As a consequence, you must
* call psa_crypto_init() before the first TLS 1.3 handshake.
*
* \note Cryptographic operations performed indirectly via another module
* (X.509, PK) or by code shared with TLS 1.2 (record protection,
* running handshake hash) only use PSA crypto if
* #MBEDTLS_USE_PSA_CRYPTO is enabled.
*
* Uncomment this macro to enable the support for TLS 1.3.
*/
@ -1627,7 +1642,10 @@
*
* Enable TLS 1.3 ephemeral key exchange mode.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C, MBEDTLS_ECDSA_C or
* Requires: PSA_WANT_ALG_ECDH
* MBEDTLS_X509_CRT_PARSE_C
* and at least one of:
* MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA)
* MBEDTLS_PKCS1_V21
*
* Comment to disable support for the ephemeral key exchange mode in TLS 1.3.
@ -1642,7 +1660,7 @@
*
* Enable TLS 1.3 PSK ephemeral key exchange mode.
*
* Requires: MBEDTLS_ECDH_C
* Requires: PSA_WANT_ALG_ECDH
*
* Comment to disable support for the PSK ephemeral key exchange mode in
* TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not
@ -1651,45 +1669,6 @@
*/
#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
/**
* \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
*
* Maximum time difference in milliseconds tolerated between the age of a
* ticket from the server and client point of view.
* From the client point of view, the age of a ticket is the time difference
* between the time when the client proposes to the server to use the ticket
* (time of writing of the Pre-Shared Key Extension including the ticket) and
* the time the client received the ticket from the server.
* From the server point of view, the age of a ticket is the time difference
* between the time when the server receives a proposition from the client
* to use the ticket and the time when the ticket was created by the server.
* The server age is expected to be always greater than the client one and
* MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
* maximum difference tolerated for the server to accept the ticket.
* This is not used in TLS 1.2.
*
*/
#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000
/**
* \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH
*
* Size in bytes of a ticket nonce. This is not used in TLS 1.2.
*
* This must be less than 256.
*/
#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32
/**
* \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS
*
* Default number of NewSessionTicket messages to be sent by a TLS 1.3 server
* after handshake completion. This is not used in TLS 1.2 and relevant only if
* the MBEDTLS_SSL_SESSION_TICKETS option is enabled.
*
*/
#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1
/**
* \def MBEDTLS_SSL_EARLY_DATA
*
@ -1943,19 +1922,26 @@
/**
* \def MBEDTLS_USE_PSA_CRYPTO
*
* Make the X.509 and TLS library use PSA for cryptographic operations, and
* enable new APIs for using keys handled by PSA Crypto.
* Make the X.509 and TLS libraries use PSA for cryptographic operations as
* much as possible, and enable new APIs for using keys handled by PSA Crypto.
*
* \note Development of this option is currently in progress, and parts of Mbed
* TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts
* will still continue to work as usual, so enabling this option should not
* break backwards compatibility.
*
* \note See docs/use-psa-crypto.md for a complete description of what this
* option currently does, and of parts that are not affected by it so far.
*
* \warning If you enable this option, you need to call `psa_crypto_init()`
* before calling any function from the SSL/TLS, X.509 or PK modules.
* before calling any function from the SSL/TLS, X.509 or PK modules, except
* for the various mbedtls_xxx_init() functions which can be called at any time.
*
* \note An important and desirable effect of this option is that it allows
* PK, X.509 and TLS to take advantage of PSA drivers. 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.
*
* \note See docs/use-psa-crypto.md for a complete description this option.
*
* Requires: MBEDTLS_PSA_CRYPTO_C.
*
@ -2054,42 +2040,53 @@
/**
* \def MBEDTLS_AESNI_C
*
* Enable AES-NI support on x86-64.
* Enable AES-NI support on x86-64 or x86-32.
*
* \note AESNI is only supported with certain compilers and target options:
* - Visual Studio 2013: supported.
* - GCC, x86-64, target not explicitly supporting AESNI:
* requires MBEDTLS_HAVE_ASM.
* - GCC, x86-32, target not explicitly supporting AESNI:
* not supported.
* - GCC, x86-64 or x86-32, target supporting AESNI: supported.
* For this assembly-less implementation, you must currently compile
* `library/aesni.c` and `library/aes.c` with machine options to enable
* SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or
* `clang -maes -mpclmul`.
* - Non-x86 targets: this option is silently ignored.
* - Other compilers: this option is silently ignored.
*
* \note
* Above, "GCC" includes compatible compilers such as Clang.
* The limitations on target support are likely to be relaxed in the future.
*
* Module: library/aesni.c
* Caller: library/aes.c
*
* Requires: MBEDTLS_HAVE_ASM
* Requires: MBEDTLS_HAVE_ASM (on some platforms, see note)
*
* This modules adds support for the AES-NI instructions on x86-64
* This modules adds support for the AES-NI instructions on x86.
*/
#define MBEDTLS_AESNI_C
/**
* \def MBEDTLS_AESCE_C
*
* Enable AES crypto extension support on Arm64.
* Enable AES cryptographic extension support on 64-bit Arm.
*
* Module: library/aesce.c
* Caller: library/aes.c
*
* Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C
* Requires: MBEDTLS_AES_C
*
* \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum
* of \c -march=armv8-a+crypto .
* \warning Runtime detection only works on Linux. For non-Linux operating
* system, Armv8-A Cryptographic Extensions must be supported by
* the CPU when this option is enabled.
*
* \warning If the target architecture is set to something that includes the
* SHA3 feature (e.g. `-march=armv8.2-a+sha3`), for example because
* `MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT` is desired, compilers
* generate code for `MBEDTLS_AESCE_C` that includes instructions
* only present with the (optional) SHA3 feature. This will lead to an
* undefined instruction exception if the code is run on a CPU without
* that feature.
* \note Minimum compiler versions for this feature are Clang 4.0,
* GCC 6.0 or MSVC 2019 version 16.11.2.
*
* \warning Runtime detection only works on linux. For non-linux operation
* system, crypto extension MUST be supported by CPU.
*
* This module adds support for the AES crypto instructions on Arm64
* This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems.
*/
#define MBEDTLS_AESCE_C
@ -2535,13 +2532,8 @@
*
* Requires: MBEDTLS_ECP_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any EC J-PAKE operations.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
* \warning If using a hash that is only provided by PSA drivers, you must
* call psa_crypto_init() before doing any EC J-PAKE operations.
*/
#define MBEDTLS_ECJPAKE_C
@ -2671,11 +2663,12 @@
/**
* \def MBEDTLS_MD_C
*
* Enable the generic message digest layer.
* Enable the generic layer for message digest (hashing) and HMAC.
*
* Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C,
* MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C,
* MBEDTLS_SHA512_C.
* MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least
* one hash.
* Module: library/md.c
* Caller: library/constant_time.c
* library/ecdsa.c
@ -2806,6 +2799,10 @@
* library/x509_csr.c
*
* Requires: MBEDTLS_BASE64_C
* optionally MBEDTLS_MD5_C, or PSA Crypto with MD5 (see below)
*
* \warning When parsing password-protected files, if MD5 is provided only by
* a PSA driver, you must call psa_crypto_init() before the first file.
*
* This modules adds support for decoding / parsing PEM files.
*/
@ -2881,15 +2878,11 @@
*
* Module: library/pkcs5.c
*
* Requires: MBEDTLS_CIPHER_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C.
* Requires: MBEDTLS_CIPHER_C
* Auto-enables: MBEDTLS_MD_C
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS5 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
* \warning If using a hash that is only provided by PSA drivers, you must
* call psa_crypto_init() before doing any PKCS5 operations.
*
* This module adds support for the PKCS#5 functions.
*/
@ -2898,11 +2891,7 @@
/**
* \def MBEDTLS_PKCS7_C
*
* This feature is a work in progress and not ready for production. Testing and
* validation is incomplete, and handling of malformed inputs may not be robust.
* The API may change.
*
* Enable PKCS7 core for using PKCS7 formatted signatures.
* Enable PKCS #7 core for using PKCS #7-formatted signatures.
* RFC Link - https://tools.ietf.org/html/rfc2315
*
* Module: library/pkcs7.c
@ -2911,9 +2900,9 @@
* MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C,
* MBEDTLS_BIGNUM_C, MBEDTLS_MD_C
*
* This module is required for the PKCS7 parsing modules.
* This module is required for the PKCS #7 parsing modules.
*/
//#define MBEDTLS_PKCS7_C
#define MBEDTLS_PKCS7_C
/**
* \def MBEDTLS_PKCS12_C
@ -2927,13 +2916,8 @@
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C and either
* MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C.
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS12 operation.
*
* \warning When building with MBEDTLS_MD_C, all hashes used with this
* need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
* etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
* this module in builds where MBEDTLS_MD_C is disabled.
* \warning If using a hash that is only provided by PSA drivers, you must
* call psa_crypto_init() before doing any PKCS12 operations.
*
* This module enables PKCS#12 functions.
*/
@ -2990,8 +2974,8 @@
* Enable dynamic secure element support in the Platform Security Architecture
* cryptography API.
*
* \deprecated This feature is deprecated. Please switch to the driver
* interface enabled by #MBEDTLS_PSA_CRYPTO_DRIVERS.
* \deprecated This feature is deprecated. Please switch to the PSA driver
* interface.
*
* Module: library/psa_crypto_se.c
*
@ -3695,6 +3679,8 @@
//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
//#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t /**< Default milliseconds time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled. It must be signed, and at least 64 bits. If it is changed from the default, MBEDTLS_PRINTF_MS_TIME must be updated to match.*/
//#define MBEDTLS_PRINTF_MS_TIME PRId64 /**< Default fmt for printf. That's avoid compiler warning if mbedtls_ms_time_t is redefined */
/** \def MBEDTLS_CHECK_RETURN
*
@ -3837,7 +3823,7 @@
*/
//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
/**
@ -3854,6 +3840,45 @@
*/
//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
/**
* \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
*
* Maximum time difference in milliseconds tolerated between the age of a
* ticket from the server and client point of view.
* From the client point of view, the age of a ticket is the time difference
* between the time when the client proposes to the server to use the ticket
* (time of writing of the Pre-Shared Key Extension including the ticket) and
* the time the client received the ticket from the server.
* From the server point of view, the age of a ticket is the time difference
* between the time when the server receives a proposition from the client
* to use the ticket and the time when the ticket was created by the server.
* The server age is expected to be always greater than the client one and
* MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
* maximum difference tolerated for the server to accept the ticket.
* This is not used in TLS 1.2.
*
*/
#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000
/**
* \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH
*
* Size in bytes of a ticket nonce. This is not used in TLS 1.2.
*
* This must be less than 256.
*/
#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32
/**
* \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS
*
* Default number of NewSessionTicket messages to be sent by a TLS 1.3 server
* after handshake completion. This is not used in TLS 1.2 and relevant only if
* the MBEDTLS_SSL_SESSION_TICKETS option is enabled.
*
*/
#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1
/* X509 options */
//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */
//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
@ -3906,4 +3931,18 @@
*/
//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
/**
* Uncomment to enable p256-m, which implements ECC key generation, ECDH,
* and ECDSA for SECP256R1 curves. This driver is used as an example to
* document how a third-party driver or software accelerator can be integrated
* to work alongside Mbed TLS.
*
* \warning p256-m has only been included to serve as a sample implementation
* of how a driver/accelerator can be integrated alongside Mbed TLS. It is not
* intended for use in production. p256-m files in Mbed TLS are not updated
* regularly, so they may not contain upstream fixes/improvements.
* DO NOT ENABLE/USE THIS MACRO IN PRODUCTION BUILDS!
*/
//#define MBEDTLS_P256M_EXAMPLE_DRIVER_ENABLED
/** \} name SECTION: Module configuration options */

View file

@ -1,7 +1,8 @@
/**
* \file md.h
*
* \brief This file contains the generic message-digest wrapper.
* \brief This file contains the generic functions for message-digest
* (hashing) and HMAC.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
@ -31,6 +32,93 @@
#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. */
@ -67,21 +155,22 @@ typedef enum {
MBEDTLS_MD_SHA3_512, /**< The SHA3-512 message digest. */
} mbedtls_md_type_t;
#if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA3_C)
#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_SHA3_C)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#elif defined(MBEDTLS_SHA384_C)
#elif defined(MBEDTLS_MD_CAN_SHA384)
#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */
#elif defined(MBEDTLS_SHA256_C)
#elif defined(MBEDTLS_MD_CAN_SHA256)
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */
#elif defined(MBEDTLS_SHA224_C)
#elif defined(MBEDTLS_MD_CAN_SHA224)
#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 */
#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160
or smaller (MD5 and earlier) */
#endif
#if defined(MBEDTLS_SHA3_C)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */
#elif defined(MBEDTLS_SHA512_C)
#elif defined(MBEDTLS_MD_CAN_SHA512)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
#else
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
@ -99,6 +188,16 @@ typedef enum {
/* Defined internally in library/md_wrap.h. */
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* Used internally to indicate whether a context uses legacy or PSA.
*
* Internal use only.
*/
typedef enum {
MBEDTLS_MD_ENGINE_LEGACY = 0,
MBEDTLS_MD_ENGINE_PSA,
} mbedtls_md_engine_t;
/**
* The generic message-digest context.
*/
@ -106,37 +205,20 @@ typedef struct mbedtls_md_context_t {
/** Information about the associated message digest. */
const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info);
/** The digest-specific context. */
#if defined(MBEDTLS_MD_SOME_PSA)
/** Are hash operations dispatched to PSA or legacy? */
mbedtls_md_engine_t MBEDTLS_PRIVATE(engine);
#endif
/** The digest-specific context (legacy) or the PSA operation. */
void *MBEDTLS_PRIVATE(md_ctx);
#if defined(MBEDTLS_MD_C)
/** The HMAC part of the context. */
void *MBEDTLS_PRIVATE(hmac_ctx);
#endif
} mbedtls_md_context_t;
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
* \note The list starts with the strongest available hashes.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const int *mbedtls_md_list(void);
/**
* \brief This function returns the message-digest information
* associated with the given digest name.
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
/**
* \brief This function returns the message-digest information
* associated with the given digest type.
@ -148,19 +230,6 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type);
/**
* \brief This function returns the message-digest information
* from the given context.
*
* \param ctx The context from which to extract the information.
* This must be initialized (or \c NULL).
*
* \return The message-digest information associated with \p ctx.
* \return \c NULL if \p ctx is \c NULL.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
const mbedtls_md_context_t *ctx);
/**
* \brief This function initializes a message-digest context without
* binding it to a particular message-digest algorithm.
@ -227,6 +296,10 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
* \return #MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE if both contexts are
* not using the same engine. This can be avoided by moving
* the call to psa_crypto_init() before the first call to
* mbedtls_md_setup().
*/
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_clone(mbedtls_md_context_t *dst,
@ -254,17 +327,6 @@ unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info);
*/
mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info);
/**
* \brief This function extracts the message-digest name from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The name of the message digest.
*/
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
/**
* \brief This function starts a message-digest computation.
*
@ -343,6 +405,54 @@ MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output);
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
* \note The list starts with the strongest available hashes.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const int *mbedtls_md_list(void);
/**
* \brief This function returns the message-digest information
* associated with the given digest name.
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
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.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The name of the message digest.
*/
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
/**
* \brief This function returns the message-digest information
* from the given context.
*
* \param ctx The context from which to extract the information.
* This must be initialized (or \c NULL).
*
* \return The message-digest information associated with \p ctx.
* \return \c NULL if \p ctx is \c NULL.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
const mbedtls_md_context_t *ctx);
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function calculates the message-digest checksum
@ -477,10 +587,6 @@ int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, const unsigned char *key,
const unsigned char *input, size_t ilen,
unsigned char *output);
/* Internal use */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_process(mbedtls_md_context_t *ctx, const unsigned char *data);
#ifdef __cplusplus
}
#endif

View file

@ -90,6 +90,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
@ -437,6 +440,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
@ -509,7 +521,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_ECP_LIGHT)
/**
* \brief Translate NamedCurve OID into an EC group identifier
*
@ -531,7 +543,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_ECP_LIGHT */
/**
* \brief Translate SignatureAlgorithm OID into md_type and pk_type

View file

@ -197,6 +197,11 @@ typedef struct mbedtls_pk_rsassa_pss_options {
#define MBEDTLS_PK_CAN_ECDSA_SOME
#endif
#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \
(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C))
#define MBEDTLS_PK_CAN_ECDH
#endif
/**
* \brief Types for interfacing with the debug module
*/
@ -766,7 +771,7 @@ static inline mbedtls_rsa_context *mbedtls_pk_rsa(const mbedtls_pk_context pk)
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
#if defined(MBEDTLS_ECP_LIGHT)
/**
* Quick access to an EC context inside a PK context.
*
@ -789,13 +794,17 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk)
return NULL;
}
}
#endif /* MBEDTLS_ECP_C */
#endif /* MBEDTLS_ECP_LIGHT */
#if defined(MBEDTLS_PK_PARSE_C)
/** \ingroup pk_module */
/**
* \brief Parse a private key in PEM or DER format
*
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
* subsystem must have been initialized by calling
* psa_crypto_init() before calling this function.
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
@ -832,6 +841,10 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
/**
* \brief Parse a public key in PEM or DER format
*
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
* subsystem must have been initialized by calling
* psa_crypto_init() before calling this function.
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
@ -861,6 +874,10 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
/**
* \brief Load and parse a private key
*
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
* subsystem must have been initialized by calling
* psa_crypto_init() before calling this function.
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param path filename to read the private key from

View file

@ -1,7 +1,7 @@
/**
* \file pkcs7.h
*
* \brief PKCS7 generic defines and structures
* \brief PKCS #7 generic defines and structures
* https://tools.ietf.org/html/rfc2315
*/
/*
@ -22,27 +22,22 @@
*/
/**
* This feature is a work in progress and not ready for production. The API may
* change. Furthermore, please note that the implementation has only been
* validated with well-formed inputs, not yet with untrusted inputs (which is
* almost always the case in practice).
*
* Note: For the time being, this implementation of the PKCS7 cryptographic
* Note: For the time being, this implementation of the PKCS #7 cryptographic
* message syntax is a partial implementation of RFC 2315.
* Differences include:
* - The RFC specifies 6 different content types. The only type currently
* supported in Mbed TLS is the signed data content type.
* - The only supported PKCS7 Signed Data syntax version is version 1
* supported in Mbed TLS is the signed-data content type.
* - The only supported PKCS #7 Signed Data syntax version is version 1
* - The RFC specifies support for BER. This implementation is limited to
* DER only.
* - The RFC specifies that multiple digest algorithms can be specified
* in the Signed Data type. Only one digest algorithm is supported in Mbed TLS.
* - The RFC specifies the Signed Data type can contain multiple X509 or PKCS6
* - The RFC specifies the Signed Data type can contain multiple X.509 or PKCS #6 extended
* certificates. In Mbed TLS, this list can only contain 0 or 1 certificates
* and they must be in X509 format.
* and they must be in X.509 format.
* - The RFC specifies the Signed Data type can contain
* certificate-revocation lists (crls). This implementation has no support
* for crls so it is assumed to be an empty list.
* certificate-revocation lists (CRLs). This implementation has no support
* for CRLs so it is assumed to be an empty list.
* - The RFC allows for SignerInfo structure to optionally contain
* unauthenticatedAttributes and authenticatedAttributes. In Mbed TLS it is
* assumed these fields are empty.
@ -62,13 +57,13 @@
#include "mbedtls/x509_crt.h"
/**
* \name PKCS7 Module Error codes
* \name PKCS #7 Module Error codes
* \{
*/
#define MBEDTLS_ERR_PKCS7_INVALID_FORMAT -0x5300 /**< The format is invalid, e.g. different type expected. */
#define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE -0x5380 /**< Unavailable feature, e.g. anything other than signed data. */
#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS7 version element is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS7 content info is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS #7 version element is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x5480 /**< The PKCS #7 content info is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_ALG -0x5500 /**< The algorithm tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CERT -0x5580 /**< The certificate tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE -0x5600 /**< Error parsing the signature */
@ -76,11 +71,11 @@
#define MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA -0x5700 /**< Input invalid. */
#define MBEDTLS_ERR_PKCS7_ALLOC_FAILED -0x5780 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_PKCS7_VERIFY_FAIL -0x5800 /**< Verification Failed */
#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID -0x5880 /**< The PKCS7 date issued/expired dates are invalid */
#define MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID -0x5880 /**< The PKCS #7 date issued/expired dates are invalid */
/* \} name */
/**
* \name PKCS7 Supported Version
* \name PKCS #7 Supported Version
* \{
*/
#define MBEDTLS_PKCS7_SUPPORTED_VERSION 0x01
@ -91,12 +86,12 @@ extern "C" {
#endif
/**
* Type-length-value structure that allows for ASN1 using DER.
* Type-length-value structure that allows for ASN.1 using DER.
*/
typedef mbedtls_asn1_buf mbedtls_pkcs7_buf;
/**
* Container for ASN1 named information objects.
* Container for ASN.1 named information objects.
* It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
*/
typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;
@ -107,7 +102,7 @@ typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;
typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence;
/**
* PKCS7 types
* PKCS #7 types
*/
typedef enum {
MBEDTLS_PKCS7_NONE=0,
@ -121,7 +116,7 @@ typedef enum {
mbedtls_pkcs7_type;
/**
* Structure holding PKCS7 signer info
* Structure holding PKCS #7 signer info
*/
typedef struct mbedtls_pkcs7_signer_info {
int MBEDTLS_PRIVATE(version);
@ -151,7 +146,7 @@ typedef struct mbedtls_pkcs7_signed_data {
mbedtls_pkcs7_signed_data;
/**
* Structure holding PKCS7 structure, only signed data for now
* Structure holding PKCS #7 structure, only signed data for now
*/
typedef struct mbedtls_pkcs7 {
mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw);
@ -160,21 +155,21 @@ typedef struct mbedtls_pkcs7 {
mbedtls_pkcs7;
/**
* \brief Initialize pkcs7 structure.
* \brief Initialize mbedtls_pkcs7 structure.
*
* \param pkcs7 pkcs7 structure.
* \param pkcs7 mbedtls_pkcs7 structure.
*/
void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7);
/**
* \brief Parse a single DER formatted pkcs7 detached signature.
* \brief Parse a single DER formatted PKCS #7 detached signature.
*
* \param pkcs7 The pkcs7 structure to be filled by parser for the output.
* \param buf The buffer holding only the DER encoded pkcs7.
* \param pkcs7 The mbedtls_pkcs7 structure to be filled by the parser.
* \param buf The buffer holding only the DER encoded PKCS #7 content.
* \param buflen The size in bytes of \p buf. The size must be exactly the
* length of the DER encoded pkcs7.
* length of the DER encoded PKCS #7 content.
*
* \note This function makes an internal copy of the PKCS7 buffer
* \note This function makes an internal copy of the PKCS #7 buffer
* \p buf. In particular, \p buf may be destroyed or reused
* after this call returns.
* \note Signatures with internal data are not supported.
@ -186,7 +181,7 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
const size_t buflen);
/**
* \brief Verification of PKCS7 signature against a caller-supplied
* \brief Verification of PKCS #7 signature against a caller-supplied
* certificate.
*
* For each signer in the PKCS structure, this function computes
@ -197,10 +192,10 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
* matches.
*
* This function does not use the certificates held within the
* PKCS7 structure itself, and does not check that the
* PKCS #7 structure itself, and does not check that the
* certificate is signed by a trusted certification authority.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param pkcs7 mbedtls_pkcs7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param data Plain data on which signature has to be verified.
* \param datalen Length of the data.
@ -216,7 +211,7 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
size_t datalen);
/**
* \brief Verification of PKCS7 signature against a caller-supplied
* \brief Verification of PKCS #7 signature against a caller-supplied
* certificate.
*
* For each signer in the PKCS structure, this function
@ -226,10 +221,10 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
* signature is good.
*
* This function does not use the certificates held within the
* PKCS7 structure itself, and does not check that the
* PKCS #7 structure itself, and does not check that the
* certificate is signed by a trusted certification authority.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param pkcs7 PKCS #7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param hash Hash of the plain data on which signature has to be verified.
* \param hashlen Length of the hash.
@ -244,10 +239,10 @@ int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
const unsigned char *hash, size_t hashlen);
/**
* \brief Unallocate all PKCS7 data and zeroize the memory.
* It doesn't free pkcs7 itself. It should be done by the caller.
* \brief Unallocate all PKCS #7 data and zeroize the memory.
* It doesn't free \p pkcs7 itself. This should be done by the caller.
*
* \param pkcs7 PKCS7 structure to free.
* \param pkcs7 mbedtls_pkcs7 structure to free.
*/
void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7);

View file

@ -39,6 +39,29 @@ typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
typedef time_t mbedtls_time_t;
#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO)
typedef MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO mbedtls_ms_time_t;
#else
#include <stdint.h>
#include <inttypes.h>
typedef int64_t mbedtls_ms_time_t;
#endif /* MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO */
/**
* \brief Get time in milliseconds.
*
* \return Monotonically-increasing current time in milliseconds.
*
* \note Define MBEDTLS_PLATFORM_MS_TIME_ALT to be able to provide an
* alternative implementation
*
* \warning This function returns a monotonically-increasing time value from a
* start time that will differ from platform to platform, and possibly
* from run to run of the process.
*
*/
mbedtls_ms_time_t mbedtls_ms_time(void);
/*
* The function pointers for time
*/

View file

@ -344,6 +344,54 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
#endif /* MBEDTLS_PSA_CRYPTO_C */
typedef struct {
psa_status_t psa_status;
int16_t mbedtls_error;
} mbedtls_error_pair_t;
#if !defined(MBEDTLS_MD_C) || !defined(MBEDTLS_MD5_C) || defined(MBEDTLS_USE_PSA_CRYPTO)
extern const mbedtls_error_pair_t psa_to_md_errors[4];
#endif
#if defined(MBEDTLS_LMS_C)
extern const mbedtls_error_pair_t psa_to_lms_errors[3];
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
extern const mbedtls_error_pair_t psa_to_ssl_errors[7];
#endif
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
extern const mbedtls_error_pair_t psa_to_pk_rsa_errors[8];
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
extern const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[7];
#endif
/* Generic fallback function for error translation,
* when the received state was not module-specific. */
int psa_generic_status_to_mbedtls(psa_status_t status);
/* This function iterates over provided local error translations,
* and if no match was found - calls the fallback error translation function. */
int psa_status_to_mbedtls(psa_status_t status,
const mbedtls_error_pair_t *local_translations,
size_t local_errors_num,
int (*fallback_f)(psa_status_t));
/* The second out of three-stage error handling functions of the pk module,
* acts as a fallback after RSA / ECDSA error translation, and if no match
* is found, it itself calls psa_generic_status_to_mbedtls. */
int psa_pk_status_to_mbedtls(psa_status_t status);
/* Utility macro to shorten the defines of error translator in modules. */
#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \
psa_status_to_mbedtls(status, error_list, \
sizeof(error_list)/sizeof(error_list[0]), \
fallback_f)
#endif /* MBEDTLS_PSA_CRYPTO_C */
#endif /* MBEDTLS_PSA_UTIL_H */

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