mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-30 16:20:11 +00:00
Merge branch 'development' into development
Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
This commit is contained in:
commit
e0bd2c2375
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Classify all '.function' files as C for syntax highlighting purposes
|
||||
*.function linguist-language=C
|
40
.github/pull_request_template.md
vendored
40
.github/pull_request_template.md
vendored
@ -1,36 +1,20 @@
|
||||
Notes:
|
||||
* Pull requests cannot be accepted until the PR follows the [contributing guidelines](../CONTRIBUTING.md). In particular, each commit must have at least one `Signed-off-by:` line from the committer to certify that the contribution is made under the terms of the [Developer Certificate of Origin](../dco.txt).
|
||||
* This is just a template, so feel free to use/remove the unnecessary things
|
||||
## Description
|
||||
A few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
Please write a few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
|
||||
## Status
|
||||
**READY/IN DEVELOPMENT/HOLD**
|
||||
|
||||
## Requires Backporting
|
||||
When there is a bug fix, it should be backported to all maintained and supported branches.
|
||||
Changes do not have to be backported if:
|
||||
- This PR is a new feature\enhancement
|
||||
- This PR contains changes in the API. If this is true, and there is a need for the fix to be backported, the fix should be handled differently in the legacy branch
|
||||
## PR checklist
|
||||
|
||||
Yes | NO
|
||||
Which branch?
|
||||
Please tick as appropriate and edit the reasons (e.g.: "backport: not needed because this is a new feature")
|
||||
|
||||
## Migrations
|
||||
If there is any API change, what's the incentive and logic for it.
|
||||
|
||||
YES | NO
|
||||
|
||||
## Additional comments
|
||||
Any additional information that could be of interest
|
||||
|
||||
## Todos
|
||||
- [ ] Tests
|
||||
- [ ] Documentation
|
||||
- [ ] Changelog updated
|
||||
- [ ] Backported
|
||||
- [ ] **changelog** provided, or not required
|
||||
- [ ] **backport** done, or not required
|
||||
- [ ] **tests** provided, or not required
|
||||
|
||||
|
||||
## Steps to test or reproduce
|
||||
Outline the steps to test or reproduce the PR here.
|
||||
|
||||
## Notes for the submitter
|
||||
|
||||
Please refer to the [contributing guidelines](https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md), especially the
|
||||
checklist for PR contributors.
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -28,6 +28,9 @@ massif-*
|
||||
.project
|
||||
/.settings
|
||||
|
||||
# Unix-like build artifacts:
|
||||
*.o
|
||||
|
||||
# MSVC build artifacts:
|
||||
*.exe
|
||||
*.pdb
|
||||
|
@ -1,5 +1,6 @@
|
||||
[MASTER]
|
||||
init-hook='import sys; sys.path.append("scripts")'
|
||||
min-similarity-lines=10
|
||||
|
||||
[BASIC]
|
||||
# We're ok with short funtion argument names.
|
||||
@ -73,3 +74,7 @@ reports=no
|
||||
# Allow unused variables if their name starts with an underscore.
|
||||
# [unused-argument]
|
||||
dummy-variables-rgx=_.*
|
||||
|
||||
[SIMILARITIES]
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=yes
|
||||
|
32
.readthedocs.yaml
Normal file
32
.readthedocs.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
# .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
|
||||
post_build:
|
||||
- |
|
||||
# Work around Readthedocs bug: Command parsing fails if the 'if' statement is on the first line
|
||||
if [ "$READTHEDOCS_VERSION" = "development" ]; then
|
||||
"$READTHEDOCS_VIRTUALENV_PATH/bin/rtd" projects "Mbed TLS API" redirects sync --wet-run -f docs/redirects.yaml
|
||||
fi
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
builder: dirhtml
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
83
.travis.yml
83
.travis.yml
@ -25,8 +25,40 @@ jobs:
|
||||
- tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
|
||||
|
||||
- name: full configuration
|
||||
os: linux
|
||||
dist: focal
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-10
|
||||
- gnutls-bin
|
||||
script:
|
||||
- tests/scripts/all.sh -k test_full_cmake_gcc_asan
|
||||
# Do a manual build+test sequence rather than using all.sh,
|
||||
# because there's no all.sh component that does what we want,
|
||||
# which is a build with Clang >= 10 and ASan, running all the SSL
|
||||
# testing.
|
||||
# - The clang executable in the default PATH is Clang 7 on
|
||||
# Travis's focal instances, but we want Clang >= 10.
|
||||
# - Running all the SSL testing requires a specific set of
|
||||
# OpenSSL and GnuTLS versions and we don't want to bother
|
||||
# with those on Travis.
|
||||
# So we explicitly select clang-10 as the compiler, and we
|
||||
# have ad hoc restrictions on SSL testing based on what is
|
||||
# passing at the time of writing. We will remove these limitations
|
||||
# gradually.
|
||||
- make generated_files
|
||||
- make CC=clang-10 CFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all -O2' LDFLAGS='-Werror -Wall -Wextra -fsanitize=address,undefined -fno-sanitize-recover=all'
|
||||
- make test
|
||||
- programs/test/selftest
|
||||
- tests/scripts/test_psa_constant_names.py
|
||||
- tests/ssl-opt.sh
|
||||
# Modern OpenSSL does not support null ciphers.
|
||||
- tests/compat.sh -p OpenSSL -e 'NULL'
|
||||
- tests/scripts/travis-log-failure.sh
|
||||
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
|
||||
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
|
||||
- tests/scripts/travis-log-failure.sh
|
||||
- tests/context-info.sh
|
||||
|
||||
- name: Windows
|
||||
os: windows
|
||||
@ -47,6 +79,55 @@ 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
|
||||
dist: focal
|
||||
arch: arm64
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc
|
||||
script:
|
||||
# Do a manual build+test sequence rather than using all.sh.
|
||||
#
|
||||
# On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
|
||||
# limitation of Travis CI. Base on `test_full_cmake_*`, we removed
|
||||
# `ssl-opt.sh` and GnuTLS compat.sh here to meet the time limitation.
|
||||
- scripts/config.py full
|
||||
- make generated_files
|
||||
- make CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
|
||||
- make test
|
||||
- programs/test/selftest
|
||||
- tests/scripts/test_psa_constant_names.py
|
||||
# Modern OpenSSL does not support fixed ECDH or null ciphers.
|
||||
- tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_'
|
||||
- tests/scripts/travis-log-failure.sh
|
||||
- tests/context-info.sh
|
||||
|
||||
- name: full configuration(GnuTLS compat tests) on arm64
|
||||
os: linux
|
||||
dist: focal
|
||||
arch: arm64
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang
|
||||
- gnutls-bin
|
||||
script:
|
||||
# Do a manual build+test sequence rather than using all.sh.
|
||||
#
|
||||
# On Arm64 host of Travis CI, the time of `test_full_cmake_*` exceeds
|
||||
# limitation of Travis CI. Base on `test_full_cmake_*`, we removed
|
||||
# `ssl-opt.sh` and OpenSSl compat.sh here to meet the time limitation.
|
||||
- scripts/config.py full
|
||||
- make generated_files
|
||||
- make CC=clang CFLAGS='-O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
|
||||
# GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
|
||||
- tests/compat.sh -p GnuTLS -e 'CAMELLIA'
|
||||
- tests/scripts/travis-log-failure.sh
|
||||
- tests/context-info.sh
|
||||
|
||||
after_failure:
|
||||
- tests/scripts/travis-log-failure.sh
|
||||
|
252
.uncrustify.cfg
Normal file
252
.uncrustify.cfg
Normal file
@ -0,0 +1,252 @@
|
||||
# Configuration options for Uncrustify specifying the Mbed TLS code style.
|
||||
#
|
||||
# Note: The code style represented by this file has not yet been introduced
|
||||
# to Mbed TLS.
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# Wrap lines at 100 characters
|
||||
code_width = 100
|
||||
|
||||
# Allow splitting long for statements between the condition statements
|
||||
ls_for_split_full = true
|
||||
|
||||
# Allow splitting function calls between arguments
|
||||
ls_func_split_full = true
|
||||
|
||||
input_tab_size = 4
|
||||
|
||||
# Spaces-only indentation
|
||||
indent_with_tabs = 0
|
||||
|
||||
indent_columns = 4
|
||||
|
||||
# Indent 'case' 1 level from 'switch'
|
||||
indent_switch_case = indent_columns
|
||||
|
||||
# Line-up strings broken by '\'
|
||||
indent_align_string = true
|
||||
|
||||
# Braces on the same line (Egyptian-style braces)
|
||||
nl_enum_brace = remove
|
||||
nl_union_brace = remove
|
||||
nl_struct_brace = remove
|
||||
nl_do_brace = remove
|
||||
nl_if_brace = remove
|
||||
nl_for_brace = remove
|
||||
nl_else_brace = remove
|
||||
nl_while_brace = remove
|
||||
nl_switch_brace = remove
|
||||
|
||||
# Braces on same line as keywords that follow them - 'else' and the 'while' in 'do {} while ()';
|
||||
nl_brace_else = remove
|
||||
nl_brace_while = remove
|
||||
# Space before else on the same line
|
||||
sp_brace_else = add
|
||||
# If else is on the same line as '{', force exactly 1 space between them
|
||||
sp_else_brace = force
|
||||
|
||||
# Functions are the exception and have braces on the next line
|
||||
nl_fcall_brace = add
|
||||
nl_fdef_brace = add
|
||||
|
||||
# Force exactly one space between ')' and '{' in statements
|
||||
sp_sparen_brace = force
|
||||
|
||||
# At least 1 space around assignment
|
||||
sp_assign = add
|
||||
|
||||
# Remove spaces around the preprocessor '##' token-concatenate
|
||||
sp_pp_concat = ignore
|
||||
|
||||
# At least 1 space around '||' and '&&'
|
||||
sp_bool = add
|
||||
|
||||
# But no space after the '!' operator
|
||||
sp_not = remove
|
||||
|
||||
# No space after the bitwise-not '~' operator
|
||||
sp_inv = remove
|
||||
|
||||
# No space after the addressof '&' operator
|
||||
sp_addr = remove
|
||||
|
||||
# No space around the member '.' and '->' operators
|
||||
sp_member = remove
|
||||
|
||||
# No space after the dereference '*' operator
|
||||
sp_deref = remove
|
||||
|
||||
# No space after a unary negation '-'
|
||||
sp_sign = remove
|
||||
|
||||
# No space between the '++'/'--' operator and its operand
|
||||
sp_incdec = remove
|
||||
|
||||
# At least 1 space around comparison operators
|
||||
sp_compare = add
|
||||
|
||||
# Remove spaces inside all kinds of parentheses:
|
||||
|
||||
# Remove spaces inside parentheses
|
||||
sp_inside_paren = remove
|
||||
|
||||
# No spaces inside statement parentheses
|
||||
sp_inside_sparen = remove
|
||||
|
||||
# No spaces inside cast parentheses '( char )x' -> '(char)x'
|
||||
sp_inside_paren_cast = remove
|
||||
|
||||
# No spaces inside function parentheses
|
||||
sp_inside_fparen = remove
|
||||
# (The case where the function has no parameters/arguments)
|
||||
sp_inside_fparens = remove
|
||||
|
||||
# No spaces inside the first parentheses in a function type
|
||||
sp_inside_tparen = remove
|
||||
|
||||
# (Uncrustify >= 0.74.0) No spaces inside parens in for statements
|
||||
sp_inside_for = remove
|
||||
|
||||
# Remove spaces between nested parentheses '( (' -> '(('
|
||||
sp_paren_paren = remove
|
||||
# (Uncrustify >= 0.74.0)
|
||||
sp_sparen_paren = remove
|
||||
|
||||
# Remove spaces between ')' and adjacent '('
|
||||
sp_cparen_oparen = remove
|
||||
|
||||
# (Uncrustify >= 0.73.0) space between 'do' and '{'
|
||||
sp_do_brace_open = force
|
||||
|
||||
# (Uncrustify >= 0.73.0) space between '}' and 'while'
|
||||
sp_brace_close_while = force
|
||||
|
||||
# At least 1 space before a '*' pointer star
|
||||
sp_before_ptr_star = add
|
||||
|
||||
# Remove spaces between pointer stars
|
||||
sp_between_ptr_star = remove
|
||||
|
||||
# No space after a pointer star
|
||||
sp_after_ptr_star = remove
|
||||
|
||||
# But allow a space in the case of e.g. char * const x;
|
||||
sp_after_ptr_star_qualifier = ignore
|
||||
|
||||
# Remove space after star in a function return type
|
||||
sp_after_ptr_star_func = remove
|
||||
|
||||
# At least 1 space after a type in variable definition etc
|
||||
sp_after_type = add
|
||||
|
||||
# Force exactly 1 space between a statement keyword (e.g. 'if') and an opening parenthesis
|
||||
sp_before_sparen = force
|
||||
|
||||
# Remove a space before a ';'
|
||||
sp_before_semi = remove
|
||||
# (Uncrustify >= 0.73.0) Remove space before a semi in a non-empty for
|
||||
sp_before_semi_for = remove
|
||||
# (Uncrustify >= 0.73.0) Remove space in empty first statement of a for
|
||||
sp_before_semi_for_empty = remove
|
||||
# (Uncrustify >= 0.74.0) Remove space in empty middle statement of a for
|
||||
sp_between_semi_for_empty = remove
|
||||
|
||||
# Add a space after a ';' (unless a comment follows)
|
||||
sp_after_semi = add
|
||||
# (Uncrustify >= 0.73.0) Add a space after a semi in non-empty for statements
|
||||
sp_after_semi_for = add
|
||||
# (Uncrustify >= 0.73.0) No space after final semi in empty for statements
|
||||
sp_after_semi_for_empty = remove
|
||||
|
||||
# Remove spaces on the inside of square brackets '[]'
|
||||
sp_inside_square = remove
|
||||
|
||||
# Must have at least 1 space after a comma
|
||||
sp_after_comma = add
|
||||
|
||||
# Must not have a space before a comma
|
||||
sp_before_comma = remove
|
||||
|
||||
# No space before the ':' in a case statement
|
||||
sp_before_case_colon = remove
|
||||
|
||||
# Must have space after a cast - '(char)x' -> '(char) x'
|
||||
sp_after_cast = add
|
||||
|
||||
# No space between 'sizeof' and '('
|
||||
sp_sizeof_paren = remove
|
||||
|
||||
# At least 1 space inside '{ }'
|
||||
sp_inside_braces = add
|
||||
|
||||
# At least 1 space inside '{ }' in an enum
|
||||
sp_inside_braces_enum = add
|
||||
|
||||
# At least 1 space inside '{ }' in a struct
|
||||
sp_inside_braces_struct = add
|
||||
|
||||
# At least 1 space between a function return type and the function name
|
||||
sp_type_func = add
|
||||
|
||||
# No space between a function name and its arguments/parameters
|
||||
sp_func_proto_paren = remove
|
||||
sp_func_def_paren = remove
|
||||
sp_func_call_paren = remove
|
||||
|
||||
# No space between '__attribute__' and '('
|
||||
sp_attribute_paren = remove
|
||||
|
||||
# No space between 'defined' and '(' in preprocessor conditions
|
||||
sp_defined_paren = remove
|
||||
|
||||
# At least 1 space between a macro's name and its definition
|
||||
sp_macro = add
|
||||
sp_macro_func = add
|
||||
|
||||
# Force exactly 1 space between a '}' and the name of a typedef if on the same line
|
||||
sp_brace_typedef = force
|
||||
|
||||
# At least 1 space before a '\' line continuation
|
||||
sp_before_nl_cont = add
|
||||
|
||||
# At least 1 space around '?' and ':' in ternary statements
|
||||
sp_cond_colon = add
|
||||
sp_cond_question = add
|
||||
|
||||
# Space between #else/#endif and comment afterwards
|
||||
sp_endif_cmt = add
|
||||
|
||||
# Remove newlines at the start of a file
|
||||
nl_start_of_file = remove
|
||||
|
||||
# At least 1 newline at the end of a file
|
||||
nl_end_of_file = add
|
||||
nl_end_of_file_min = 1
|
||||
|
||||
# Add braces in single-line statements
|
||||
mod_full_brace_do = add
|
||||
mod_full_brace_for = add
|
||||
mod_full_brace_if = add
|
||||
mod_full_brace_while = add
|
||||
|
||||
# Remove parentheses from return statements
|
||||
mod_paren_on_return = remove
|
||||
|
||||
# Disable removal of leading spaces in a multi-line comment if the first and
|
||||
# last lines are the same length
|
||||
cmt_multi_check_last = false
|
9
3rdparty/CMakeLists.txt
vendored
9
3rdparty/CMakeLists.txt
vendored
@ -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()
|
||||
|
3
3rdparty/Makefile.inc
vendored
3
3rdparty/Makefile.inc
vendored
@ -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
|
||||
|
1
3rdparty/everest/.gitignore
vendored
1
3rdparty/everest/.gitignore
vendored
@ -1,2 +1 @@
|
||||
*.o
|
||||
Makefile
|
||||
|
5
3rdparty/everest/library/everest.c
vendored
5
3rdparty/everest/library/everest.c
vendored
@ -28,12 +28,7 @@
|
||||
#include "everest/x25519.h"
|
||||
#include "everest/everest.h"
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
|
||||
|
25
3rdparty/p256-m/CMakeLists.txt
vendored
Normal file
25
3rdparty/p256-m/CMakeLists.txt
vendored
Normal 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
5
3rdparty/p256-m/Makefile.inc
vendored
Normal 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
4
3rdparty/p256-m/README.md
vendored
Normal 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
202
3rdparty/p256-m/p256-m/LICENSE
vendored
Normal 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
544
3rdparty/p256-m/p256-m/README.md
vendored
Normal 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
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
95
3rdparty/p256-m/p256-m/p256-m.h
vendored
Normal 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 */
|
242
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
Normal file
242
3rdparty/p256-m/p256-m_driver_entrypoints.c
vendored
Normal 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 */
|
162
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
Normal file
162
3rdparty/p256-m/p256-m_driver_entrypoints.h
vendored
Normal 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 */
|
@ -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.0>.
|
||||
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.3>.
|
||||
|
||||
Users are urged to always use the latest version of a maintained branch.
|
||||
|
@ -34,9 +34,9 @@ cmake_policy(SET CMP0011 NEW)
|
||||
cmake_policy(SET CMP0012 NEW)
|
||||
|
||||
if(TEST_CPP)
|
||||
project("mbed TLS" C CXX)
|
||||
project("mbed TLS" LANGUAGES C CXX)
|
||||
else()
|
||||
project("mbed TLS" C)
|
||||
project("mbed TLS" LANGUAGES C)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
@ -120,38 +120,33 @@ endif()
|
||||
|
||||
# Create a symbolic link from ${base_name} in the binary directory
|
||||
# to the corresponding path in the source directory.
|
||||
# Note: Copies the file(s) on Windows.
|
||||
function(link_to_source base_name)
|
||||
# Get OS dependent path to use in `execute_process`
|
||||
if (CMAKE_HOST_WIN32)
|
||||
#mklink is an internal command of cmd.exe it can only work with \
|
||||
string(REPLACE "/" "\\" link "${CMAKE_CURRENT_BINARY_DIR}/${base_name}")
|
||||
string(REPLACE "/" "\\" target "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}")
|
||||
else()
|
||||
set(link "${CMAKE_CURRENT_BINARY_DIR}/${base_name}")
|
||||
set(target "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}")
|
||||
endif()
|
||||
set(link "${CMAKE_CURRENT_BINARY_DIR}/${base_name}")
|
||||
set(target "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}")
|
||||
|
||||
# Linking to non-existent file is not desirable. At best you will have a
|
||||
# dangling link, but when building in tree, this can create a symbolic link
|
||||
# to itself.
|
||||
if (EXISTS ${target} AND NOT EXISTS ${link})
|
||||
if (CMAKE_HOST_UNIX)
|
||||
set(command ln -s ${target} ${link})
|
||||
execute_process(COMMAND ln -s ${target} ${link}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE output)
|
||||
|
||||
if (NOT ${result} EQUAL 0)
|
||||
message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
|
||||
endif()
|
||||
else()
|
||||
if (IS_DIRECTORY ${target})
|
||||
set(command cmd.exe /c mklink /j ${link} ${target})
|
||||
file(GLOB_RECURSE files FOLLOW_SYMLINKS LIST_DIRECTORIES false RELATIVE ${target} "${target}/*")
|
||||
foreach(file IN LISTS files)
|
||||
configure_file("${target}/${file}" "${link}/${file}" COPYONLY)
|
||||
endforeach(file)
|
||||
else()
|
||||
set(command cmd.exe /c mklink /h ${link} ${target})
|
||||
configure_file(${target} ${link} COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${command}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE output)
|
||||
|
||||
if (NOT ${result} EQUAL 0)
|
||||
message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction(link_to_source)
|
||||
|
||||
@ -285,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)
|
||||
@ -309,22 +315,15 @@ if(ENABLE_TESTING)
|
||||
# additional convenience targets for Unix only
|
||||
if(UNIX)
|
||||
|
||||
ADD_CUSTOM_TARGET(covtest
|
||||
COMMAND make test
|
||||
COMMAND programs/test/selftest
|
||||
COMMAND tests/compat.sh
|
||||
COMMAND tests/ssl-opt.sh
|
||||
)
|
||||
|
||||
# For coverage testing:
|
||||
# 1. Build with:
|
||||
# cmake -D CMAKE_BUILD_TYPE=Coverage /path/to/source && make
|
||||
# 2. Run the relevant tests for the part of the code you're interested in.
|
||||
# For the reference coverage measurement, see
|
||||
# tests/scripts/basic-build-test.sh
|
||||
# 3. Run scripts/lcov.sh to generate an HTML report.
|
||||
ADD_CUSTOM_TARGET(lcov
|
||||
COMMAND rm -rf Coverage
|
||||
COMMAND lcov --capture --initial --directory library/CMakeFiles/mbedtls.dir -o files.info
|
||||
COMMAND lcov --capture --directory library/CMakeFiles/mbedtls.dir -o tests.info
|
||||
COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
|
||||
COMMAND lcov --remove all.info -o final.info '*.h'
|
||||
COMMAND gendesc tests/Descriptions.txt -o descriptions
|
||||
COMMAND genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
|
||||
COMMAND rm -f files.info tests.info all.info final.info descriptions
|
||||
COMMAND scripts/lcov.sh
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(memcheck
|
||||
@ -355,12 +354,12 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
write_basic_package_version_file(
|
||||
"cmake/MbedTLSConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
VERSION 3.2.1)
|
||||
VERSION 3.4.0)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfigVersion.cmake"
|
||||
DESTINATION "cmake")
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS")
|
||||
|
||||
export(
|
||||
EXPORT MbedTLSTargets
|
||||
@ -370,7 +369,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
install(
|
||||
EXPORT MbedTLSTargets
|
||||
NAMESPACE MbedTLS::
|
||||
DESTINATION "cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS"
|
||||
FILE "MbedTLSTargets.cmake")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15)
|
||||
|
@ -1,14 +1,21 @@
|
||||
Contributing
|
||||
============
|
||||
We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
|
||||
We gratefully accept bug reports and contributions from the community. All PRs are reviewed by the project team / community, and may need some modifications to
|
||||
be accepted.
|
||||
|
||||
- As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
|
||||
- The contribution should not break API or ABI, unless there is a real justification for that. If there is an API change, the contribution, if accepted, will be merged only when there will be a major release.
|
||||
Quick Checklist for PR contributors
|
||||
-----------------------------------
|
||||
More details on all of these points may be found in the sections below.
|
||||
|
||||
- [Sign-off](#license-and-copyright): all commits must be signed off.
|
||||
- [Tests](#tests): please ensure the PR includes adequate tests.
|
||||
- [Changelog](#documentation): if needed, please provide a changelog entry.
|
||||
- [Backports](#long-term-support-branches): provide a backport if needed (it's fine to wait until the main PR is accepted).
|
||||
|
||||
Coding Standards
|
||||
----------------
|
||||
- We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions are fully tested before submission, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections.
|
||||
- The code should be written in a clean and readable style.
|
||||
- Contributions should include tests, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections. Please check that your contribution passes basic tests before submission, and check the CI results after making a pull request.
|
||||
- The code should be written in a clean and readable style, and must follow [our coding standards](https://mbed-tls.readthedocs.io/en/latest/kb/development/mbedtls-coding-standards/).
|
||||
- The code should be written in a portable generic way, that will benefit the whole community, and not only your own needs.
|
||||
- The code should be secure, and will be reviewed from a security point of view as well.
|
||||
|
||||
@ -17,23 +24,17 @@ 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.
|
||||
1. All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible.
|
||||
1. Ensure that each commit has at least one `Signed-off-by:` line from the committer. If anyone else contributes to the commit, they should also add their own `Signed-off-by:` line. By adding this line, contributor(s) certify that the contribution is made under the terms of the [Developer Certificate of Origin](dco.txt). The contribution licensing is described in the [License section of the README](README.md#License).
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
|
||||
The project aims to minimise the impact on users upgrading to newer versions of the library and it should not be necessary for a user to make any changes to their own code to work with a newer version of the library. Unless the user has made an active decision to use newer features, a newer generation of the library or a change has been necessary due to a security issue or other significant software defect, no modifications to their own code should be necessary. To achieve this, API compatibility is maintained between different versions of Mbed TLS on the main development branch and in LTS (Long Term Support) branches, as described in [BRANCHES.md](BRANCHES.md).
|
||||
|
||||
To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change.
|
||||
To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change. If there is an API change, the contribution, if accepted, will be merged only when there is a major release.
|
||||
|
||||
Where changes to an existing interface are necessary, functions in the public interface which need to be changed, are marked as 'deprecated'. This is done with the preprocessor symbols `MBEDTLS_DEPRECATED_WARNING` and `MBEDTLS_DEPRECATED_REMOVED`. Then, a new function with a new name but similar if not identical behaviour to the original function containing the necessary changes should be created alongside the existing deprecated function.
|
||||
|
||||
When a build is made with the deprecation preprocessor symbols defined, a compiler warning will be generated to warn a user that the function will be removed at some point in the future, notifying users that they should change from the older deprecated function to the newer function at their own convenience.
|
||||
|
||||
Therefore, no changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. As described above, if a function needs to be changed, a new function needs to be created alongside it, with a new name, and whatever change is necessary, such as a new parameter or the addition of a return value.
|
||||
No changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. Where changes to an existing interface are necessary, functions in the public interface which need to be changed are marked as 'deprecated'. If there is a strong reason to replace an existing function with one that has a slightly different interface (different prototype, or different documented behavior), create a new function with a new name with the desired interface. Keep the old function, but mark it as deprecated.
|
||||
|
||||
Periodically, the library will remove deprecated functions from the library which will be a breaking change in the API, but such changes will be made only in a planned, structured way that gives sufficient notice to users of the library.
|
||||
|
||||
@ -56,9 +57,9 @@ Tests
|
||||
-----
|
||||
As mentioned, tests that show the correctness of the feature or bug fix should be added to the pull request, if no such tests exist.
|
||||
|
||||
Mbed TLS includes a comprehensive set of test suites in the `tests/` directory that are dynamically generated to produce the actual test source files (e.g. `test_suite_mpi.c`). These files are generated from a `function file` (e.g. `suites/test_suite_mpi.function`) and a `data file` (e.g. `suites/test_suite_mpi.data`). The function file contains the test functions. The data file contains the test cases, specified as parameters that will be passed to the test function.
|
||||
Mbed TLS includes a comprehensive set of test suites in the `tests/` directory that are dynamically generated to produce the actual test source files (e.g. `test_suite_rsa.c`). These files are generated from a `function file` (e.g. `suites/test_suite_rsa.function`) and a `data file` (e.g. `suites/test_suite_rsa.data`). The function file contains the test functions. The data file contains the test cases, specified as parameters that will be passed to the test function.
|
||||
|
||||
[A Knowledge Base article describing how to add additional tests is available on the Mbed TLS website](https://tls.mbed.org/kb/development/test_suites).
|
||||
[A Knowledge Base article describing how to add additional tests is available on the Mbed TLS website](https://mbed-tls.readthedocs.io/en/latest/kb/development/test_suites/).
|
||||
|
||||
A test script `tests/scripts/basic-build-test.sh` is available to show test coverage of the library. New code contributions should provide a similar level of code coverage to that which already exists for the library.
|
||||
|
||||
@ -77,5 +78,14 @@ Mbed TLS is well documented, but if you think documentation is needed, speak out
|
||||
1. All interfaces should be documented through Doxygen. New APIs should introduce Doxygen documentation.
|
||||
1. Complex parts in the code should include comments.
|
||||
1. If needed, a Readme file is advised.
|
||||
1. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
|
||||
1. If a [Knowledge Base (KB)](https://mbed-tls.readthedocs.io/en/latest/kb/) article should be added, write this as a comment in the PR description.
|
||||
1. A [ChangeLog](https://github.com/Mbed-TLS/mbedtls/blob/development/ChangeLog.d/00README.md) entry should be added for this contribution.
|
||||
|
||||
License and Copyright
|
||||
---------------------
|
||||
|
||||
All new files should include the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) standard license header where possible. For licensing details, please see the [License section of the README](README.md#License).
|
||||
|
||||
The copyright on contributions is retained by the original authors of the code. Where possible for new files, this should be noted in a comment at the top of the file in the form: "Copyright The Mbed TLS Contributors".
|
||||
|
||||
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and be subject to the same Apache 2.0 license. This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.
|
||||
|
440
ChangeLog
440
ChangeLog
@ -1,9 +1,424 @@
|
||||
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
|
||||
* Previously the macro MBEDTLS_SSL_DTLS_CONNECTION_ID implemented version 05
|
||||
of the IETF draft, and was marked experimental and disabled by default.
|
||||
It is now no longer experimental, and implements the final version from
|
||||
RFC 9146, which is not interoperable with the draft-05 version.
|
||||
If you need to communicate with peers that use earlier versions of
|
||||
Mbed TLS, then you need to define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT
|
||||
to 1, but then you won't be able to communicate with peers that use the
|
||||
standard (non-draft) version.
|
||||
If you need to interoperate with both classes of peers with the
|
||||
same build of Mbed TLS, please let us know about your situation on the
|
||||
mailing list or GitHub.
|
||||
|
||||
Requirement changes
|
||||
* When building with PSA drivers using generate_driver_wrappers.py, or
|
||||
when building the library from the development branch rather than
|
||||
from a release, the Python module jsonschema is now necessary, in
|
||||
addition to jinja2. The official list of required Python modules is
|
||||
maintained in scripts/basic.requirements.txt and may change again
|
||||
in the future.
|
||||
|
||||
New deprecations
|
||||
* Deprecate mbedtls_asn1_free_named_data().
|
||||
Use mbedtls_asn1_free_named_data_list()
|
||||
or mbedtls_asn1_free_named_data_list_shallow().
|
||||
|
||||
Features
|
||||
* Support rsa_pss_rsae_* signature algorithms in TLS 1.2.
|
||||
* make: enable building unversioned shared library, with e.g.:
|
||||
"SHARED=1 SOEXT_TLS=so SOEXT_X509=so SOEXT_CRYPTO=so make lib"
|
||||
resulting in library names like "libmbedtls.so" rather than
|
||||
"libmbedcrypto.so.11".
|
||||
* Expose the EC J-PAKE functionality through the Draft PSA PAKE Crypto API.
|
||||
Only the ECC primitive with secp256r1 curve and SHA-256 hash algorithm
|
||||
are supported in this implementation.
|
||||
* Some modules can now use PSA drivers for hashes, including with no
|
||||
built-in implementation present, but only in some configurations.
|
||||
- RSA OAEP and PSS (PKCS#1 v2.1), PKCS5, PKCS12 and EC J-PAKE now use
|
||||
hashes from PSA when (and only when) MBEDTLS_MD_C is disabled.
|
||||
- PEM parsing of encrypted files now uses MD-5 from PSA when (and only
|
||||
when) MBEDTLS_MD5_C is disabled.
|
||||
See the documentation of the corresponding macros in mbedtls_config.h for
|
||||
details.
|
||||
Note that some modules are not able to use hashes from PSA yet, including
|
||||
the entropy module. As a consequence, for now the only way to build with
|
||||
all hashes only provided by drivers (no built-in hash) is to use
|
||||
MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
|
||||
* When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 now
|
||||
properly negotiate/accept hashes based on their availability in PSA.
|
||||
As a consequence, they now work in configurations where the built-in
|
||||
implementations of (some) hashes are excluded and those hashes are only
|
||||
provided by PSA drivers. (See previous entry for limitation on RSA-PSS
|
||||
though: that module only use hashes from PSA when MBEDTLS_MD_C is off).
|
||||
* Add support for opaque keys as the private keys associated to certificates
|
||||
for authentication in TLS 1.3.
|
||||
* Add the LMS post-quantum-safe stateful-hash asymmetric signature scheme.
|
||||
Signature verification is production-ready, but generation is for testing
|
||||
purposes only. This currently only supports one parameter set
|
||||
(LMS_SHA256_M32_H10), meaning that each private key can be used to sign
|
||||
1024 messages. As such, it is not intended for use in TLS, but instead
|
||||
for verification of assets transmitted over an insecure channel,
|
||||
particularly firmware images.
|
||||
* Add the LM-OTS post-quantum-safe one-time signature scheme, which is
|
||||
required for LMS. This can be used independently, but each key can only
|
||||
be used to sign one message so is impractical for most circumstances.
|
||||
* Mbed TLS now supports TLS 1.3 key establishment via pre-shared keys.
|
||||
The pre-shared keys can be provisioned externally or via the ticket
|
||||
mechanism (session resumption).
|
||||
The ticket mechanism is supported when the configuration option
|
||||
MBEDTLS_SSL_SESSION_TICKETS is enabled.
|
||||
New options MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_xxx_ENABLED
|
||||
control the support for the three possible TLS 1.3 key exchange modes.
|
||||
* cert_write: support for setting extended key usage attributes. A
|
||||
corresponding new public API call has been added in the library,
|
||||
mbedtls_x509write_crt_set_ext_key_usage().
|
||||
* cert_write: support for writing certificate files in either PEM
|
||||
or DER format.
|
||||
* The PSA driver wrapper generator generate_driver_wrappers.py now
|
||||
supports a subset of the driver description language, including
|
||||
the following entry points: import_key, export_key, export_public_key,
|
||||
get_builtin_key, copy_key.
|
||||
* The new functions mbedtls_asn1_free_named_data_list() and
|
||||
mbedtls_asn1_free_named_data_list_shallow() simplify the management
|
||||
of memory in named data lists in X.509 structures.
|
||||
* The TLS 1.2 EC J-PAKE key exchange can now use the PSA Crypto API.
|
||||
Additional PSA key slots will be allocated in the process of such key
|
||||
exchange for builds that enable MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED and
|
||||
MBEDTLS_USE_PSA_CRYPTO.
|
||||
* Add support for DTLS Connection ID as defined by RFC 9146, controlled by
|
||||
MBEDTLS_SSL_DTLS_CONNECTION_ID (enabled by default) and configured with
|
||||
mbedtls_ssl_set_cid().
|
||||
* Add a driver dispatch layer for raw key agreement, enabling alternative
|
||||
implementations of raw key agreement through the key_agreement driver
|
||||
entry point. This entry point is specified in the proposed PSA driver
|
||||
interface, but had not yet been implemented.
|
||||
* Add an ad-hoc key derivation function handling EC J-PAKE to PMS
|
||||
calculation that can be used to derive the session secret in TLS 1.2,
|
||||
as described in draft-cragie-tls-ecjpake-01. This can be achieved by
|
||||
using PSA_ALG_TLS12_ECJPAKE_TO_PMS as the key derivation algorithm.
|
||||
|
||||
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.
|
||||
* 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.
|
||||
|
||||
Bugfix
|
||||
* Refactor mbedtls_aes_context to support shallow-copying. Fixes #2147.
|
||||
* Fix an issue with in-tree CMake builds in releases with GEN_FILES
|
||||
turned off: if a shipped file was missing from the working directory,
|
||||
it could be turned into a symbolic link to itself.
|
||||
* Fix a long-standing build failure when building x86 PIC code with old
|
||||
gcc (4.x). The code will be slower, but will compile. We do however
|
||||
recommend upgrading to a more recent compiler instead. Fixes #1910.
|
||||
* Fix support for little-endian Microblaze when MBEDTLS_HAVE_ASM is defined.
|
||||
Contributed by Kazuyuki Kimura to fix #2020.
|
||||
* Use double quotes to include private header file psa_crypto_cipher.h.
|
||||
Fixes 'file not found with <angled> include' error
|
||||
when building with Xcode.
|
||||
* Fix handling of broken symlinks when loading certificates using
|
||||
mbedtls_x509_crt_parse_path(). Instead of returning an error as soon as a
|
||||
broken link is encountered, skip the broken link and continue parsing
|
||||
other certificate files. Contributed by Eduardo Silva in #2602.
|
||||
* Fix an interoperability failure between an Mbed TLS client with both
|
||||
TLS 1.2 and TLS 1.3 support, and a TLS 1.2 server that supports
|
||||
rsa_pss_rsae_* signature algorithms. This failed because Mbed TLS
|
||||
advertised support for PSS in both TLS 1.2 and 1.3, but only
|
||||
actually supported PSS in TLS 1.3.
|
||||
* Fix a compilation error when using CMake with an IAR toolchain.
|
||||
Fixes #5964.
|
||||
* Fix a build error due to a missing prototype warning when
|
||||
MBEDTLS_DEPRECATED_REMOVED is enabled.
|
||||
* Fix mbedtls_ctr_drbg_free() on an initialized but unseeded context. When
|
||||
MBEDTLS_AES_ALT is enabled, it could call mbedtls_aes_free() on an
|
||||
uninitialized context.
|
||||
* Fix a build issue on Windows using CMake where the source and build
|
||||
directories could not be on different drives. Fixes #5751.
|
||||
* Fix bugs and missing dependencies when building and testing
|
||||
configurations with only one encryption type enabled in TLS 1.2.
|
||||
* Provide the missing definition of mbedtls_setbuf() in some configurations
|
||||
with MBEDTLS_PLATFORM_C disabled. Fixes #6118, #6196.
|
||||
* Fix compilation errors when trying to build with
|
||||
PSA drivers for AEAD (GCM, CCM, Chacha20-Poly1305).
|
||||
* Fix memory leak in ssl_parse_certificate_request() caused by
|
||||
mbedtls_x509_get_name() not freeing allocated objects in case of error.
|
||||
Change mbedtls_x509_get_name() to clean up allocated objects on error.
|
||||
* Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
|
||||
MBEDTLS_USE_PSA_CRYPTO or MBEDTLS_PK_WRITE_C. Fixes #6408.
|
||||
* Fix build failure with MBEDTLS_RSA_C and MBEDTLS_PSA_CRYPTO_C but not
|
||||
MBEDTLS_PK_PARSE_C. Fixes #6409.
|
||||
* Fix ECDSA verification, where it was not always validating the
|
||||
public key. This bug meant that it was possible to verify a
|
||||
signature with an invalid public key, in some cases. Reported by
|
||||
Guido Vranken using Cryptofuzz in #4420.
|
||||
* Fix a possible null pointer dereference if a memory allocation fails
|
||||
in TLS PRF code. Reported by Michael Madsen in #6516.
|
||||
* Fix TLS 1.3 session resumption. Fixes #6488.
|
||||
* Add a configuration check to exclude optional client authentication
|
||||
in TLS 1.3 (where it is forbidden).
|
||||
* Fix a bug in which mbedtls_x509_crt_info() would produce non-printable
|
||||
bytes when parsing certificates containing a binary RFC 4108
|
||||
HardwareModuleName as a Subject Alternative Name extension. Hardware
|
||||
serial numbers are now rendered in hex format. Fixes #6262.
|
||||
* Fix bug in error reporting in dh_genprime.c where upon failure,
|
||||
the error code returned by mbedtls_mpi_write_file() is overwritten
|
||||
and therefore not printed.
|
||||
* In the bignum module, operations of the form (-A) - (+A) or (-A) - (-A)
|
||||
with A > 0 created an unintended representation of the value 0 which was
|
||||
not processed correctly by some bignum operations. Fix this. This had no
|
||||
consequence on cryptography code, but might affect applications that call
|
||||
bignum directly and use negative numbers.
|
||||
* Fix a bug whereby the list of signature algorithms sent as part of
|
||||
the TLS 1.2 server certificate request would get corrupted, meaning the
|
||||
first algorithm would not get sent and an entry consisting of two random
|
||||
bytes would be sent instead. Found by Serban Bejan and Dudek Sebastian.
|
||||
* Fix undefined behavior (typically harmless in practice) of
|
||||
mbedtls_mpi_add_mpi(), mbedtls_mpi_add_abs() and mbedtls_mpi_add_int()
|
||||
when both operands are 0 and the left operand is represented with 0 limbs.
|
||||
* Fix undefined behavior (typically harmless in practice) when some bignum
|
||||
functions receive the most negative value of mbedtls_mpi_sint. Credit
|
||||
to OSS-Fuzz. Fixes #6597.
|
||||
* Fix undefined behavior (typically harmless in practice) in PSA ECB
|
||||
encryption and decryption.
|
||||
* Move some SSL-specific code out of libmbedcrypto where it had been placed
|
||||
accidentally.
|
||||
* Fix a build error when compiling the bignum module for some Arm platforms.
|
||||
Fixes #6089, #6124, #6217.
|
||||
|
||||
Changes
|
||||
* Add the ability to query PSA_WANT_xxx macros to query_compile_time_config.
|
||||
* Calling AEAD tag-specific functions for non-AEAD algorithms (which
|
||||
should not be done - they are documented for use only by AES-GCM and
|
||||
ChaCha20+Poly1305) now returns MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
|
||||
instead of success (0).
|
||||
|
||||
= Mbed TLS 3.2.1 branch released 2022-07-12
|
||||
|
||||
Bugfix
|
||||
* Re-add missing generated file library/ssl_debug_helpers_generated.c
|
||||
* Re-add missing generated file library/psa_crypto_driver_wrappers.c
|
||||
|
||||
= Mbed TLS 3.2.0 branch released 2022-07-11
|
||||
|
||||
@ -249,7 +664,7 @@ Bugfix
|
||||
make to break on a clean checkout. Fixes #5340.
|
||||
* Work around an MSVC ARM64 compiler bug causing incorrect behaviour
|
||||
in mbedtls_mpi_exp_mod(). Reported by Tautvydas Žilys in #5467.
|
||||
* Removed the prompt to exit from all windows build programs that was causing
|
||||
* Removed the prompt to exit from all windows build programs, which was causing
|
||||
issues in CI/CD environments.
|
||||
|
||||
Changes
|
||||
@ -463,7 +878,7 @@ API changes
|
||||
provides better randomness. Instead of HAVEGE, declare OS or hardware RNG
|
||||
interfaces with mbedtls_entropy_add_source() and/or use an entropy seed
|
||||
file created securely during device provisioning. See
|
||||
https://tls.mbed.org/kb/how-to/add-entropy-sources-to-entropy-pool for
|
||||
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/add-entropy-sources-to-entropy-pool/ for
|
||||
more information.
|
||||
* Add missing const attributes to API functions.
|
||||
* Remove helpers for the transition from Mbed TLS 1.3 to Mbed TLS 2.0: the
|
||||
@ -765,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
|
||||
|
3
ChangeLog.d/X509Parse_SignatureKeyId_AuthorityKeyId.txt
Normal file
3
ChangeLog.d/X509Parse_SignatureKeyId_AuthorityKeyId.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* When parsing X.509 certificates, support the extensions
|
||||
SignatureKeyIdentifier and AuthorityKeyIdentifier.
|
3
ChangeLog.d/add-directoryname-san.txt
Normal file
3
ChangeLog.d/add-directoryname-san.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Add parsing of directoryName subtype for subjectAltName extension in
|
||||
x509 certificates.
|
5
ChangeLog.d/add-milliseconds-time-api.txt
Normal file
5
ChangeLog.d/add-milliseconds-time-api.txt
Normal 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.
|
||||
|
5
ChangeLog.d/add-missing-md-includes.txt
Normal file
5
ChangeLog.d/add-missing-md-includes.txt
Normal 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.
|
3
ChangeLog.d/add-psa_want_alg_some_pake.txt
Normal file
3
ChangeLog.d/add-psa_want_alg_some_pake.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Don't include the PSA dispatch functions for PAKEs (psa_pake_setup() etc)
|
||||
if no PAKE algorithms are requested
|
@ -1,8 +0,0 @@
|
||||
Features
|
||||
* When GnuTLS/Openssl server is configured in TLS 1.2 mode with a certificate
|
||||
declaring an RSA public key and Mbed TLS is configured in hybrid mode, if
|
||||
`rsa_pss_rsae_*` algorithms are before `rsa_pkcs1_*` ones in this list then
|
||||
the GnuTLS/Openssl server chooses an `rsa_pss_rsae_*` signature algorithm
|
||||
for its signature in the key exchange message. As Mbed TLS 1.2 does not
|
||||
support them, the handshake fails. Add `rsa_pss_rsae_*` support for TLS 1.2
|
||||
to resolve the compitablity issue.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix a long-standing build failure when building x86 PIC code with old
|
||||
gcc (4.x). The code will be slower, but will compile. We do however
|
||||
recommend upgrading to a more recent compiler instead. Fixes #1910.
|
3
ChangeLog.d/driver-ffdh.txt
Normal file
3
ChangeLog.d/driver-ffdh.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Features
|
||||
* Add a driver dispatch layer for FFDH keys, enabling alternative
|
||||
implementations of FFDH through the driver entry points.
|
7
ChangeLog.d/driver-only-ecdh.txt
Normal file
7
ChangeLog.d/driver-only-ecdh.txt
Normal 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.
|
10
ChangeLog.d/driver-only-hashes.txt
Normal file
10
ChangeLog.d/driver-only-hashes.txt
Normal 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.
|
3
ChangeLog.d/ec_jpake_user_peer_2.txt
Normal file
3
ChangeLog.d/ec_jpake_user_peer_2.txt
Normal 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").
|
@ -1,2 +0,0 @@
|
||||
Changes
|
||||
* Add the ability to query PSA_WANT_xxx macros to query_compile_time_config
|
@ -1,2 +0,0 @@
|
||||
Bugfix
|
||||
* Refactor mbedtls_aes_context to support shallow-copying. Fixes #2147.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix mbedtls_ctr_drbg_free() on an initialized but unseeded context. When
|
||||
MBEDTLS_AES_ALT is enabled, it could call mbedtls_aes_free() on an
|
||||
uninitialized context.
|
@ -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.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix build error due to missing prototype
|
||||
warning when MBEDTLS_DEPRECATED_REMOVED is enabled
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix an issue in releases with GEN_FILES turned off whereby missing
|
||||
generated files could be turned into symlinks to themselves.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fixed an issue that cause compile error using CMake IAR toolchain.
|
||||
Fixes #5964.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Use double quotes to include private header file psa_crypto_cipher.h.
|
||||
Fixes 'file not found with <angled> include' error
|
||||
when building with Xcode.
|
@ -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.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix support for little-endian Microblaze when MBEDTLS_HAVE_ASM is defined.
|
||||
Contributed by Kazuyuki Kimura to fix #2020.
|
@ -1,5 +0,0 @@
|
||||
Features
|
||||
* make: enable building unversioned shared library, with e.g.:
|
||||
"SHARED=1 SOEXT_TLS=so SOEXT_X509=so SOEXT_CRYPTO=so make lib"
|
||||
resulting in library names like "libmbedtls.so" rather than
|
||||
"libmbedcrypto.so.11".
|
3
ChangeLog.d/programs_psa_fix.txt
Normal file
3
ChangeLog.d/programs_psa_fix.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Bugfix
|
||||
* Fix missing PSA initialization in sample programs when
|
||||
MBEDTLS_USE_PSA_CRYPTO is enabled.
|
@ -1,5 +0,0 @@
|
||||
Removals
|
||||
* Remove compression property from SSL session struct.
|
||||
MBEDTLS_SSL_COMPRESS_NULL is now the only supported
|
||||
compression option and can be used for compatibility
|
||||
reasons. Changes requested in #4223.
|
3
ChangeLog.d/rfc8410.txt
Normal file
3
ChangeLog.d/rfc8410.txt
Normal 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.
|
@ -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.
|
5
ChangeLog.d/tls13-server-version-negotiation.txt
Normal file
5
ChangeLog.d/tls13-server-version-negotiation.txt
Normal 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.
|
2
ChangeLog.d/verify-ip-sans-properly.txt
Normal file
2
ChangeLog.d/verify-ip-sans-properly.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Features
|
||||
* X.509 hostname verification now supports IPAddress Subject Alternate Names.
|
@ -1,5 +0,0 @@
|
||||
Bugfix
|
||||
* Fix handling of broken symlinks when loading certificates using
|
||||
mbedtls_x509_crt_parse_path(). Instead of returning an error as soon as a
|
||||
broken link is encountered, skip the broken link and continue parsing
|
||||
other certificate files. Contributed by Eduardo Silva in #2602.
|
40
Makefile
40
Makefile
@ -4,7 +4,7 @@ PERL ?= perl
|
||||
|
||||
.SILENT:
|
||||
|
||||
.PHONY: all no_test programs lib tests install uninstall clean test check covtest lcov apidoc apidoc_clean
|
||||
.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
|
||||
|
||||
all: programs tests
|
||||
$(MAKE) post_build
|
||||
@ -37,7 +37,7 @@ generated_files: tests/generated_files
|
||||
generated_files: visualc_files
|
||||
|
||||
.PHONY: visualc_files
|
||||
VISUALC_FILES = visualc/VS2010/mbedTLS.sln visualc/VS2010/mbedTLS.vcxproj
|
||||
VISUALC_FILES = visualc/VS2013/mbedTLS.sln visualc/VS2013/mbedTLS.vcxproj
|
||||
# TODO: $(app).vcxproj for each $(app) in programs/
|
||||
visualc_files: $(VISUALC_FILES)
|
||||
|
||||
@ -46,9 +46,9 @@ visualc_files: $(VISUALC_FILES)
|
||||
# they just need to be present.
|
||||
$(VISUALC_FILES): | library/generated_files
|
||||
$(VISUALC_FILES): scripts/generate_visualc_files.pl
|
||||
$(VISUALC_FILES): scripts/data_files/vs2010-app-template.vcxproj
|
||||
$(VISUALC_FILES): scripts/data_files/vs2010-main-template.vcxproj
|
||||
$(VISUALC_FILES): scripts/data_files/vs2010-sln-template.sln
|
||||
$(VISUALC_FILES): scripts/data_files/vs2013-app-template.vcxproj
|
||||
$(VISUALC_FILES): scripts/data_files/vs2013-main-template.vcxproj
|
||||
$(VISUALC_FILES): scripts/data_files/vs2013-sln-template.sln
|
||||
# TODO: also the list of .c and .h source files, but not their content
|
||||
$(VISUALC_FILES):
|
||||
echo " Gen $@ ..."
|
||||
@ -124,10 +124,10 @@ neat: clean_more_on_top
|
||||
$(MAKE) -C programs neat
|
||||
$(MAKE) -C tests neat
|
||||
ifndef WINDOWS
|
||||
rm -f visualc/VS2010/*.vcxproj visualc/VS2010/mbedTLS.sln
|
||||
rm -f visualc/VS2013/*.vcxproj visualc/VS2013/mbedTLS.sln
|
||||
else
|
||||
if exist visualc\VS2010\*.vcxproj del /Q /F visualc\VS2010\*.vcxproj
|
||||
if exist visualc\VS2010\mbedTLS.sln del /Q /F visualc\VS2010\mbedTLS.sln
|
||||
if exist visualc\VS2013\*.vcxproj del /Q /F visualc\VS2013\*.vcxproj
|
||||
if exist visualc\VS2013\mbedTLS.sln del /Q /F visualc\VS2013\mbedTLS.sln
|
||||
endif
|
||||
|
||||
check: lib tests
|
||||
@ -136,23 +136,15 @@ check: lib tests
|
||||
test: check
|
||||
|
||||
ifndef WINDOWS
|
||||
# note: for coverage testing, build with:
|
||||
# make CFLAGS='--coverage -g3 -O0'
|
||||
covtest:
|
||||
$(MAKE) check
|
||||
programs/test/selftest
|
||||
tests/compat.sh
|
||||
tests/ssl-opt.sh
|
||||
|
||||
# For coverage testing:
|
||||
# 1. Build with:
|
||||
# make CFLAGS='--coverage -g3 -O0' LDFLAGS='--coverage'
|
||||
# 2. Run the relevant tests for the part of the code you're interested in.
|
||||
# For the reference coverage measurement, see
|
||||
# tests/scripts/basic-build-test.sh
|
||||
# 3. Run scripts/lcov.sh to generate an HTML report.
|
||||
lcov:
|
||||
rm -rf Coverage
|
||||
lcov --capture --initial --directory library -o files.info
|
||||
lcov --rc lcov_branch_coverage=1 --capture --directory library -o tests.info
|
||||
lcov --rc lcov_branch_coverage=1 --add-tracefile files.info --add-tracefile tests.info -o all.info
|
||||
lcov --rc lcov_branch_coverage=1 --remove all.info -o final.info '*.h'
|
||||
gendesc tests/Descriptions.txt -o descriptions
|
||||
genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --branch-coverage -o Coverage final.info
|
||||
rm -f files.info tests.info all.info final.info descriptions
|
||||
scripts/lcov.sh
|
||||
|
||||
apidoc:
|
||||
mkdir -p apidoc
|
||||
|
41
README.md
41
README.md
@ -17,7 +17,9 @@ We provide some non-standard configurations focused on specific use cases in the
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Documentation for the Mbed TLS interfaces in the default library configuration is available as part of the [Mbed TLS documentation](https://tls.mbed.org/api/).
|
||||
The main Mbed TLS documentation is available via [ReadTheDocs](https://mbed-tls.readthedocs.io/).
|
||||
|
||||
Documentation for the PSA Cryptography API is available [on GitHub](https://arm-software.github.io/psa-api/crypto/).
|
||||
|
||||
To generate a local copy of the library documentation in HTML format, tailored to your compile-time configuration:
|
||||
|
||||
@ -59,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.
|
||||
@ -103,9 +106,9 @@ Setting the variable `SHARED` in your environment will build shared libraries in
|
||||
|
||||
Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -Wextra`), so if you just want to add some warning options to the default ones, you can do so by setting `CFLAGS=-O2 -Werror` for example. Setting `WARNING_CFLAGS` is useful when you want to get rid of its default content (for example because your compiler doesn't accept `-Wall` as an option). Directory-specific options cannot be overridden from the command line.
|
||||
|
||||
Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue.
|
||||
Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://mbed-tls.readthedocs.io/en/latest/kb/) for articles on your platform or issue.
|
||||
|
||||
In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS Knowledge Base](https://tls.mbed.org/kb).
|
||||
In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS Knowledge Base](https://mbed-tls.readthedocs.io/en/latest/kb/).
|
||||
|
||||
### CMake
|
||||
|
||||
@ -218,7 +221,7 @@ subproject.
|
||||
|
||||
### Microsoft Visual Studio
|
||||
|
||||
The build files for Microsoft Visual Studio are generated for Visual Studio 2010.
|
||||
The build files for Microsoft Visual Studio are generated for Visual Studio 2013.
|
||||
|
||||
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need Python and perl environments as well. However, the selftest program in `programs/test/` is still available.
|
||||
|
||||
@ -240,17 +243,19 @@ For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, ad
|
||||
- `tests/ssl-opt.sh` runs integration tests for various TLS options (renegotiation, resumption, etc.) and tests interoperability of these options with other implementations.
|
||||
- `tests/compat.sh` tests interoperability of every ciphersuite with other implementations.
|
||||
- `tests/scripts/test-ref-configs.pl` test builds in various reduced configurations.
|
||||
- `tests/scripts/key-exchanges.pl` test builds in configurations with a single key exchange enabled
|
||||
- `tests/scripts/depends.py` test builds in configurations with a single curve, key exchange, hash, cipher, or pkalg on.
|
||||
- `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `mbedtls_config.h`, etc).
|
||||
|
||||
Instead of manually installing the required versions of all tools required for testing, it is possible to use the Docker images from our CI systems, as explained in [our testing infrastructure repository](https://github.com/Mbed-TLS/mbedtls-test/blob/master/README.md#quick-start).
|
||||
|
||||
Porting Mbed TLS
|
||||
----------------
|
||||
|
||||
Mbed TLS can be ported to many different architectures, OS's and platforms. Before starting a port, you may find the following Knowledge Base articles useful:
|
||||
|
||||
- [Porting Mbed TLS to a new environment or OS](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS)
|
||||
- [What external dependencies does Mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
|
||||
- [How do I configure Mbed TLS](https://tls.mbed.org/kb/compiling-and-building/how-do-i-configure-mbedtls)
|
||||
- [Porting Mbed TLS to a new environment or OS](https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS/)
|
||||
- [What external dependencies does Mbed TLS rely on?](https://mbed-tls.readthedocs.io/en/latest/kb/development/what-external-dependencies-does-mbedtls-rely-on/)
|
||||
- [How do I configure Mbed TLS](https://mbed-tls.readthedocs.io/en/latest/kb/compiling-and-building/how-do-i-configure-mbedtls/)
|
||||
|
||||
Mbed TLS is mostly written in portable C99; however, it has a few platform requirements that go beyond the standard, but are met by most modern architectures:
|
||||
|
||||
@ -259,15 +264,17 @@ Mbed TLS is mostly written in portable C99; however, it has a few platform requi
|
||||
- Signed integers must be represented using two's complement.
|
||||
- `int` and `size_t` must be at least 32 bits wide.
|
||||
- The types `uint8_t`, `uint16_t`, `uint32_t` and their signed equivalents must be available.
|
||||
- Mixed-endian platforms are not supported.
|
||||
- SIZE_MAX must be at least as big as INT_MAX and UINT_MAX.
|
||||
|
||||
PSA cryptography API
|
||||
--------------------
|
||||
|
||||
### PSA API design
|
||||
### PSA API
|
||||
|
||||
Arm's [Platform Security Architecture (PSA)](https://developer.arm.com/architectures/security-architectures/platform-security-architecture) 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 allows security to be consistently designed in, at both a hardware and firmware level.
|
||||
|
||||
The [PSA cryptography API](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) provides access to a set of cryptographic primitives. It has a dual purpose. First, it can be used in a PSA-compliant platform to build services, such as secure boot, secure storage and secure communication. Second, it can also be used independently of other PSA components on any platform.
|
||||
The [PSA cryptography API](https://arm-software.github.io/psa-api/crypto/) provides access to a set of cryptographic primitives. It has a dual purpose. First, it can be used in a PSA-compliant platform to build services, such as secure boot, secure storage and secure communication. Second, it can also be used independently of other PSA components on any platform.
|
||||
|
||||
The design goals of the PSA cryptography API include:
|
||||
|
||||
@ -279,10 +286,6 @@ The design goals of the PSA cryptography API include:
|
||||
|
||||
Arm welcomes feedback on the design of the API. If you think something could be improved, please open an issue on our Github repository. Alternatively, if you prefer to provide your feedback privately, please email us at [`mbed-crypto@arm.com`](mailto:mbed-crypto@arm.com). All feedback received by email is treated confidentially.
|
||||
|
||||
### PSA API documentation
|
||||
|
||||
A browsable copy of the PSA Cryptography API documents is available on the [PSA cryptography interfaces documentation portal](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) in [PDF](https://armmbed.github.io/mbed-crypto/PSA_Cryptography_API_Specification.pdf) and [HTML](https://armmbed.github.io/mbed-crypto/html/index.html) formats.
|
||||
|
||||
### PSA implementation in Mbed TLS
|
||||
|
||||
Mbed TLS includes a reference implementation of the PSA Cryptography API.
|
||||
@ -304,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
|
||||
------------
|
||||
|
||||
|
117
SECURITY.md
117
SECURITY.md
@ -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,10 +2,11 @@
|
||||
|
||||
Here are some useful sources of information about using Mbed TLS:
|
||||
|
||||
- [ReadTheDocs](https://mbed-tls.readthedocs.io/);
|
||||
- API documentation, see the [Documentation section of the
|
||||
README](README.md#License);
|
||||
README](README.md#documentation);
|
||||
- the `docs` directory in the source tree;
|
||||
- the [Mbed TLS knowledge Base](https://tls.mbed.org/kb);
|
||||
- the [Mbed TLS Knowledge Base](https://mbed-tls.readthedocs.io/en/latest/kb/);
|
||||
- the [Mbed TLS mailing-list
|
||||
archives](https://lists.trustedfirmware.org/archives/list/mbed-tls@lists.trustedfirmware.org/).
|
||||
|
||||
|
@ -47,10 +47,6 @@
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NET_C
|
||||
/* The library does not currently support enabling SHA-224 without SHA-256.
|
||||
* A future version of the library will have this option disabled
|
||||
* by default. */
|
||||
#define MBEDTLS_SHA224_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_COOKIE_C
|
||||
@ -73,8 +69,8 @@
|
||||
* save ROM and a few bytes of RAM by specifying our own ciphersuite list
|
||||
*/
|
||||
#define MBEDTLS_SSL_CIPHERSUITES \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
|
||||
|
||||
/*
|
||||
* Save RAM at the expense of interoperability: do this only if you control
|
||||
|
@ -46,10 +46,6 @@
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NET_C
|
||||
/* The library does not currently support enabling SHA-224 without SHA-256.
|
||||
* A future version of the library will have this option disabled
|
||||
* by default. */
|
||||
#define MBEDTLS_SHA224_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
@ -64,8 +60,8 @@
|
||||
* save ROM and a few bytes of RAM by specifying our own ciphersuite list
|
||||
*/
|
||||
#define MBEDTLS_SSL_CIPHERSUITES \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
|
||||
|
||||
/*
|
||||
* Save RAM at the expense of interoperability: do this only if you control
|
||||
|
@ -60,10 +60,6 @@
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
/* The library does not currently support enabling SHA-224 without SHA-256.
|
||||
* A future version of the library will have this option disabled
|
||||
* by default. */
|
||||
#define MBEDTLS_SHA224_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SHA384_C
|
||||
#define MBEDTLS_SHA512_C
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define MBEDTLS_HAVE_TIME
|
||||
#define MBEDTLS_HAVE_TIME_DATE
|
||||
|
||||
/* Mbed Crypto feature support */
|
||||
/* Mbed TLS feature support */
|
||||
#define MBEDTLS_CIPHER_MODE_CBC
|
||||
#define MBEDTLS_CIPHER_MODE_CFB
|
||||
#define MBEDTLS_CIPHER_MODE_CTR
|
||||
@ -42,7 +42,7 @@
|
||||
#define MBEDTLS_USE_PSA_CRYPTO
|
||||
#define MBEDTLS_VERSION_FEATURES
|
||||
|
||||
/* Mbed Crypto modules */
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
|
@ -63,10 +63,6 @@
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
/* The library does not currently support enabling SHA-224 without SHA-256.
|
||||
* A future version of the library will have this option disabled
|
||||
* by default. */
|
||||
#define MBEDTLS_SHA224_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_COOKIE_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
|
115
configs/crypto_config_profile_medium.h
Normal file
115
configs/crypto_config_profile_medium.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file psa/crypto_config.h
|
||||
* \brief PSA crypto configuration options (set of defines)
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||
/**
|
||||
* When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h,
|
||||
* this file determines which cryptographic mechanisms are enabled
|
||||
* through the PSA Cryptography API (\c psa_xxx() functions).
|
||||
*
|
||||
* To enable a cryptographic mechanism, uncomment the definition of
|
||||
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
|
||||
* To disable a cryptographic mechanism, comment out the definition of
|
||||
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
|
||||
* The names of cryptographic mechanisms correspond to values
|
||||
* defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead
|
||||
* of \c PSA_.
|
||||
*
|
||||
* Note that many cryptographic mechanisms involve two symbols: one for
|
||||
* the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm
|
||||
* (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve
|
||||
* additional symbols.
|
||||
*/
|
||||
#else
|
||||
/**
|
||||
* When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h,
|
||||
* this file is not used, and cryptographic mechanisms are supported
|
||||
* through the PSA API if and only if they are supported through the
|
||||
* mbedtls_xxx API.
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef PROFILE_M_PSA_CRYPTO_CONFIG_H
|
||||
#define PROFILE_M_PSA_CRYPTO_CONFIG_H
|
||||
|
||||
/*
|
||||
* CBC-MAC is not yet supported via the PSA API in Mbed TLS.
|
||||
*/
|
||||
//#define PSA_WANT_ALG_CBC_MAC 1
|
||||
//#define PSA_WANT_ALG_CBC_NO_PADDING 1
|
||||
//#define PSA_WANT_ALG_CBC_PKCS7 1
|
||||
#define PSA_WANT_ALG_CCM 1
|
||||
//#define PSA_WANT_ALG_CMAC 1
|
||||
//#define PSA_WANT_ALG_CFB 1
|
||||
//#define PSA_WANT_ALG_CHACHA20_POLY1305 1
|
||||
//#define PSA_WANT_ALG_CTR 1
|
||||
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
//#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECDH 1
|
||||
#define PSA_WANT_ALG_ECDSA 1
|
||||
//#define PSA_WANT_ALG_GCM 1
|
||||
#define PSA_WANT_ALG_HKDF 1
|
||||
#define PSA_WANT_ALG_HMAC 1
|
||||
//#define PSA_WANT_ALG_MD5 1
|
||||
//#define PSA_WANT_ALG_OFB 1
|
||||
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
|
||||
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
|
||||
//#define PSA_WANT_ALG_PBKDF2_HMAC 1
|
||||
//#define PSA_WANT_ALG_RIPEMD160 1
|
||||
//#define PSA_WANT_ALG_RSA_OAEP 1
|
||||
//#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
|
||||
//#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
|
||||
//#define PSA_WANT_ALG_RSA_PSS 1
|
||||
//#define PSA_WANT_ALG_SHA_1 1
|
||||
#define PSA_WANT_ALG_SHA_224 1
|
||||
#define PSA_WANT_ALG_SHA_256 1
|
||||
//#define PSA_WANT_ALG_SHA_384 1
|
||||
//#define PSA_WANT_ALG_SHA_512 1
|
||||
//#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||
#define PSA_WANT_ALG_TLS12_PRF 1
|
||||
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
|
||||
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
|
||||
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
|
||||
//#define PSA_WANT_ALG_XTS 1
|
||||
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
|
||||
//#define PSA_WANT_ECC_MONTGOMERY_255 1
|
||||
//#define PSA_WANT_ECC_MONTGOMERY_448 1
|
||||
//#define PSA_WANT_ECC_SECP_K1_192 1
|
||||
/*
|
||||
* SECP224K1 is buggy via the PSA API in Mbed TLS
|
||||
* (https://github.com/Mbed-TLS/mbedtls/issues/3541). Thus, do not enable it by
|
||||
* default.
|
||||
*/
|
||||
//#define PSA_WANT_ECC_SECP_K1_224 1
|
||||
//#define PSA_WANT_ECC_SECP_K1_256 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_192 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_224 1
|
||||
#define PSA_WANT_ECC_SECP_R1_256 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_384 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_521 1
|
||||
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_HMAC 1
|
||||
#define PSA_WANT_KEY_TYPE_AES 1
|
||||
//#define PSA_WANT_KEY_TYPE_ARIA 1
|
||||
//#define PSA_WANT_KEY_TYPE_CAMELLIA 1
|
||||
//#define PSA_WANT_KEY_TYPE_CHACHA20 1
|
||||
//#define PSA_WANT_KEY_TYPE_DES 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
|
||||
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */
|
629
configs/tfm_mbedcrypto_config_profile_medium.h
Normal file
629
configs/tfm_mbedcrypto_config_profile_medium.h
Normal file
@ -0,0 +1,629 @@
|
||||
/**
|
||||
* \file config.h
|
||||
*
|
||||
* \brief Configuration options (set of defines)
|
||||
*
|
||||
* This set of compile-time options may be used to enable
|
||||
* or disable features selectively, and reduce the global
|
||||
* memory footprint.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2022, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_M_MBEDTLS_CONFIG_H
|
||||
#define PROFILE_M_MBEDTLS_CONFIG_H
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: System support
|
||||
*
|
||||
* This section sets system specific settings.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HAVE_ASM
|
||||
*
|
||||
* The compiler has support for asm().
|
||||
*
|
||||
* Requires support for asm() in compiler.
|
||||
*
|
||||
* Used in:
|
||||
* library/aria.c
|
||||
* library/timing.c
|
||||
* include/mbedtls/bn_mul.h
|
||||
*
|
||||
* Required by:
|
||||
* MBEDTLS_AESNI_C
|
||||
* MBEDTLS_PADLOCK_C
|
||||
*
|
||||
* Comment to disable the use of assembly code.
|
||||
*/
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PLATFORM_MEMORY
|
||||
*
|
||||
* Enable the memory allocation layer.
|
||||
*
|
||||
* By default mbed TLS uses the system-provided calloc() and free().
|
||||
* This allows different allocators (self-implemented or provided) to be
|
||||
* provided to the platform abstraction layer.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY without the
|
||||
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
|
||||
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
|
||||
* free() function pointer at runtime.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
|
||||
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
|
||||
* alternate function at compile time.
|
||||
*
|
||||
* Requires: MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* Enable this layer to allow use of alternative memory allocators.
|
||||
*/
|
||||
#define MBEDTLS_PLATFORM_MEMORY
|
||||
|
||||
/* \} name SECTION: System support */
|
||||
|
||||
/**
|
||||
* \name SECTION: mbed TLS feature support
|
||||
*
|
||||
* This section sets support for features that are or are not needed
|
||||
* within the modules that are enabled.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MD2_PROCESS_ALT
|
||||
*
|
||||
* MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
|
||||
* alternate core implementation of symmetric crypto or hash function. Keep in
|
||||
* mind that function prototypes should remain the same.
|
||||
*
|
||||
* This replaces only one function. The header file from mbed TLS is still
|
||||
* used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
|
||||
*
|
||||
* Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
|
||||
* no longer provide the mbedtls_sha1_process() function, but it will still provide
|
||||
* the other function (using your mbedtls_sha1_process() function) and the definition
|
||||
* of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
|
||||
* with this definition.
|
||||
*
|
||||
* \note Because of a signature change, the core AES encryption and decryption routines are
|
||||
* currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
|
||||
* respectively. When setting up alternative implementations, these functions should
|
||||
* be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
|
||||
* must stay untouched.
|
||||
*
|
||||
* \note If you use the AES_xxx_ALT macros, then is is recommended to also set
|
||||
* MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
|
||||
* tables.
|
||||
*
|
||||
* Uncomment a macro to enable alternate implementation of the corresponding
|
||||
* function.
|
||||
*
|
||||
* \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
|
||||
* constitutes a security risk. If possible, we recommend avoiding
|
||||
* dependencies on them, and considering stronger message digests
|
||||
* and ciphers instead.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_SETKEY_DEC_ALT
|
||||
#define MBEDTLS_AES_DECRYPT_ALT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ROM_TABLES
|
||||
*
|
||||
* Use precomputed AES tables stored in ROM.
|
||||
*
|
||||
* Uncomment this macro to use precomputed AES tables stored in ROM.
|
||||
* Comment this macro to generate AES tables in RAM at runtime.
|
||||
*
|
||||
* Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
|
||||
* (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
|
||||
* initialization time before the first AES operation can be performed.
|
||||
* It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
|
||||
* MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
|
||||
* performance if ROM access is slower than RAM access.
|
||||
*
|
||||
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_FEWER_TABLES
|
||||
*
|
||||
* Use less ROM/RAM for AES tables.
|
||||
*
|
||||
* Uncommenting this macro omits 75% of the AES tables from
|
||||
* ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
|
||||
* by computing their values on the fly during operations
|
||||
* (the tables are entry-wise rotations of one another).
|
||||
*
|
||||
* Tradeoff: Uncommenting this reduces the RAM / ROM footprint
|
||||
* by ~6kb but at the cost of more arithmetic operations during
|
||||
* runtime. Specifically, one has to compare 4 accesses within
|
||||
* different tables to 4 accesses with additional arithmetic
|
||||
* operations within the same table. The performance gain/loss
|
||||
* depends on the system and memory details.
|
||||
*
|
||||
* This option is independent of \c MBEDTLS_AES_ROM_TABLES.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_FEWER_TABLES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECP_NIST_OPTIM
|
||||
*
|
||||
* Enable specific 'modulo p' routines for each NIST prime.
|
||||
* Depending on the prime and architecture, makes operations 4 to 8 times
|
||||
* faster on the corresponding curve.
|
||||
*
|
||||
* Comment this macro to disable NIST curves optimisation.
|
||||
*/
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ERROR_STRERROR_DUMMY
|
||||
*
|
||||
* Enable a dummy error function to make use of mbedtls_strerror() in
|
||||
* third party libraries easier when MBEDTLS_ERROR_C is disabled
|
||||
* (no effect when MBEDTLS_ERROR_C is enabled).
|
||||
*
|
||||
* You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
|
||||
* not using mbedtls_strerror() or error_strerror() in your application.
|
||||
*
|
||||
* Disable if you run into name conflicts and want to really remove the
|
||||
* mbedtls_strerror()
|
||||
*/
|
||||
#define MBEDTLS_ERROR_STRERROR_DUMMY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
*
|
||||
* Do not use built-in platform entropy functions.
|
||||
* This is useful if your platform does not support
|
||||
* standards like the /dev/urandom or Windows CryptoAPI.
|
||||
*
|
||||
* Uncomment this macro to disable the built-in platform entropy functions.
|
||||
*/
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_NV_SEED
|
||||
*
|
||||
* Enable the non-volatile (NV) seed file-based entropy source.
|
||||
* (Also enables the NV seed read/write functions in the platform layer)
|
||||
*
|
||||
* This is crucial (if not required) on systems that do not have a
|
||||
* cryptographic entropy source (in hardware or kernel) available.
|
||||
*
|
||||
* Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* \note The read/write functions that are used by the entropy source are
|
||||
* determined in the platform layer, and can be modified at runtime and/or
|
||||
* compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
|
||||
*
|
||||
* \note If you use the default implementation functions that read a seedfile
|
||||
* with regular fopen(), please make sure you make a seedfile with the
|
||||
* proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
|
||||
* least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
|
||||
* and written to or you will get an entropy source error! The default
|
||||
* implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
|
||||
* bytes from the file.
|
||||
*
|
||||
* \note The entropy collector will write to the seed file before entropy is
|
||||
* given to an external source, to update it.
|
||||
*/
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
//#define MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
*
|
||||
* Enable key identifiers that encode a key owner identifier.
|
||||
*
|
||||
* This is only meaningful when building the library as part of a
|
||||
* multi-client service. When you activate this option, you must provide an
|
||||
* implementation of the type mbedtls_key_owner_id_t and a translation from
|
||||
* mbedtls_svc_key_id_t to file name in all the storage backends that you
|
||||
* you wish to support.
|
||||
*
|
||||
* Note that while this define has been removed from TF-M's copy of this config
|
||||
* file, TF-M still passes this option to Mbed TLS during the build via CMake.
|
||||
* Therefore we keep it in our copy. See discussion on PR #7426 for more info.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_SPM
|
||||
*
|
||||
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
|
||||
* Partition Manager) integration which separates the code into two parts: a
|
||||
* NSPE (Non-Secure Process Environment) and an SPE (Secure Process
|
||||
* Environment).
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_SPM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_SMALLER
|
||||
*
|
||||
* Enable an implementation of SHA-256 that has lower ROM footprint but also
|
||||
* lower performance.
|
||||
*
|
||||
* The default implementation is meant to be a reasonnable compromise between
|
||||
* performance and size. This version optimizes more aggressively for size at
|
||||
* the expense of performance. Eg on Cortex-M4 it reduces the size of
|
||||
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
|
||||
* 30%.
|
||||
*
|
||||
* Uncomment to enable the smaller implementation of SHA256.
|
||||
*/
|
||||
#define MBEDTLS_SHA256_SMALLER
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
*
|
||||
* This setting allows support for cryptographic mechanisms through the PSA
|
||||
* API to be configured separately from support through the mbedtls API.
|
||||
*
|
||||
* When this option is disabled, the PSA API exposes the cryptographic
|
||||
* mechanisms that can be implemented on top of the `mbedtls_xxx` API
|
||||
* configured with `MBEDTLS_XXX` symbols.
|
||||
*
|
||||
* When this option is enabled, the PSA API exposes the cryptographic
|
||||
* mechanisms requested by the `PSA_WANT_XXX` symbols defined in
|
||||
* include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are
|
||||
* automatically enabled if required (i.e. if no PSA driver provides the
|
||||
* mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols
|
||||
* in mbedtls_config.h.
|
||||
*
|
||||
* If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
|
||||
* an alternative header to include instead of include/psa/crypto_config.h.
|
||||
*
|
||||
* This feature is still experimental and is not ready for production since
|
||||
* it is not completed.
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
|
||||
/* \} name SECTION: mbed TLS feature support */
|
||||
|
||||
/**
|
||||
* \name SECTION: mbed TLS modules
|
||||
*
|
||||
* This section enables or disables entire modules in mbed TLS
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_C
|
||||
*
|
||||
* Enable the AES block cipher.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
* Caller: library/cipher.c
|
||||
* library/pem.c
|
||||
* library/ctr_drbg.c
|
||||
*
|
||||
* This module is required to support the TLS ciphersuites that use the AES
|
||||
* cipher.
|
||||
*
|
||||
* PEM_PARSE uses AES for decrypting encrypted keys.
|
||||
*/
|
||||
#define MBEDTLS_AES_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CIPHER_C
|
||||
*
|
||||
* Enable the generic cipher layer.
|
||||
*
|
||||
* Module: library/cipher.c
|
||||
*
|
||||
* Uncomment to enable generic cipher wrappers.
|
||||
*/
|
||||
#define MBEDTLS_CIPHER_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CTR_DRBG_C
|
||||
*
|
||||
* Enable the CTR_DRBG AES-based random generator.
|
||||
* The CTR_DRBG generator uses AES-256 by default.
|
||||
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
|
||||
*
|
||||
* Module: library/ctr_drbg.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_AES_C
|
||||
*
|
||||
* This module provides the CTR_DRBG AES random number generator.
|
||||
*/
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_C
|
||||
*
|
||||
* Enable the platform-specific entropy code.
|
||||
*
|
||||
* Module: library/entropy.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
|
||||
*
|
||||
* This module provides a generic entropy pool
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ERROR_C
|
||||
*
|
||||
* Enable error code to error string conversion.
|
||||
*
|
||||
* Module: library/error.c
|
||||
* Caller:
|
||||
*
|
||||
* This module enables mbedtls_strerror().
|
||||
*/
|
||||
#define MBEDTLS_ERROR_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HKDF_C
|
||||
*
|
||||
* Enable the HKDF algorithm (RFC 5869).
|
||||
*
|
||||
* Module: library/hkdf.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_MD_C
|
||||
*
|
||||
* This module adds support for the Hashed Message Authentication Code
|
||||
* (HMAC)-based key derivation function (HKDF).
|
||||
*/
|
||||
#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
*
|
||||
* Enable the buffer allocator implementation that makes use of a (stack)
|
||||
* based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
|
||||
* calls)
|
||||
*
|
||||
* Module: library/memory_buffer_alloc.c
|
||||
*
|
||||
* Requires: MBEDTLS_PLATFORM_C
|
||||
* MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
|
||||
*
|
||||
* Enable this module to enable the buffer memory allocator.
|
||||
*/
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_C
|
||||
*
|
||||
* Enable the generic public (asymetric) key layer.
|
||||
*
|
||||
* Module: library/pk.c
|
||||
*
|
||||
* Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
|
||||
*
|
||||
* Uncomment to enable generic public key wrappers.
|
||||
*/
|
||||
#define MBEDTLS_PK_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_PARSE_C
|
||||
*
|
||||
* Enable the generic public (asymetric) key parser.
|
||||
*
|
||||
* Module: library/pkparse.c
|
||||
*
|
||||
* Requires: MBEDTLS_PK_C
|
||||
*
|
||||
* Uncomment to enable generic public key parse functions.
|
||||
*/
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_WRITE_C
|
||||
*
|
||||
* Enable the generic public (asymetric) key writer.
|
||||
*
|
||||
* Module: library/pkwrite.c
|
||||
*
|
||||
* Requires: MBEDTLS_PK_C
|
||||
*
|
||||
* Uncomment to enable generic public key write functions.
|
||||
*/
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* Enable the platform abstraction layer that allows you to re-assign
|
||||
* functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
|
||||
* or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
|
||||
* above to be specified at runtime or compile time respectively.
|
||||
*
|
||||
* \note This abstraction layer must be enabled on Windows (including MSYS2)
|
||||
* as other module rely on it for a fixed snprintf implementation.
|
||||
*
|
||||
* Module: library/platform.c
|
||||
* Caller: Most other .c files
|
||||
*
|
||||
* This module enables abstraction of common (libc) functions.
|
||||
*/
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
* Enable the Platform Security Architecture cryptography API.
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
*
|
||||
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
*
|
||||
* Enable the Platform Security Architecture persistent key storage.
|
||||
*
|
||||
* Module: library/psa_crypto_storage.c
|
||||
*
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C,
|
||||
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
|
||||
* the PSA ITS interface
|
||||
*/
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
||||
/* \} name SECTION: mbed TLS modules */
|
||||
|
||||
/**
|
||||
* \name SECTION: General configuration options
|
||||
*
|
||||
* This section contains Mbed TLS build settings that are not associated
|
||||
* with a particular module.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included instead of
|
||||
* `"mbedtls/mbedtls_config.h"`.
|
||||
* This header file specifies the compile-time configuration of Mbed TLS.
|
||||
* Unlike other configuration options, this one must be defined on the
|
||||
* compiler command line: a definition in `mbedtls_config.h` would have
|
||||
* no effect.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_USER_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included after
|
||||
* `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE.
|
||||
* This allows you to modify the default configuration, including the ability
|
||||
* to undefine options that are enabled by default.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_USER_CONFIG_FILE "/dev/null"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included instead of
|
||||
* `"psa/crypto_config.h"`.
|
||||
* This header file specifies which cryptographic mechanisms are available
|
||||
* through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and
|
||||
* is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included after
|
||||
* `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE.
|
||||
* This allows you to modify the default configuration, including the ability
|
||||
* to undefine options that are enabled by default.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
|
||||
|
||||
/** \} name SECTION: General configuration options */
|
||||
|
||||
/**
|
||||
* \name SECTION: Module configuration options
|
||||
*
|
||||
* This section allows for the setting of module specific sizes and
|
||||
* configuration options. The default values are already present in the
|
||||
* relevant header files and should suffice for the regular use cases.
|
||||
*
|
||||
* Our advice is to enable options and change their values here
|
||||
* only if you have a good reason and know the consequences.
|
||||
*
|
||||
* Please check the respective header file for documentation on these
|
||||
* parameters (to prevent duplicate documentation).
|
||||
* \{
|
||||
*/
|
||||
|
||||
/* ECP options */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Disable fixed-point speed-up */
|
||||
|
||||
/* \} name SECTION: Customisation configuration options */
|
||||
|
||||
#if CRYPTO_NV_SEED
|
||||
#include "tfm_mbedcrypto_config_extra_nv_seed.h"
|
||||
#endif /* CRYPTO_NV_SEED */
|
||||
|
||||
#if !defined(CRYPTO_HW_ACCELERATOR) && defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#include "mbedtls_entropy_nv_seed_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
#include "mbedtls_accelerator_config.h"
|
||||
#endif
|
||||
|
||||
#endif /* PROFILE_M_MBEDTLS_CONFIG_H */
|
2
docs/.gitignore
vendored
2
docs/.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
*.html
|
||||
*.pdf
|
||||
_build/
|
||||
api/
|
||||
|
@ -141,7 +141,7 @@ recommended), or users who used it through the entropy module but had it as the
|
||||
only source of entropy. If you're in that case, please declare OS or hardware
|
||||
RNG interfaces with `mbedtls_entropy_add_source()` and/or use an entropy seed
|
||||
file created securely during device provisioning. See
|
||||
<https://tls.mbed.org/kb/how-to/add-entropy-sources-to-entropy-pool> for more
|
||||
<https://mbed-tls.readthedocs.io/en/latest/kb/how-to/add-entropy-sources-to-entropy-pool> for more
|
||||
information.
|
||||
|
||||
### Remove helpers for the transition from Mbed TLS 1.3 to Mbed TLS 2.0
|
||||
|
40
docs/Makefile
Normal file
40
docs/Makefile
Normal 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)
|
@ -3,10 +3,18 @@ PANDOC = pandoc
|
||||
default: all
|
||||
|
||||
all_markdown = \
|
||||
mbed-crypto-storage-specification.md \
|
||||
testing/driver-interface-test-strategy.md \
|
||||
testing/invasive-testing.md \
|
||||
testing/test-framework.md \
|
||||
alternative-implementations.md \
|
||||
mbed-crypto-storage-specification.md \
|
||||
psa-crypto-implementation-structure.md \
|
||||
psa-migration/psa-limitations.md \
|
||||
psa-migration/strategy.md \
|
||||
psa-migration/tasks-g2.md \
|
||||
psa-migration/testing.md \
|
||||
testing/driver-interface-test-strategy.md \
|
||||
testing/invasive-testing.md \
|
||||
testing/psa-storage-format-testing.md \
|
||||
testing/test-framework.md \
|
||||
tls13-support.md \
|
||||
# This line is intentionally left blank
|
||||
|
||||
html: $(all_markdown:.md=.html)
|
||||
|
@ -38,7 +38,7 @@ The general principle of an alternative implementation is:
|
||||
* Create a header file `xxx_alt.h` that defines the context type(s) used by the module. For example, `mbedtls_aes_context` for AES.
|
||||
* Implement all the functions from the module, i.e. the functions declared in `include/mbedtls/xxx.h`.
|
||||
|
||||
See https://tls.mbed.org/kb/development/hw_acc_guidelines for a more detailed guide.
|
||||
See https://mbed-tls.readthedocs.io/en/latest/kb/development/hw_acc_guidelines for a more detailed guide.
|
||||
|
||||
### Constraints on context types
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
Mbed Crypto storage specification
|
||||
Mbed TLS storage specification
|
||||
=================================
|
||||
|
||||
This document specifies how Mbed Crypto uses storage.
|
||||
This document specifies how Mbed TLS uses storage.
|
||||
Key storage was originally introduced in a product called Mbed Crypto, which was re-distributed via Mbed TLS and has since been merged into Mbed TLS.
|
||||
This document contains historical information both from before and after this merge.
|
||||
|
||||
Mbed Crypto may be upgraded on an existing device with the storage preserved. Therefore:
|
||||
|
||||
@ -354,7 +356,7 @@ Supported features:
|
||||
|
||||
* [Persistent keys](#key-file-format-for-mbed-tls-2.25.0) designated by a [key identifier and owner](#key-names-for-mbed-tls-2.25.0). Keys can be:
|
||||
* Transparent, stored in the export format.
|
||||
* Opaque, using the unified driver interface with statically registered drivers (`MBEDTLS_PSA_CRYPTO_DRIVERS`). The driver determines the content of the opaque key blob.
|
||||
* Opaque, using the PSA driver interface with statically registered drivers. The driver determines the content of the opaque key blob.
|
||||
* Opaque, using the deprecated secure element interface with dynamically registered drivers (`MBEDTLS_PSA_CRYPTO_SE_C`). The driver picks a slot number which is stored in the place of the key material.
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0) on ITS only.
|
||||
|
||||
|
@ -71,3 +71,105 @@ In case of any error occurring at step 3 or 4, psa_fail_key_creation() is called
|
||||
A driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software.
|
||||
|
||||
An Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa_<driver name>_<entry point>(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the "import_key" entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key().
|
||||
|
||||
## How to implement a new cryptographic mechanism
|
||||
|
||||
Summary of files to modify when adding a new algorithm or key type:
|
||||
|
||||
* [ ] PSA Crypto API draft, if not already done — [PSA standardization](#psa-standardization)
|
||||
* [ ] `include/psa/crypto_values.h` or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `include/psa/crypto_config.h`, `tests/include/test/drivers/crypto_config_test_driver_extension.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* Occasionally `library/check_crypto_config.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `include/mbedtls/config_psa.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `library/psa_crypto.c`, `library/psa_crypto_*.[hc]` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] `include/psa/crypto_builtin_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto_metadata.data` — [New functions and macros](#new-functions-and-macros)
|
||||
* (If adding `PSA_IS_xxx`) `tests/suites/test_suite_psa_crypto_metadata.function` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto*.data`, `tests/suites/test_suite_psa_crypto*.function` — [Unit tests](#unit-tests)
|
||||
* [ ] `scripts/mbedtls_dev/crypto_knowledge.py`, `scripts/mbedtls_dev/asymmetric_key_data.py` — [Unit tests](#unit-tests)
|
||||
* [ ] `ChangeLog.d/*.txt` — changelog entry
|
||||
|
||||
Summary of files to modify when adding new API functions:
|
||||
|
||||
* [ ] `include/psa/crypto.h` and `include/psa/crypto_sizes.h`, or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `library/psa_crypto.c`, `scripts/data_files/driver_templates/*.jinja` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] If adding stateful functions: `include/psa/crypto_struct.h`, `include/psa/crypto_builtin_*.h`, `include/psa/crypto_driver_contexts_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto.data`, `tests/suites/test_suite_psa_crypto.function`, `tests/suites/test_suite_psa_crypto_driver_wrappers.*` — [Unit tests](#unit-tests)
|
||||
|
||||
Note that this is just a basic guide. In some cases, you won't need to change all the files listed here. In some cases, you may need to change other files.
|
||||
|
||||
### PSA standardization
|
||||
|
||||
Typically, if there's enough demand for a cryptographic mechanism in Mbed TLS, there's enough demand for it to be part of the official PSA Cryptography specification. Therefore the first step before implementing a new mechanism should be to approach the PSA Cryptography working group in Arm for standardization.
|
||||
|
||||
At the time of writing, all cryptographic mechanisms that are accessible through `psa_xxx` APIs in in Mbed TLS are current or upcoming PSA standards. Mbed TLS implements some extensions to the PSA API that offer extra integration customization or extra key policies.
|
||||
|
||||
Mbed TLS routinely implements cryptographic mechanisms that are not yet part of a published PSA standard, but that are scheduled to be part of a future version of the standard. The Mbed TLS implementation validates the feasibility of the upcoming PSA standard. The PSA Cryptography working group and the Mbed TLS development team communicate during the elaboration of the new interfaces.
|
||||
|
||||
### New functions and macros
|
||||
|
||||
If a mechanism requires new functions, they should follow the design guidelines in the PSA Cryptography API specification.
|
||||
|
||||
Functions that are part of the current or upcoming API are declared in `include/psa/crypto.h`, apart from structure accessors defined in `include/psa/crypto_struct.h`. Functions that have output buffers have associated sufficient-output-size macros in `include/psa/crypto_sizes.h`.
|
||||
|
||||
Constants (algorithm identifiers, key type identifiers, etc.) and associated destructor macros (e.g. `PSA_IS_xxx()`) are defined in `include/psa/crypto_values.h`.
|
||||
|
||||
Functions and macros that are not intended for standardization, or that are at a stage where the draft standard might still evolve significantly, are declared in `include/psa/crypto_extra.h`.
|
||||
|
||||
The PSA Cryptography API specification defines both names and values for certain kinds of constants: algorithms (`PSA_ALG_xxx`), key types (`PSA_KEY_TYPE_xxx`), ECC curve families (`PSA_ECC_FAMILY_xxx`), DH group families (`PSA_DH_FAMILY_xxx`). If Mbed TLS defines an algorithm or a key type that is not part of a current or upcoming PSA standard, pick a value with the `VENDOR` flag set. If Mbed TLS defines an ECC curve or DH group family that is not part of a current or upcoming PSA standard, define a vendor key type and use the family identifier only with this vendor key type.
|
||||
|
||||
New constants must have a test case in `tests/suites/test_suite_psa_crypto_metadata.data` that verifies that `PSA_IS_xxx` macros behave properly with the new constant. New `PSA_IS_xxx` macros must be declared in `tests/suites/test_suite_psa_crypto_metadata.function`.
|
||||
|
||||
### Preprocessor symbols
|
||||
|
||||
Each cryptographic mechanism is optional and can be selected by the application at build time. For each feature `PSA_ttt_xxx`:
|
||||
|
||||
* The feature is available to applications when the preprocessor symbol `PSA_WANT_ttt_xxx` is defined. These symbols are set:
|
||||
* If `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled: based on the available mechanisms in Mbed TLS, deduced from `mbedtls/mbedtls_config.h` by code in `include/mbedtls/config_psa.h`.
|
||||
* if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled: in the application configuration file `include/psa/crypto_config.h` (or `MBEDTLS_PSA_CRYPTO_CONFIG_FILE`, plus `MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`), with code in `include/mbedtls/config_psa.h` deducing the necessary underlying `MBEDTLS_xxx` symbols.
|
||||
* For transparent keys (keys that are not in a secure element), the feature is implemented by Mbed TLS if `MBEDTLS_PSA_BUILTIN_ttt_xxx` is defined, and by an accelerator driver if `MBEDTLS_PSA_ACCEL_ttt_xxx` is defined. `MBEDTLS_PSA_BUILTIN_ttt_xxx` constants are set in `include/mbedtls/config_psa.h` based on the application requests `PSA_WANT_ttt_xxx` and the accelerator driver declarations `MBEDTLS_PSA_ACCEL_ttt_xxx`.
|
||||
* For the testing of the driver dispatch code, `tests/include/test/drivers/crypto_config_test_driver_extension.h` sets additional `MBEDTLS_PSA_ACCEL_xxx` symbols.
|
||||
|
||||
For more details, see *[Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](../proposed/psa-conditional-inclusion-c.html)*.
|
||||
|
||||
Some mechanisms require other mechanisms. For example, you can't do GCM without a block cipher, or RSA-PSS without RSA keys. When mechanism A requires mechanism B, `include/mbedtls/config_psa.h` ensures that B is enabled whenever A is enabled. When mechanism A requires at least one of a set {B1, B2, B3, ...} but there is no particular reason why enabling A would enable any of the specific Bi's, it's up to the application to choose Bi's and the file `library/check_crypto_config.h` contains compile-time constraints to ensure that at least one Bi is enabled.
|
||||
|
||||
### Implementation of the mechanisms
|
||||
|
||||
The general structure of a cryptographic operation function is:
|
||||
|
||||
1. API function defined in `library/psa_crypto.c`. The entry point performs generic checks that don't depend on whether the mechanism is implemented in software or in a driver and looks up keys in the key store.
|
||||
2. Driver dispatch code in `scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja` or files included from there.
|
||||
3. Built-in implementation in `library/psa_crypto_*.c` (with function declarations in the corresponding `.h` file). These files typically contain the implementation of modes of operation over basic building blocks that are defined elsewhere. For example, HMAC is implemented in `library/psa_crypto_mac.c` but the underlying hash functions are implemented in `library/sha*.c` and `library/md*.c`.
|
||||
4. Basic cryptographic building blocks in `library/*.c`.
|
||||
|
||||
When implementing a new algorithm or key type, there are typically things to change in `library/crypto.c` (e.g. buffer size calculations, algorithm/key-type compatibility) and in the built-in implementation, but not in the driver dispatch code.
|
||||
|
||||
### Translucent data structures
|
||||
|
||||
Some mechanisms require state to be kept between function calls. Keys and key-like data is kept in the key store, which PSA manages internally. Other state, for example the state of multipart operations, is kept in structures allocated by the caller.
|
||||
|
||||
The size of operation structures needs to be known at compile time, since callers may allocate them on the stack. Therefore these structures are defined in a public header: `include/psa/crypto_struct.h` for the parts that are independent of the underlying implementation, `include/psa/crypto_builtin_*` for parts that are specific to the Mbed TLS built-in implementation, `include/psa/crypto_driver_*.h` for structures implemented by drivers.
|
||||
|
||||
### Unit tests
|
||||
|
||||
A number of unit tests are automatically generated by `tests/scripts/generate_psa_tests.py` based on the algorithms and key types declared in `include/psa/crypto_values.h` and `include/psa/crypto_extra.h`:
|
||||
|
||||
* Attempt to create a key with a key type that is not supported.
|
||||
* Attempt to perform an operation with a combination of key type and algorithm that is not valid or not supported.
|
||||
* Storage and retrieval of a persistent key.
|
||||
|
||||
When adding a new key type or algorithm:
|
||||
|
||||
* `scripts/mbedtls_dev/crypto_knowledge.py` contains knowledge about the compatibility of key types, key sizes and algorithms.
|
||||
* `scripts/mbedtls_dev/asymmetric_key_data.py` contains valid key data for asymmetric key types.
|
||||
|
||||
Other things need to be tested manually, either in `tests/suites/test_sutie_psa_crypto.data` or in another file. For example (this is not an exhaustive list):
|
||||
|
||||
* Known answer tests.
|
||||
* Potential edge cases (e.g. data less/equal/more than the block size, number equal to zero in asymmetric cryptography).
|
||||
* Tests with invalid keys (e.g. wrong size or format).
|
||||
* Tests with invalid data (e.g. wrong size or format, output buffer too small, invalid padding).
|
||||
* For new functions: incorrect function call sequence, driver dispatch (in `tests/suites/test_suite_psa_crypto_driver_wrappers.*`).
|
||||
* For key derivation algorithms: variation on the sequence of input steps, variation on the output size.
|
||||
|
||||
|
479
docs/architecture/psa-migration/md-cipher-dispatch.md
Normal file
479
docs/architecture/psa-migration/md-cipher-dispatch.md
Normal file
@ -0,0 +1,479 @@
|
||||
PSA migration strategy for hashes and ciphers
|
||||
=============================================
|
||||
|
||||
## Introduction
|
||||
|
||||
This document discusses a migration strategy for code that is not subject to `MBEDTLS_USE_PSA_CRYPTO`, is currently using legacy cryptography APIs, and should transition to PSA, without a major version change.
|
||||
|
||||
### Relationship with the main strategy document
|
||||
|
||||
This is complementary to the main [strategy document](strategy.html) and is intended as a refinement. However, at this stage, there may be contradictions between the strategy proposed here and some of the earlier strategy.
|
||||
|
||||
A difference between the original strategy and the current one is that in this work, we are not treating PSA as a black box. We can change experimental features, and we can call internal interfaces.
|
||||
|
||||
## Requirements
|
||||
|
||||
### User stories
|
||||
|
||||
#### Backward compatibility user story
|
||||
|
||||
As a developer of an application that uses Mbed TLS's interfaces (including legacy crypto),
|
||||
I want Mbed TLS to preserve backward compatibility,
|
||||
so that my code keeps working in new minor versions of Mbed TLS.
|
||||
|
||||
#### Interface design user story
|
||||
|
||||
As a developer of library code that uses Mbed TLS to perform cryptographic operations,
|
||||
I want to know which functions to call and which feature macros to check,
|
||||
so that my code works in all Mbed TLS configurations.
|
||||
|
||||
Note: this is the same problem we face in X.509 and TLS.
|
||||
|
||||
#### Hardware accelerator vendor user stories
|
||||
|
||||
As a vendor of a platform with hardware acceleration for some crypto,
|
||||
I want to build Mbed TLS in a way that uses my hardware wherever relevant,
|
||||
so that my customers maximally benefit from my hardware.
|
||||
|
||||
As a vendor of a platform with hardware acceleration for some crypto,
|
||||
I want to build Mbed TLS without software that replicates what my hardware does,
|
||||
to minimize the code size.
|
||||
|
||||
#### Maintainer user stories
|
||||
|
||||
As a maintainer of Mbed TLS,
|
||||
I want to have clear rules for when to use which interface,
|
||||
to avoid bugs in “unusual” configurations.
|
||||
|
||||
As a maintainer of Mbed TLS,
|
||||
I want to avoid duplicating code,
|
||||
because this is inefficient and error-prone.
|
||||
|
||||
### Use PSA more
|
||||
|
||||
In the long term, all code using cryptography should use PSA interfaces, to benefit from PSA drivers, allow eliminating legacy interfaces (less code size, less maintenance). However, this can't be done without breaking [backward compatibility](#backward-compatibility).
|
||||
|
||||
The goal of this work is to arrange for more non-PSA interfaces to use PSA interfaces under the hood, without breaking code in the cases where this doesn't work. Using PSA interfaces has two benefits:
|
||||
|
||||
* Where a PSA driver is available, it likely has better performance, and sometimes better security, than the built-in software implementation.
|
||||
* In many scenarios, where a PSA driver is available, this allows removing the software implementation altogether.
|
||||
* We may be able to get rid of some redundancies, for example the duplication between the implementations of HMAC in `md.c` and in `psa_crypto_mac.c`, and HKDF in `hkdf.c` and `psa_crypto.c`.
|
||||
|
||||
### Correct dependencies
|
||||
|
||||
Traditionally, to determine whether a cryptographic mechanism was available, you had to check whether the corresponding Mbed TLS module or submodule was present: `MBEDTLS_SHA256_C` for SHA256, `MBEDTLS_AES_C && MBEDTLS_CIPHER_MODE_CBC` for AES-CBC, etc. In code that uses the PSA interfaces, this needs to change to `PSA_WANT_xxx` symbols.
|
||||
|
||||
### Backward compatibility
|
||||
|
||||
All documented behavior must be preserved, except for interfaces currently described as experimental or unstable. Those interfaces can change, but we should minimize disruption by providing a transition path for reasonable use cases.
|
||||
|
||||
#### Changeable configuration options
|
||||
|
||||
The following configuration options are described as experimental, and are likely to change at least marginally:
|
||||
|
||||
* `MBEDTLS_PSA_CRYPTO_CLIENT`: “This interface is experimental and may change or be removed without notice.” In practice we don't want to remove this, but we may constrain how it's used.
|
||||
* `MBEDTLS_PSA_CRYPTO_DRIVERS`: “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.” In practice, this may mean constraints not only on how to write drivers, but also on how to integrate drivers into code that is platform code more than application code.
|
||||
* `MBEDTLS_PSA_CRYPTO_CONFIG`: “This feature is still experimental and is not ready for production since it is not completed.” We may want to change this, for example, to automatically enable more mechanisms (although this wouldn't be considered a backward compatibility break anyway, since we don't promise that you will not get a feature if you don't enable its `PSA_WANT_xxx`).
|
||||
|
||||
### Non-goals
|
||||
|
||||
It is not a goal at this stage to make more code directly call `psa_xxx` functions. Rather, the goal is to make more code call PSA drivers where available. How dispatch is done is secondary.
|
||||
|
||||
## Problem analysis
|
||||
|
||||
### Scope analysis
|
||||
|
||||
#### Limitations of `MBEDTLS_USE_PSA_CRYPTO`
|
||||
|
||||
The option `MBEDTLS_USE_PSA_CRYPTO` causes parts of the library to call the PSA API instead of legacy APIs for cryptographic calculations. `MBEDTLS_USE_PSA_CRYPTO` only applies to `pk.h`, X.509 and TLS. When this option is enabled, applications must call `psa_crypto_init()` before calling any of the functions in these modules.
|
||||
|
||||
In this work, we want two things:
|
||||
|
||||
* Make non-covered modules call PSA, but only [when this will actually work](#why-psa-is-not-always-possible). This effectively brings those modules to a partial use-PSA behavior (benefiting from PSA accelerators when they're usable) regardless of whether the option is enabled.
|
||||
* Call PSA when a covered module calls a non-covered module which calls another module, for example X.509 calling pk for PSS verification which calls RSA which calculates a hash ([see issue \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497)). This effectively extends the option to modules that aren't directly covered.
|
||||
|
||||
#### Classification of callers
|
||||
|
||||
We can classify code that implements or uses cryptographic mechanisms into several groups:
|
||||
|
||||
* Software implementations of primitive cryptographic mechanisms. These are not expected to change.
|
||||
* Software implementations of constructed cryptographic mechanisms (e.g. HMAC, CTR_DRBG, RSA (calling a hash for PSS/OAEP, and needing to know the hash length in PKCS1v1.5 sign/verify), …). These need to keep working whenever a legacy implementation of the auxiliary mechanism is available, regardless of whether a PSA implementation is also available.
|
||||
* Code implementing the PSA crypto interface. This is not expected to change, except perhaps to expose some internal functionality to overhauled glue code.
|
||||
* Code that's subject to `MBEDTLS_USE_PSA_CRYPTO`: `pk.h`, X.509, TLS (excluding TLS 1.3).
|
||||
* Code that always uses PSA for crypto: TLS 1.3, LMS.
|
||||
|
||||
For the purposes of this work, three domains emerge:
|
||||
|
||||
* **Legacy domain**: does not interact with PSA. Implementations of hashes, of cipher primitives, of arithmetic.
|
||||
* **Mixed domain**: does not currently use PSA, but should [when possible](#why-psa-is-not-always-possible). This consists of the constructed cryptographic primitives (except LMS), as well as pk, X.509 and TLS when `MBEDTLS_USE_PSA_CRYPTO` is disabled.
|
||||
* **PSA domain**: includes pk, X.509 and TLS when `MBEDTLS_USE_PSA_CRYPTO` is enabled. Also TLS 1.3, LMS.
|
||||
|
||||
#### Non-use-PSA modules
|
||||
|
||||
The following modules in Mbed TLS call another module to perform cryptographic operations which, in the long term, will be provided through a PSA interface, but cannot make any PSA-related assumption:
|
||||
|
||||
* CCM (block cipher in ECB mode; interdependent with cipher)
|
||||
* cipher (cipher and AEAD algorithms)
|
||||
* CMAC (AES-ECB and DES-ECB, but could be extended to the other block ciphers; interdependent with cipher)
|
||||
* CTR\_DRBG (AES-ECB, but could be extended to the other block ciphers)
|
||||
* entropy (hashes via low-level)
|
||||
* ECDSA (HMAC\_DRBG; `md.h` exposed through API)
|
||||
* ECJPAKE (hashes via md; `md.h` exposed through API)
|
||||
* GCM (block cipher in ECB mode; interdependent with cipher)
|
||||
* md (hashes and HMAC)
|
||||
* NIST\_KW (AES-ECB; interdependent with cipher)
|
||||
* HMAC\_DRBG (hashes and HMAC via `md.h`; `md.h` exposed through API)
|
||||
* PEM (AES and DES in CBC mode without padding; MD5 hash via low-level)
|
||||
* PKCS12 (cipher, generically, selected from ASN.1 or function parameters; hashes via md; `cipher.h` exposed through API)
|
||||
* PKCS5 (cipher, generically, selected from ASN.1; HMAC via `md.h`; `md.h` exposed through API)
|
||||
* RSA (hash via md for PSS and OAEP; `md.h` exposed through API)
|
||||
|
||||
### Difficulties
|
||||
|
||||
#### Why PSA is not always possible
|
||||
|
||||
Here are some reasons why calling `psa_xxx()` to perform a hash or cipher calculation might not be desirable in some circumstances, explaining why the application would arrange to call the legacy software implementation instead.
|
||||
|
||||
* `MBEDTLS_PSA_CRYPTO_C` is disabled.
|
||||
* There is a PSA driver which has not been initialized (this happens in `psa_crypto_init()`).
|
||||
* For ciphers, the keystore is not initialized yet, and Mbed TLS uses a custom implementation of PSA ITS where the file system is not accessible yet (because something else needs to happen first, and the application takes care that it happens before it calls `psa_crypto_init()`). A possible workaround may be to dispatch to the internal functions that are called after the keystore lookup, rather than to the PSA API functions (but this is incompatible with `MBEDTLS_PSA_CRYPTO_CLIENT`).
|
||||
* The requested mechanism is enabled in the legacy interface but not in the PSA interface. This was not really intended, but is possible, for example, if you enable `MBEDTLS_MD5_C` for PEM decoding with PBKDF1 but don't want `PSA_ALG_WANT_MD5` because it isn't supported for `PSA_ALG_RSA_PSS` and `PSA_ALG_DETERMINISTIC_ECDSA`.
|
||||
* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the client has not yet activated the connection to the server (this happens in `psa_crypto_init()`).
|
||||
* `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, but the operation is part of the implementation of an encrypted communication with the crypto service, or the local implementation is faster because it avoids a costly remote procedure call.
|
||||
|
||||
#### Indirect knowledge
|
||||
|
||||
Consider for example the code in `rsa.c` to perform an RSA-PSS signature. It needs to calculate a hash. If `mbedtls_rsa_rsassa_pss_sign()` is called directly by application code, it is supposed to call the built-in implementation: calling a PSA accelerator would be a behavior change, acceptable only if this does not add a risk of failure or performance degradation ([PSA is impossible or undesirable in some circumstances](#why-psa-is-not-always-possible)). Note that this holds regardless of the state of `MBEDTLS_USE_PSA_CRYPTO`, since `rsa.h` is outside the scope of `MBEDTLS_USE_PSA_CRYPTO`. On the other hand, if `mbedtls_rsa_rsassa_pss_sign()` is called from X.509 code, it should use PSA to calculate hashes. It doesn't, currently, which is [bug \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497).
|
||||
|
||||
Generally speaking, modules in the mixed domain:
|
||||
|
||||
* must call PSA if called by a module in the PSA domain;
|
||||
* must not call PSA (or must have a fallback) if their caller is not in the PSA domain and the PSA call is not guaranteed to work.
|
||||
|
||||
#### Non-support guarantees: requirements
|
||||
|
||||
Generally speaking, just because some feature is not enabled in `mbedtls_config.h` or `psa_config.h` doesn't guarantee that it won't be enabled in the build. We can enable additional features through `build_info.h`.
|
||||
|
||||
If `PSA_WANT_xxx` is disabled, this should guarantee that attempting xxx through the PSA API will fail. This is generally guaranteed by the test suite `test_suite_psa_crypto_not_supported` with automatically enumerated test cases, so it would be inconvenient to carve out an exception.
|
||||
|
||||
### Technical requirements
|
||||
|
||||
Based on the preceding analysis, the core of the problem is: for code in the mixed domain (see [“Classification of callers”](#classification-of-callers)), how do we handle a cryptographic mechanism? This has several related subproblems:
|
||||
|
||||
* How the mechanism is encoded (e.g. `mbedtls_md_type_t` vs `const *mbedtls_md_info_t` vs `psa_algorithm_t` for hashes).
|
||||
* How to decide whether a specific algorithm or key type is supported (eventually based on `MBEDTLS_xxx_C` vs `PSA_WANT_xxx`).
|
||||
* How to obtain metadata about algorithms (e.g. hash/MAC/tag size, key size).
|
||||
* How to perform the operation (context type, which functions to call).
|
||||
|
||||
We need a way to decide this based on the available information:
|
||||
|
||||
* Who's the ultimate caller — see [indirect knowledge](#indirect-knowledge) — which is not actually available.
|
||||
* Some parameter indicating which algorithm to use.
|
||||
* The available cryptographic implementations, based on preprocessor symbols (`MBEDTLS_xxx_C`, `PSA_WANT_xxx`, `MBEDTLS_PSA_ACCEL_xxx`, etc.).
|
||||
* Possibly additional runtime state (for example, we might check whether `psa_crypto_init` has been called).
|
||||
|
||||
And we need to take care of the [the cases where PSA is not possible](#why-psa-is-not-always-possible): either make sure the current behavior is preserved, or (where allowed by backward compatibility) document a behavior change and, preferably, a workaround.
|
||||
|
||||
### Working through an example: RSA-PSS
|
||||
|
||||
Let us work through the example of RSA-PSS which calculates a hash, as in [see issue \#6497](https://github.com/Mbed-TLS/mbedtls/issues/6497).
|
||||
|
||||
RSA is in the [mixed domain](#classification-of-callers). So:
|
||||
|
||||
* When called from `psa_sign_hash` and other PSA functions, it must call the PSA hash accelerator if there is one.
|
||||
* When called from user code, it must call the built-in hash implementation if PSA is not available (regardless of whether this is because `MBEDTLS_PSA_CRYPTO_C` is disabled, or because `PSA_WANT_ALG_xxx` is disabled for this hash, or because there is an accelerator driver which has not been initialized yet).
|
||||
|
||||
RSA knows which hash algorithm to use based on a parameter of type `mbedtls_md_type_t`. (More generally, all mixed-domain modules that take an algorithm specification as a parameter take it via a numerical type, except HMAC\_DRBG and HKDF which take a `const mbedtls_md_info_t*` instead, and CMAC which takes a `const mbedtls_cipher_info_t *`.)
|
||||
|
||||
#### Double encoding solution
|
||||
|
||||
A natural solution is to double up the encoding of hashes in `mbedtls_md_type_t`. Pass `MBEDTLS_MD_SHA256` and `md` will dispatch to the legacy code, pass a new constant `MBEDTLS_MD_SHA256_USE_PSA` and `md` will dispatch through PSA.
|
||||
|
||||
This maximally preserves backward compatibility, but then no non-PSA code benefits from PSA accelerators, and there's little potential for removing the software implementation.
|
||||
|
||||
#### Availability of hashes in RSA-PSS
|
||||
|
||||
Here we try to answer the question: As a caller of RSA-PSS via `rsa.h`, how do I know whether it can use a certain hash?
|
||||
|
||||
* For a caller in the legacy domain: if e.g. `MBEDTLS_SHA256_C` is enabled, then I want RSA-PSS to support SHA-256. I don't care about negative support. So `MBEDTLS_SHA256_C` must imply support for RSA-PSS-SHA-256. It must work at all times, regardless of the state of PSA (e.g. drivers not initialized).
|
||||
* For a caller in the PSA domain: if e.g. `PSA_WANT_ALG_SHA_256` is enabled, then I want RSA-PSS to support SHA-256, provided that `psa_crypto_init()` has been called. In some limited cases, such as `test_suite_psa_crypto_not_supported` when PSA implements RSA-PSS in software, we care about negative support: if `PSA_WANT_ALG_SHA_256` is disabled then `psa_verify_hash` must reject `PSA_WANT_ALG_SHA_256`. This can be done at the level of PSA before it calls the RSA module, though, so it doesn't have any implication on the RSA module. As far as `rsa.c` is concerned, what matters is that `PSA_WANT_ALG_SHA_256` implies that SHA-256 is supported after `psa_crypto_init()` has been called.
|
||||
* For a caller in the mixed domain: requirements depend on the caller. Whatever solution RSA has to determine the availability of algorithms will apply to its caller as well.
|
||||
|
||||
Conclusion so far: RSA must be able to do SHA-256 if either `MBEDTLS_SHA256_C` or `PSA_WANT_ALG_SHA_256` is enabled. If only `PSA_WANT_ALG_SHA_256` and not `MBEDTLS_SHA256_C` is enabled (which implies that PSA's SHA-256 comes from an accelerator driver), then SHA-256 only needs to work if `psa_crypto_init()` has been called.
|
||||
|
||||
#### More in-depth discussion of compile-time availability determination
|
||||
|
||||
The following combinations of compile-time support are possible:
|
||||
|
||||
* `MBEDTLS_PSA_CRYPTO_CLIENT`. Then calling PSA may or may not be desirable for performance. There are plausible use cases where only the server has access to an accelerator so it's best to call the server, and plausible use cases where calling the server has overhead that negates the savings from using acceleration, if there are savings at all. In any case, calling PSA only works if the connection to the server has been established, meaning `psa_crypto_init` has been called successfully. In the rest of this case enumeration, assume `MBEDTLS_PSA_CRYPTO_CLIENT` is disabled.
|
||||
* No PSA accelerator. Then just call `mbedtls_sha256`, it's all there is, and it doesn't matter (from an API perspective) exactly what call chain leads to it.
|
||||
* PSA accelerator, no software implementation. Then we might as well call the accelerator, unless it's important that the call fails. At the time of writing, I can't think of a case where we would want to guarantee that if `MBEDTLS_xxx_C` is not enabled, but xxx is enabled through PSA, then a request to use algorithm xxx through some legacy interface must fail.
|
||||
* Both PSA acceleration and the built-in implementation. In this case, we would prefer PSA for the acceleration, but we can only do this if the accelerator driver is working. For hashes, it's enough to assume the driver is initialized; we've [considered requiring hash drivers to work without initialization](https://github.com/Mbed-TLS/mbedtls/pull/6470). For ciphers, this is more complicated because the cipher functions require the keystore, and plausibly a cipher accelerator might want entropy (for side channel countermeasures) which might not be available at boot time.
|
||||
|
||||
Note that it's a bit tricky to determine which algorithms are available. In the case where there is a PSA accelerator but no software implementation, we don't want the preprocessor symbols to indicate that the algorithm is available through the legacy domain, only through the PSA domain. What does this mean for the interfaces in the mixed domain? They can't guarantee the availability of the algorithm, but they must try if requested.
|
||||
|
||||
### Designing an interface for hashes
|
||||
|
||||
In this section, we specify a hash metadata and calculation for the [mixed domain](#classification-of-callers), i.e. code that can be called both from legacy code and from PSA code.
|
||||
|
||||
#### Availability of hashes
|
||||
|
||||
Generalizing the analysis in [“Availability of hashes in RSA-PSS”](#availability-of-hashes-in-RSA-PSS):
|
||||
|
||||
A hash is available through the mixed-domain interface iff either of the following conditions is true:
|
||||
|
||||
* A legacy hash interface is available and the hash algorithm is implemented in software.
|
||||
* PSA crypto is enabled and the hash algorithm is implemented via PSA.
|
||||
|
||||
We could go further and make PSA accelerators available to legacy callers that call any legacy hash interface, e.g. `md.h` or `shaX.h`. There is little point in doing this, however: callers should just use the mixed-domain interface.
|
||||
|
||||
#### Implications between legacy availability and PSA availability
|
||||
|
||||
* When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, all legacy mechanisms are automatically enabled through PSA. Users can manually enable PSA mechanisms that are available through accelerators but not through legacy, but this is not officially supported (users are not supposed to manually define PSA configuration symbols when `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled).
|
||||
* When `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled, there is no mandatory relationship between PSA support and legacy support for a mechanism. Users can configure legacy support and PSA support independently. Legacy support is automatically enabled if PSA support is requested, but only if there is no accelerator.
|
||||
|
||||
It is strongly desirable to allow mechanisms available through PSA but not legacy: this allows saving code size when an accelerator is present.
|
||||
|
||||
There is no strong reason to allow mechanisms available through legacy but not PSA when `MBEDTLS_PSA_CRYPTO_C` is enabled. This would only save at best a very small amount of code size in the PSA dispatch code. This may be more desirable when `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled (having a mechanism available only locally and not in the crypto service), but we do not have an explicit request for this and it would be entirely reasonable to forbid it.
|
||||
|
||||
In this analysis, we have not found a compelling reason to require all legacy mechanisms to also be available through PSA. However, this can simplify both the implementation and the use of dispatch code thanks to some simplifying properties:
|
||||
|
||||
* Mixed-domain code can call PSA code if it knows that `psa_crypto_init()` has been called, without having to inspect the specifics of algorithm support.
|
||||
* Mixed-domain code can assume that PSA buffer calculations work correctly for all algorithms that it supports.
|
||||
|
||||
#### Shape of the mixed-domain hash interface
|
||||
|
||||
We now need to create an abstraction for mixed-domain hash calculation. (We could not create an abstraction, but that would require every piece of mixed-domain code to replicate the logic here. We went that route in Mbed TLS 3.3, but it made it effectively impossible to get something that works correctly.)
|
||||
|
||||
Requirements: given a hash algorithm,
|
||||
|
||||
* Obtain some metadata about it (size, block size).
|
||||
* Calculate the hash.
|
||||
* Set up a multipart operation to calculate the hash. The operation must support update, finish, reset, abort, clone.
|
||||
|
||||
The existing interface in `md.h` is close to what we want, but not perfect. What's wrong with it?
|
||||
|
||||
* It has an extra step of converting from `mbedtls_md_type_t` to `const mbedtls_md_info_t *`.
|
||||
* It includes extra fluff such as names and HMAC. This costs code size.
|
||||
* The md module has some legacy baggage dating from when it was more open, which we don't care about anymore. This may cost code size.
|
||||
|
||||
These problems are easily solvable.
|
||||
|
||||
* `mbedtls_md_info_t` can become a very thin type. We can't remove the extra function call from the source code of callers, but we can make it a very thin abstraction that compilers can often optimize.
|
||||
* We can make names and HMAC optional. The mixed-domain hash interface won't be the full `MBEDTLS_MD_C` but a subset.
|
||||
* We can optimize `md.c` without making API changes to `md.h`.
|
||||
|
||||
## Specification
|
||||
|
||||
### MD light
|
||||
|
||||
https://github.com/Mbed-TLS/mbedtls/pull/6474 implements part of this specification, but it's based on Mbed TLS 3.2, so it needs to be rewritten for 3.3.
|
||||
|
||||
#### Definition of MD light
|
||||
|
||||
MD light is a subset of `md.h` that implements the hash calculation interface described in ”[Designing an interface for hashes](#designing-an-interface-for-hashes)”. It is activated by `MBEDTLS_MD_LIGHT` in `mbedtls_config.h`.
|
||||
|
||||
The following things enable MD light automatically in `build_info.h`:
|
||||
|
||||
* A [mixed-domain](#classification-of-callers) module that needs to calculate hashes is enabled.
|
||||
* `MBEDTLS_MD_C` is enabled.
|
||||
|
||||
MD light includes the following types:
|
||||
|
||||
* `mbedtls_md_type_t`
|
||||
* `mbedtls_md_info_t`
|
||||
* `mbedtls_md_context_t`
|
||||
|
||||
MD light includes the following functions:
|
||||
|
||||
* `mbedtls_md_info_from_type`
|
||||
* `mbedtls_md_init`
|
||||
* `mbedtls_md_free`
|
||||
* `mbedtls_md_setup` — but `hmac` must be 0 if `MBEDTLS_MD_C` is disabled.
|
||||
* `mbedtls_md_clone`
|
||||
* `mbedtls_md_get_size`
|
||||
* `mbedtls_md_get_type`
|
||||
* `mbedtls_md_starts`
|
||||
* `mbedtls_md_update`
|
||||
* `mbedtls_md_finish`
|
||||
* `mbedtls_md`
|
||||
|
||||
Unlike the full MD, MD light does not support null pointers as `mbedtls_md_context_t *`. At least some functions still need to support null pointers as `const mbedtls_md_info_t *` because this arises when you try to use an unsupported algorithm (`mbedtls_md_info_from_type` returns `NULL`).
|
||||
|
||||
#### MD algorithm support macros
|
||||
|
||||
For each hash algorithm, `md.h` defines a macro `MBEDTLS_MD_CAN_xxx` whenever the corresponding hash is available through MD light. These macros are only defined when `MBEDTLS_MD_LIGHT` is enabled. Per “[Availability of hashes](#availability-of-hashes)”, `MBEDTLS_MD_CAN_xxx` is enabled if:
|
||||
|
||||
* the corresponding `MBEDTLS_xxx_C` is defined; or
|
||||
* one of `MBEDTLS_PSA_CRYPTO_C` or `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, and the corresponding `PSA_WANT_ALG_xxx` is enabled.
|
||||
|
||||
Note that some algorithms have different spellings in legacy and PSA. Since MD is a legacy interface, we'll use the legacy names. Thus, for example:
|
||||
|
||||
```
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
#if defined(MBEDTLS_SHA256_C) || \
|
||||
(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`.
|
||||
* If at least one hash has a legacy implementation, defined `MBEDTLS_MD_SOME_LEGACY`.
|
||||
|
||||
#### Support for PSA in the MD context
|
||||
|
||||
An MD context needs to contain either a legacy module's context (or a pointer to one, as is the case now), or a PSA context (or a pointer to one).
|
||||
|
||||
I am inclined to remove the pointer indirection, but this means that an MD context would always be as large as the largest supported hash context. So for the time being, this specification keeps a pointer. For uniformity, PSA will also have a pointer (we may simplify this later).
|
||||
|
||||
```
|
||||
enum {
|
||||
MBEDTLS_MD_ENGINE_LEGACY,
|
||||
MBEDTLS_MD_ENGINE_PSA,
|
||||
} mbedtls_md_engine_t; // private type
|
||||
|
||||
typedef struct mbedtls_md_context_t {
|
||||
mbedtls_md_type_t type;
|
||||
#if defined(MBEDTLS_MD_SOME_PSA)
|
||||
mbedtls_md_engine_t engine;
|
||||
#endif
|
||||
void *md_ctx; // mbedtls_xxx_context or psa_hash_operation
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
void *hmac_ctx;
|
||||
#endif
|
||||
} mbedtls_md_context_t;
|
||||
```
|
||||
|
||||
All fields are private.
|
||||
|
||||
The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
|
||||
|
||||
#### Inclusion of MD info structures
|
||||
|
||||
MD light needs to support hashes that are only enabled through PSA. Therefore the `mbedtls_md_info_t` structures must be included based on `MBEDTLS_MD_CAN_xxx` instead of just the legacy module.
|
||||
|
||||
The same criterion applies in `mbedtls_md_info_from_type`.
|
||||
|
||||
#### Conversion to PSA encoding
|
||||
|
||||
The implementation needs to convert from a legacy type encoding to a PSA encoding.
|
||||
|
||||
```
|
||||
static inline psa_algorithm_t psa_alg_of_md_info(
|
||||
const mbedtls_md_info_t *md_info );
|
||||
```
|
||||
|
||||
#### Determination of PSA support at runtime
|
||||
|
||||
```
|
||||
int psa_can_do_hash(psa_algorithm_t hash_alg);
|
||||
```
|
||||
|
||||
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA.
|
||||
|
||||
As a starting point, return 1 if PSA crypto has been initialized. This will be refined later (to return 1 if the [accelerator subsystem](https://github.com/Mbed-TLS/mbedtls/issues/6007) has been initialized).
|
||||
|
||||
Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
|
||||
|
||||
#### Support for PSA dispatch in hash operations
|
||||
|
||||
Each function that performs some hash operation or context management needs to know whether to dispatch via PSA or legacy.
|
||||
|
||||
If given an established context, use its `engine` field.
|
||||
|
||||
If given an algorithm as an `mbedtls_md_type_t type` (possibly being the `type` field of a `const mbedtls_md_info_t *`):
|
||||
|
||||
* If there is a PSA accelerator for this hash and `psa_can_do_hash(alg)`, call the corresponding PSA function, and if applicable set the engine to `MBEDTLS_MD_ENGINE_PSA`. (Skip this is `MBEDTLS_MD_SOME_PSA` is not defined.)
|
||||
* Otherwise dispatch to the legacy module based on the type as currently done. (Skip this is `MBEDTLS_MD_SOME_LEGACY` is not defined.)
|
||||
* If no dispatch is possible, return `MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE`.
|
||||
|
||||
Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress. Document this.
|
||||
|
||||
#### Error code conversion
|
||||
|
||||
After calling a PSA function, call `mbedtls_md_error_from_psa` to convert its status code. This function is currently defined in `hash_info.c`.
|
||||
|
||||
### Migration to MD light
|
||||
|
||||
#### Migration of modules that used to call MD and now do the legacy-or-PSA dance
|
||||
|
||||
Get rid of the case where `MBEDTLS_MD_C` is undefined. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of modules that used to call a low-level hash module and now do the legacy-or-PSA dance
|
||||
|
||||
Switch to calling MD (light) unconditionally. Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of modules that call a low-level hash module
|
||||
|
||||
Switch to calling MD (light). Enable `MBEDTLS_MD_LIGHT` in `build_info.h`.
|
||||
|
||||
#### Migration of use-PSA mixed code
|
||||
|
||||
Instead of calling `hash_info.h` functions to obtain metadata, get it from `md.h`.
|
||||
|
||||
Optionally, code that currently tests on `MBEDTLS_USE_PSA_CRYPTO` just to determine whether to call MD or PSA to calculate hashes can switch to just having the MD variant.
|
||||
|
||||
#### Remove `legacy_or_psa.h`
|
||||
|
||||
It's no longer used.
|
||||
|
||||
### Support all legacy algorithms in PSA
|
||||
|
||||
As discussed in [“Implications between legacy availability and PSA availability”](#implications-between-legacy-availability-and-psa-availability), we require the following property:
|
||||
|
||||
> If an algorithm has a legacy implementation, it is also available through PSA.
|
||||
|
||||
When `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled, this is already the case. When is enabled, we will now make it so as well. Change `include/mbedtls/config_psa.h` accordingly.
|
||||
|
||||
### MD light optimizations
|
||||
|
||||
This section is not necessary to implement MD light, but will cut down its code size.
|
||||
|
||||
#### Split names out of MD light
|
||||
|
||||
Remove hash names from `mbedtls_md_info_t`. Use a simple switch-case or a separate list to implement `mbedtls_md_info_from_string` and `mbedtls_md_get_name`.
|
||||
|
||||
#### Remove metadata from the info structure
|
||||
|
||||
In `mbedtls_md_get_size` and in modules that want a hash's block size, instead of looking up hash metadata in the info structure, call the PSA macros.
|
||||
|
||||
#### Optimize type conversions
|
||||
|
||||
To allow optimizing conversions between `mbedtls_md_type_t` and `psa_algorithm_t`, renumber the `mbedtls_md_type_t` enum so that the values are the 8 lower bits of the PSA encoding.
|
||||
|
||||
With this optimization,
|
||||
```
|
||||
static inline psa_algorithm_t psa_alg_of_md_info(
|
||||
const mbedtls_md_info_t *md_info )
|
||||
{
|
||||
if( md_info == NULL )
|
||||
return( PSA_ALG_NONE );
|
||||
return( PSA_ALG_CATEGORY_HASH | md_info->type );
|
||||
}
|
||||
```
|
||||
|
||||
Work in progress on this conversion is at https://github.com/gilles-peskine-arm/mbedtls/tree/hash-unify-ids-wip-1
|
||||
|
||||
#### Get rid of the hash_info module
|
||||
|
||||
The hash_info module is redundant with MD light. Move `mbedtls_md_error_from_psa` to `md.c`, defined only when `MBEDTLS_MD_SOME_PSA` is defined. The rest is no longer used.
|
||||
|
||||
#### Unify HMAC with PSA
|
||||
|
||||
PSA has its own HMAC implementation. In builds with both `MBEDTLS_MD_C` and `PSA_WANT_ALG_HMAC` not fully provided by drivers, we should have a single implementation. Replace the one in `md.h` by calls to the PSA driver interface. This will also give mixed-domain modules access to HMAC accelerated directly by a PSA driver (eliminating the need to a HMAC interface in software if all supported hashes have an accelerator that includes HMAC support).
|
||||
|
||||
### Improving support for `MBEDTLS_PSA_CRYPTO_CLIENT`
|
||||
|
||||
So far, MD light only dispatches to PSA if an algorithm is available via `MBEDTLS_PSA_CRYPTO_C`, not if it's available via `MBEDTLS_PSA_CRYPTO_CLIENT`. This is acceptable because `MBEDTLS_USE_PSA_CRYPTO` requires `MBEDTLS_PSA_CRYPTO_C`, hence mixed-domain code never invokes PSA.
|
||||
|
||||
The architecture can be extended to support `MBEDTLS_PSA_CRYPTO_CLIENT` with a little extra work. Here is an overview of the task breakdown, which should be fleshed up after we've done the first [migration](#migration-to-md-light):
|
||||
|
||||
* Compile-time dependencies: instead of checking `defined(MBEDTLS_PSA_CRYPTO_C)`, check `defined(MBEDTLS_PSA_CRYPTO_C) || defined(MBEDTLS_PSA_CRYPTO_CLIENT)`.
|
||||
* Implementers of `MBEDTLS_PSA_CRYPTO_CLIENT` will need to provide `psa_can_do_hash()` (or a more general function `psa_can_do`) alongside `psa_crypto_init()`. Note that at this point, it will become a public interface, hence we won't be able to change it at a whim.
|
@ -1,47 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script runs tests in various revisions and configurations and analyses
|
||||
# the results in order to highlight any difference in the set of tests skipped
|
||||
# in the test suites of interest.
|
||||
# This script runs tests before and after a PR and analyzes the results in
|
||||
# order to highlight any difference in the set of tests skipped.
|
||||
#
|
||||
# It can be used to ensure the testing criteria mentioned in strategy.md,
|
||||
# It can be used to check the first testing criterion mentioned in strategy.md,
|
||||
# end of section "Supporting builds with drivers without the software
|
||||
# implementation" are met, namely:
|
||||
# implementation", namely: the sets of tests skipped in the default config and
|
||||
# the full config must be the same before and after the PR.
|
||||
#
|
||||
# - the sets of tests skipped in the default config and the full config must be
|
||||
# the same before and after the PR that implements step 3;
|
||||
# - the set of tests skipped in the driver-only build is the same as in an
|
||||
# equivalent software-based configuration, or the difference is small enough,
|
||||
# justified, and a github issue is created to track it.
|
||||
# USAGE:
|
||||
# - First, commit any uncommited changes. (Also, see warning below.)
|
||||
# - Then launch --> [SKIP_SSL_OPT=1] docs/architecture/psa-migration/outcome-analysis.sh
|
||||
# - SKIP_SSL_OPT=1 can optionally be set to skip ssl-opt.sh tests
|
||||
#
|
||||
# WARNING: this script checks out a commit other than the head of the current
|
||||
# branch; it checks out the current branch again when running successfully,
|
||||
# but while the script is running, or if it terminates early in error, you
|
||||
# should be aware that you might be at a different commit than expected.
|
||||
#
|
||||
# NOTE: This is only an example/template script, you should make a copy and
|
||||
# edit it to suit your needs. The part that needs editing is at the top.
|
||||
#
|
||||
# Also, you can comment out parts that don't need to be re-done when
|
||||
# NOTE: you can comment out parts that don't need to be re-done when
|
||||
# re-running this script (for example "get numbers before this PR").
|
||||
|
||||
# ----- BEGIN edit this -----
|
||||
# The component in all.sh that builds and tests with drivers.
|
||||
DRIVER_COMPONENT=test_psa_crypto_config_accel_hash_use_psa
|
||||
# A similar configuration to that of the component, except without drivers,
|
||||
# for comparison.
|
||||
reference_config () {
|
||||
scripts/config.py set MBEDTLS_USE_PSA_CRYPTO
|
||||
scripts/config.py unset MBEDTLS_PKCS1_V21
|
||||
scripts/config.py unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
|
||||
scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
|
||||
}
|
||||
# Space-separated list of test suites of interest.
|
||||
SUITES="rsa pkcs1_v15 pk pkparse pkwrite"
|
||||
# ----- END edit this -----
|
||||
|
||||
set -eu
|
||||
|
||||
: ${SKIP_SSL_OPT:=0}
|
||||
|
||||
cleanup() {
|
||||
make clean
|
||||
git checkout -- include/mbedtls/mbedtls_config.h include/psa/crypto_config.h
|
||||
@ -50,7 +33,14 @@ cleanup() {
|
||||
record() {
|
||||
export MBEDTLS_TEST_OUTCOME_FILE="$PWD/outcome-$1.csv"
|
||||
rm -f $MBEDTLS_TEST_OUTCOME_FILE
|
||||
|
||||
make check
|
||||
|
||||
if [ $SKIP_SSL_OPT -eq 0 ]; then
|
||||
make -C programs ssl/ssl_server2 ssl/ssl_client2 \
|
||||
test/udp_proxy test/query_compile_time_config
|
||||
tests/ssl-opt.sh
|
||||
fi
|
||||
}
|
||||
|
||||
# save current HEAD
|
||||
@ -59,38 +49,55 @@ HEAD=$(git branch --show-current)
|
||||
# get the numbers before this PR for default and full
|
||||
cleanup
|
||||
git checkout $(git merge-base HEAD development)
|
||||
|
||||
record "before-default"
|
||||
|
||||
cleanup
|
||||
|
||||
scripts/config.py full
|
||||
record "before-full"
|
||||
|
||||
# get the numbers now for default and full
|
||||
cleanup
|
||||
git checkout $HEAD
|
||||
|
||||
record "after-default"
|
||||
|
||||
cleanup
|
||||
|
||||
scripts/config.py full
|
||||
record "after-full"
|
||||
|
||||
# get the numbers now for driver-only and reference
|
||||
cleanup
|
||||
reference_config
|
||||
record "reference"
|
||||
|
||||
cleanup
|
||||
export MBEDTLS_TEST_OUTCOME_FILE="$PWD/outcome-drivers.csv"
|
||||
tests/scripts/all.sh -k test_psa_crypto_config_accel_hash_use_psa
|
||||
|
||||
# analysis
|
||||
|
||||
populate_suites () {
|
||||
SUITES=''
|
||||
make generated_files >/dev/null
|
||||
data_files=$(cd tests/suites && echo *.data)
|
||||
for data in $data_files; do
|
||||
suite=${data%.data}
|
||||
SUITES="$SUITES $suite"
|
||||
done
|
||||
make neat
|
||||
|
||||
if [ $SKIP_SSL_OPT -eq 0 ]; then
|
||||
SUITES="$SUITES ssl-opt"
|
||||
extra_files=$(cd tests/opt-testcases && echo *.sh)
|
||||
for extra in $extra_files; do
|
||||
suite=${extra%.sh}
|
||||
SUITES="$SUITES $suite"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
compare_suite () {
|
||||
ref="outcome-$1.csv"
|
||||
new="outcome-$2.csv"
|
||||
suite="$3"
|
||||
|
||||
pattern_suite=";test_suite_$suite;"
|
||||
pattern_suite=";$suite;"
|
||||
total=$(grep -c "$pattern_suite" "$ref")
|
||||
sed_cmd="s/^.*$pattern_suite\(.*\);SKIP.*/\1/p"
|
||||
sed -n "$sed_cmd" "$ref" > skipped-ref
|
||||
@ -98,19 +105,33 @@ compare_suite () {
|
||||
nb_ref=$(wc -l <skipped-ref)
|
||||
nb_new=$(wc -l <skipped-new)
|
||||
|
||||
printf "%12s: total %3d; skipped %3d -> %3d\n" \
|
||||
$suite $total $nb_ref $nb_new
|
||||
diff skipped-ref skipped-new | grep '^> ' || true
|
||||
name=${suite#test_suite_}
|
||||
printf "%40s: total %4d; skipped %4d -> %4d\n" \
|
||||
$name $total $nb_ref $nb_new
|
||||
if diff skipped-ref skipped-new | grep '^> '; then
|
||||
ret=1
|
||||
else
|
||||
ret=0
|
||||
fi
|
||||
rm skipped-ref skipped-new
|
||||
return $ret
|
||||
}
|
||||
|
||||
compare_builds () {
|
||||
printf "\n*** Comparing $1 -> $2 ***\n"
|
||||
failed=''
|
||||
for suite in $SUITES; do
|
||||
compare_suite "$1" "$2" "$suite"
|
||||
if compare_suite "$1" "$2" "$suite"; then :; else
|
||||
failed="$failed $suite"
|
||||
fi
|
||||
done
|
||||
if [ -z "$failed" ]; then
|
||||
printf "No coverage gap found.\n"
|
||||
else
|
||||
printf "Suites with less coverage:%s\n" "$failed"
|
||||
fi
|
||||
}
|
||||
|
||||
populate_suites
|
||||
compare_builds before-default after-default
|
||||
compare_builds before-full after-full
|
||||
compare_builds reference drivers
|
||||
|
@ -11,14 +11,21 @@ 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, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with
|
||||
`MBEDTLS_ECP_RESTARTABLE`.
|
||||
Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
|
||||
both enabled, some operations that should be restartable are not (ECDH in TLS
|
||||
1.2 clients using ECDHE-ECDSA), as they are using PSA instead, and some
|
||||
operations that should use PSA do not (signature generation & verification) as
|
||||
they use the legacy API instead, in order to get restartable behaviour.
|
||||
|
||||
Things that are in the API but not implemented yet
|
||||
--------------------------------------------------
|
||||
@ -29,11 +36,6 @@ github.
|
||||
|
||||
[ffdh]: https://github.com/Mbed-TLS/mbedtls/issues/3261
|
||||
|
||||
PSA Crypto has an experimental API for EC J-PAKE, but it's not implemented in
|
||||
Mbed TLS yet. See the [EC J-PAKE follow-up EPIC][ecjp] on github.
|
||||
|
||||
[ecjp]: https://github.com/orgs/Mbed-TLS/projects/1#column-17950140
|
||||
|
||||
Arbitrary parameters for FFDH
|
||||
-----------------------------
|
||||
|
||||
@ -80,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
|
||||
------------------
|
||||
|
||||
@ -323,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)
|
||||
============================================================
|
||||
|
||||
|
@ -18,13 +18,17 @@ needs to be changed to use new APIs. For a more detailed account of what's
|
||||
implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and
|
||||
internal changes implement (G1).
|
||||
|
||||
As of early 2023, work towards G5 is in progress: Mbed TLS 3.3 and 3.4 saw
|
||||
some improvements in this area, and more will be coming in future releases.
|
||||
|
||||
Generally speaking, the numbering above doesn't mean that each goal requires
|
||||
the preceding ones to be completed.
|
||||
|
||||
|
||||
Compile-time options
|
||||
====================
|
||||
|
||||
We currently have two compile-time options that are relevant to the migration:
|
||||
We currently have a few compile-time options that are relevant to the migration:
|
||||
|
||||
- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
|
||||
Crypto APIs.
|
||||
@ -36,7 +40,9 @@ We currently have two compile-time options that are relevant to the migration:
|
||||
|
||||
The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
|
||||
are:
|
||||
- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`;
|
||||
- it's not fully compatible with `MBEDTLS_ECP_RESTARTABLE`: you can enable
|
||||
both, but then you won't get the full effect of RESTARTBLE (see the
|
||||
documentation of this option in `mbedtls_config.h`);
|
||||
- to avoid a hard/default dependency of TLS, X.509 and PK on
|
||||
`MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
|
||||
- When `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
|
||||
@ -71,10 +77,10 @@ Crypto does not support restartable operations, there's a clear conflict: the
|
||||
TLS and X.509 layers can't both use only PSA APIs and get restartable
|
||||
behaviour.
|
||||
|
||||
Supporting this in PSA is on our roadmap and currently planned for end of
|
||||
2022, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18883250>.
|
||||
Support for restartable (aka interruptible) ECDSA sign/verify operation was
|
||||
added to PSA in Mbed TLS 3.4, but support for ECDH is not present yet.
|
||||
|
||||
It will then require follow-up work to make use of the new PSA API in
|
||||
It will then require follow-up work to make use of the new PSA APIs in
|
||||
PK/X.509/TLS in all places where we currently allow restartable operations.
|
||||
|
||||
### Backward compatibility issues with making `MBEDTLS_USE_PSA_CRYPTO` always on
|
||||
@ -137,8 +143,11 @@ crypto API.
|
||||
- Downside: tricky to implement if the PSA implementation is currently done on
|
||||
top of that layer (dependency loop).
|
||||
|
||||
This strategy is currently (early 2022) used for all operations in the PK
|
||||
layer.
|
||||
This strategy is currently (early 2023) used for all operations in the PK
|
||||
layer; the MD layer uses a variant where it dispatches to PSA if a driver is
|
||||
available and the driver subsystem has been initialized, regardless of whether
|
||||
`USE_PSA_CRYPTO` is enabled; see `md-cipher-dispatch.md` in the same directory
|
||||
for details.
|
||||
|
||||
This strategy is not very well suited to the Cipher layer, as the PSA
|
||||
implementation is currently done on top of that layer.
|
||||
@ -161,8 +170,9 @@ Replace calls for each operation
|
||||
code size.
|
||||
- Downside: TLS/X.509 code has to be done for each operation.
|
||||
|
||||
This strategy is currently (early 2022) used for the MD layer and the Cipher
|
||||
layer.
|
||||
This strategy is currently (early 2023) used for the MD layer and the Cipher
|
||||
layer in X.509 and TLS. Crypto modules however always call to MD which may
|
||||
then dispatch to PSA, see `md-cipher-dispatch.md`.
|
||||
|
||||
Opt-in use of PSA from the abstraction layer
|
||||
--------------------------------------------
|
||||
@ -210,7 +220,10 @@ Strategies currently (early 2022) used with each abstraction layer:
|
||||
- PK (for G1): silently call PSA
|
||||
- PK (for G2): opt-in use of PSA (new key type)
|
||||
- Cipher (G1): replace calls at each call site
|
||||
- MD (G1): replace calls at each call site
|
||||
- MD (G1, X.509 and TLS): replace calls at each call site (depending on
|
||||
`USE_PSA_CRYPTO`)
|
||||
- MD (G5): silently call PSA when a driver is available, see
|
||||
`md-cipher-dispatch.md`.
|
||||
|
||||
|
||||
Supporting builds with drivers without the software implementation
|
||||
@ -219,10 +232,6 @@ Supporting builds with drivers without the software implementation
|
||||
This section presents a plan towards G5: save code size by compiling out our
|
||||
software implementation when a driver is available.
|
||||
|
||||
Additionally, we want to save code size by compiling out the
|
||||
abstractions layers that we are not using when `MBEDTLS_USE_PSA_CRYPTO` is
|
||||
enabled (see previous section): MD and Cipher.
|
||||
|
||||
Let's expand a bit on the definition of the goal: in such a configuration
|
||||
(driver used, software implementation and abstraction layer compiled out),
|
||||
we want:
|
||||
@ -238,9 +247,10 @@ at feature parity with software-based builds.
|
||||
We can roughly divide the work needed to get there in the following steps:
|
||||
|
||||
0. Have a working driver interface for the algorithms we want to replace.
|
||||
1. Have users of these algorithms call to PSA, not the legacy API, for all
|
||||
operations. (This is G1, and for PK, X.509 and TLS this is controlled by
|
||||
`MBEDTLS_USE_PSA_CRYPTO`.) This needs to be done in the library and tests.
|
||||
1. Have users of these algorithms call to PSA or an abstraction layer than can
|
||||
dispatch to PSA, but not the low-level legacy API, for all operations.
|
||||
(This is G1, and for PK, X.509 and TLS this is controlled by
|
||||
`MBEDTLS_USE_PSA_CRYPTO`.) This needs to be done in the library and tests.
|
||||
2. Have users of these algorithms not depend on the legacy API for information
|
||||
management (getting a size for a given algorithm, etc.)
|
||||
3. Adapt compile-time guards used to query availability of a given algorithm;
|
||||
@ -262,50 +272,32 @@ not possible to achieve good test coverage at the end of step 1 or step 2, it
|
||||
is preferable to group with the next step(s) in the same PR until good test
|
||||
coverage can be reached.
|
||||
|
||||
**Status as of Mbed TLS 3.2:**
|
||||
**Status as of end of March 2023 (shortly after 3.4):**
|
||||
|
||||
- Step 0 is achieved for most algorithms, with only a few gaps remaining.
|
||||
- Step 1 is achieved for most of PK, X.509, and TLS when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled with only a few gaps remaining (see
|
||||
docs/use-psa-crypto.md).
|
||||
- Step 1 is not achieved for a lot of the crypto library including the PSA
|
||||
core. For example, `entropy.c` calls the legacy API
|
||||
`mbedtls_sha256` (or `mbedtls_sha512` optionally); `hmac_drbg.c` calls the
|
||||
legacy API `mbedtls_md` and `ctr_drbg.c` calls the legacy API `mbedtls_aes`;
|
||||
the PSA core depends on the entropy module and at least one of the DRBG
|
||||
modules (unless `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is used). Further, several
|
||||
crypto modules have similar issues, for example RSA PKCS#1 v2.1 calls
|
||||
`mbedtls_md` directly.
|
||||
- Step 1 is achieved for the crypto library regarding hashes: everything uses
|
||||
MD (not low-level hash APIs), which then dispatches to PSA if applicable.
|
||||
- Step 1 is not achieved for all of the crypto library when it come to
|
||||
ciphers. For example,`ctr_drbg.c` calls the legacy API `mbedtls_aes`.
|
||||
- Step 2 is achieved for most of X.509 and TLS (same gaps as step 1) when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled - this was tasks like #5795, #5796,
|
||||
#5797. It is being done in PK and RSA PKCS#1 v1.5 by PR #6065.
|
||||
- Step 3 was mostly not started at all before 3.2; it is being done for PK by
|
||||
PR #6065.
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
- Step 3 is done for hashes and top-level ECC modules (ECDSA, ECDH, ECJPAKE).
|
||||
|
||||
**Strategy for step 1:**
|
||||
|
||||
Regarding PK, X.509, and TLS, this is mostly achieved with only a few gaps.
|
||||
(The strategy was outlined in the previous section.)
|
||||
|
||||
Regarding libmbedcrypto, outside of the RNG subsystem, for modules that
|
||||
currently depend on other legacy crypto modules, this can be achieved without
|
||||
backwards compatibility issues, by using the software implementation if
|
||||
available, and "falling back" to PSA only if it's not. The compile-time
|
||||
dependency changes from the current one (say, `MD_C` or `AES_C`) to "the
|
||||
previous dependency OR PSA Crypto with needed algorithms". When building
|
||||
without software implementation, users need to call `psa_crypto_init()` before
|
||||
calling any function from these modules. This condition does not constitute a
|
||||
break of backwards compatibility, as it was previously impossible to build in
|
||||
those configurations, and in configurations were the build was possible,
|
||||
application code keeps working unchanged. An work-in-progress example of
|
||||
applying this strategy, for RSA PKCS#1 v2.1, is here:
|
||||
<https://github.com/Mbed-TLS/mbedtls/pull/6141>
|
||||
|
||||
There is a problem with the modules used for the PSA RNG, as currently the RNG
|
||||
is initialized before drivers and the key store. This part will need further
|
||||
study, but in the meantime we can proceed with everything that's not the
|
||||
entropy module of one of the DRBG modules, and that does not depend on one of
|
||||
those modules.
|
||||
Regarding libmbedcrypto:
|
||||
- for hashes and ciphers, see `md-cipher-dispatch.md` in the same directory;
|
||||
- for ECC, we have no internal uses of the top-level algorithms (ECDSA, ECDH,
|
||||
ECJPAKE), however they all depend on `ECP_C` which in turn depends on
|
||||
`BIGNUM_C`. So, direct calls from TLS, X.509 and PK to ECP and Bignum will
|
||||
need to be replaced; see <https://github.com/Mbed-TLS/mbedtls/issues/6839> and
|
||||
linked issues for a summary of intermediate steps and open points.
|
||||
|
||||
**Strategy for step 2:**
|
||||
|
||||
@ -315,14 +307,11 @@ convenient, for example in parts of the code that accept old-style identifiers
|
||||
(such as `mbedtls_md_type_t`) in their API and can't assume PSA to be
|
||||
compiled in (such as `rsa.c`).
|
||||
|
||||
It is suggested that, as a temporary solution until we clean this up
|
||||
later when removing the legacy API including its identifiers (G4), we may
|
||||
occasionally use ad-hoc internal functions, such as the ones introduced by PR
|
||||
6065 in `library/hash_info.[ch]`.
|
||||
|
||||
An alternative would be to have two different code paths depending on whether
|
||||
`MBEDTLS_PSA_CRYPTO_C` is defined or not. However this is not great for
|
||||
readability or testability.
|
||||
When using an existing abstraction layer such as MD, it can provide
|
||||
information management functions. In other cases, information that was in a
|
||||
low-level module but logically belongs in a higher-level module can be moved
|
||||
to that module (for example, TLS identifiers of curves and there conversion
|
||||
to/from PSA or legacy identifiers belongs in TLS, not `ecp.c`).
|
||||
|
||||
**Strategy for step 3:**
|
||||
|
||||
@ -338,25 +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
|
||||
`library/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 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).
|
||||
@ -376,15 +355,16 @@ are expressed (sometimes in bulk), to get things wrong in a way that would
|
||||
result in more tests being skipped, which is easy to miss. Care must be
|
||||
taken to ensure this does not happen. The following criteria can be used:
|
||||
|
||||
- the sets of tests skipped in the default config and the full config must be
|
||||
the same before and after the PR that implements step 3;
|
||||
- the set of tests skipped in the driver-only build is the same as in an
|
||||
equivalent software-based configuration, or the difference is small enough,
|
||||
justified, and a github issue is created to track it.
|
||||
|
||||
Note that the favourable case is when the number of tests skipped is 0 in the
|
||||
driver-only build. In other cases, analysis of the outcome files is needed,
|
||||
see the example script `outcome-analysis.sh` in the same directory.
|
||||
1. The sets of tests skipped in the default config and the full config must be
|
||||
the same before and after the PR that implements step 3. This is tested
|
||||
manually for each PR that changes dependency declarations by using the script
|
||||
`outcome-analysis.sh` in the present directory.
|
||||
2. The set of tests skipped in the driver-only build is the same as in an
|
||||
equivalent software-based configuration. This is tested automatically by the
|
||||
CI in the "Results analysis" stage, by running
|
||||
`tests/scripts/analyze_outcomes.py`. See the
|
||||
`analyze_driver_vs_reference_xxx` actions in the script and the comments above
|
||||
their declaration for how to do that locally.
|
||||
|
||||
|
||||
Migrating away from the legacy API
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Mbed Crypto driver interface test strategy
|
||||
# Mbed TLS driver interface test strategy
|
||||
|
||||
This document describes the test strategy for the driver interfaces in Mbed Crypto. Mbed Crypto has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed Crypto itself; testing drivers is out of scope.
|
||||
This document describes the test strategy for the driver interfaces in Mbed TLS. Mbed TLS has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed TLS itself; testing drivers is out of scope.
|
||||
|
||||
The driver interfaces are standardized through PSA Cryptography functional specifications.
|
||||
|
||||
@ -16,9 +16,9 @@ Drivers exposing this interface need to be registered at compile time by declari
|
||||
|
||||
#### Dynamic secure element driver interface
|
||||
|
||||
The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
|
||||
The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed TLS and one or more third-party drivers.
|
||||
|
||||
The SE interface consists of one function provided by Mbed Crypto (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed Crypto, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
|
||||
The SE interface consists of one function provided by Mbed TLS (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed TLS, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
|
||||
|
||||
### SE driver interface unit tests
|
||||
|
||||
@ -57,7 +57,7 @@ For each API function that can lead to a driver call (more precisely, for each d
|
||||
|
||||
#### SE driver outputs
|
||||
|
||||
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed Crypto handles the outputs.
|
||||
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed TLS handles the outputs.
|
||||
|
||||
* Correct outputs.
|
||||
* Incorrect outputs such as an invalid output length.
|
||||
|
@ -47,7 +47,7 @@ The PSA subsystem provides storage on top of the PSA trusted storage interface.
|
||||
* [Storage transaction file](#storage-transaction-resumption).
|
||||
* [Driver state files](#driver-state-files).
|
||||
|
||||
For a more detailed description, refer to the [Mbed Crypto storage specification](../mbed-crypto-storage-specification.md).
|
||||
For a more detailed description, refer to the [Mbed TLS storage specification](../mbed-crypto-storage-specification.md).
|
||||
|
||||
In addition, Mbed TLS includes an implementation of the PSA trusted storage interface on top of C stdio. This document addresses the test strategy for [PSA ITS over file](#psa-its-over-file) in a separate section below.
|
||||
|
||||
|
@ -6,7 +6,7 @@ This document is incomplete. You can help by expanding it.
|
||||
|
||||
## Unit tests
|
||||
|
||||
See <https://tls.mbed.org/kb/development/test_suites>
|
||||
See <https://mbed-tls.readthedocs.io/en/latest/kb/development/test_suites>
|
||||
|
||||
### Unit test descriptions
|
||||
|
||||
|
@ -28,9 +28,12 @@ Support description
|
||||
|
||||
- Mbed TLS does not support DHE key establishment.
|
||||
|
||||
- Mbed TLS does not support pre-shared keys, including any form of
|
||||
session resumption. This implies that it does not support sending early
|
||||
data (0-RTT data).
|
||||
- Mbed TLS supports pre-shared keys for key establishment, pre-shared keys
|
||||
provisioned externally as well as provisioned via the ticket mechanism.
|
||||
|
||||
- Mbed TLS supports session resumption via the ticket mechanism.
|
||||
|
||||
- Mbed TLS does not support sending or receiving early data (0-RTT data).
|
||||
|
||||
- Supported cipher suites: depends on the library configuration. Potentially
|
||||
all of them:
|
||||
@ -54,8 +57,8 @@ Support description
|
||||
| server_certificate_type | no |
|
||||
| padding | no |
|
||||
| key_share | YES |
|
||||
| pre_shared_key | no |
|
||||
| psk_key_exchange_modes | no |
|
||||
| pre_shared_key | YES |
|
||||
| psk_key_exchange_modes | YES |
|
||||
| early_data | no |
|
||||
| cookie | no |
|
||||
| supported_versions | YES |
|
||||
@ -83,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
|
||||
@ -118,7 +115,7 @@ Support description
|
||||
| MBEDTLS_SSL_RENEGOTIATION | n/a |
|
||||
| MBEDTLS_SSL_MAX_FRAGMENT_LENGTH | no |
|
||||
| | |
|
||||
| MBEDTLS_SSL_SESSION_TICKETS | no |
|
||||
| MBEDTLS_SSL_SESSION_TICKETS | yes |
|
||||
| MBEDTLS_SSL_SERVER_NAME_INDICATION | yes |
|
||||
| MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH | no |
|
||||
| | |
|
||||
@ -141,10 +138,33 @@ Support description
|
||||
| MBEDTLS_USE_PSA_CRYPTO | yes |
|
||||
|
||||
(1) These options must remain in their default state of enabled.
|
||||
(2) Key exchange configuration options for TLS 1.3 will likely to be
|
||||
organized around the notion of key exchange mode along the line
|
||||
of the MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE/PSK/PSK_EPHEMERAL/EPHEMERAL
|
||||
runtime configuration macros.
|
||||
(2) See the TLS 1.3 specific build options section below.
|
||||
|
||||
- TLS 1.3 specific build options:
|
||||
|
||||
- MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE enables the support for middlebox
|
||||
compatibility mode as defined in section D.4 of RFC 8446.
|
||||
|
||||
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED enables the support for
|
||||
the PSK key exchange mode as defined by RFC 8446. If it is the only key
|
||||
exchange mode enabled, the TLS 1.3 implementation does not contain any code
|
||||
related to key exchange protocols, certificates and signatures.
|
||||
|
||||
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED enables the
|
||||
support for the ephemeral key exchange mode. If it is the only key exchange
|
||||
mode enabled, the TLS 1.3 implementation does not contain any code related
|
||||
to PSK based key exchange. The ephemeral key exchange mode requires at least
|
||||
one of the key exchange protocol allowed by the TLS 1.3 specification, the
|
||||
parsing and validation of x509 certificates and at least one signature
|
||||
algorithm allowed by the TLS 1.3 specification for signature computing and
|
||||
verification.
|
||||
|
||||
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED enables the
|
||||
support for the PSK ephemeral key exchange mode. If it is the only key
|
||||
exchange mode enabled, the TLS 1.3 implementation does not contain any code
|
||||
related to certificates and signatures. The PSK ephemeral key exchange
|
||||
mode requires at least one of the key exchange protocol allowed by the
|
||||
TLS 1.3 specification.
|
||||
|
||||
|
||||
Prototype upstreaming status
|
||||
@ -152,8 +172,7 @@ Prototype upstreaming status
|
||||
|
||||
The following parts of the TLS 1.3 prototype remain to be upstreamed:
|
||||
|
||||
- Pre-shared keys, session resumption and 0-RTT data (both client and server
|
||||
side).
|
||||
- Sending (client) and receiving (server) early data (0-RTT data).
|
||||
|
||||
- New TLS Message Processing Stack (MPS)
|
||||
|
||||
@ -181,7 +200,7 @@ Coding rules checklist for TLS 1.3
|
||||
The following coding rules are aimed to be a checklist for TLS 1.3 upstreaming
|
||||
work to reduce review rounds and the number of comments in each round. They
|
||||
come along (do NOT replace) the project coding rules
|
||||
(https://tls.mbed.org/kb/development/mbedtls-coding-standards). They have been
|
||||
(https://mbed-tls.readthedocs.io/en/latest/kb/development/mbedtls-coding-standards). They have been
|
||||
established and discussed following the review of #4882 that was the
|
||||
PR upstreaming the first part of TLS 1.3 ClientHello writing code.
|
||||
|
||||
@ -453,3 +472,175 @@ outbound message on server side as well.
|
||||
|
||||
* state change: the state change is done in the main state handler to ease
|
||||
the navigation of the state machine transitions.
|
||||
|
||||
|
||||
Writing and reading early or 0-RTT data
|
||||
---------------------------------------
|
||||
|
||||
An application function to write and send a buffer of data to a server through
|
||||
TLS may plausibly look like:
|
||||
|
||||
```
|
||||
int write_data( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *data_to_write,
|
||||
size_t data_to_write_len,
|
||||
size_t *data_written )
|
||||
{
|
||||
*data_written = 0;
|
||||
|
||||
while( *data_written < data_to_write_len )
|
||||
{
|
||||
ret = mbedtls_ssl_write( ssl, data_to_write + *data_written,
|
||||
data_to_write_len - *data_written );
|
||||
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*data_written += ret;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
```
|
||||
where ssl is the SSL context to use, data_to_write the address of the data
|
||||
buffer and data_to_write_len the number of data bytes. The handshake may
|
||||
not be completed, not even started for the SSL context ssl when the function is
|
||||
called and in that case the mbedtls_ssl_write() API takes care transparently of
|
||||
completing the handshake before to write and send data to the server. The
|
||||
mbedtls_ssl_write() may not been able to write and send all data in one go thus
|
||||
the need for a loop calling it as long as there are still data to write and
|
||||
send.
|
||||
|
||||
An application function to write and send early data and only early data,
|
||||
data sent during the first flight of client messages while the handshake is in
|
||||
its initial phase, would look completely similar but the call to
|
||||
mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write().
|
||||
```
|
||||
int write_early_data( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *data_to_write,
|
||||
size_t data_to_write_len,
|
||||
size_t *data_written )
|
||||
{
|
||||
*data_written = 0;
|
||||
|
||||
while( *data_written < data_to_write_len )
|
||||
{
|
||||
ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written,
|
||||
data_to_write_len - *data_written );
|
||||
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*data_written += ret;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
```
|
||||
Note that compared to write_data(), write_early_data() can also return
|
||||
MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled
|
||||
specifically by the user of write_early_data(). A fresh SSL context (typically
|
||||
just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would
|
||||
be expected when calling `write_early_data`.
|
||||
|
||||
All together, code to write and send a buffer of data as long as possible as
|
||||
early data and then as standard post-handshake application data could
|
||||
plausibly look like:
|
||||
|
||||
```
|
||||
ret = write_early_data( ssl, data_to_write, data_to_write_len,
|
||||
&early_data_written );
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = write_data( ssl, data_to_write + early_data_written,
|
||||
data_to_write_len - early_data_written, &data_written );
|
||||
if( ret < 0 )
|
||||
goto error;
|
||||
|
||||
data_written += early_data_written;
|
||||
```
|
||||
|
||||
Finally, taking into account that the server may reject early data, application
|
||||
code to write and send a buffer of data could plausibly look like:
|
||||
```
|
||||
ret = write_early_data( ssl, data_to_write, data_to_write_len,
|
||||
&early_data_written );
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the handshake is completed as it is a requisite to
|
||||
* mbedtls_ssl_get_early_data_status().
|
||||
*/
|
||||
while( !mbedtls_ssl_is_handshake_over( ssl ) )
|
||||
{
|
||||
ret = mbedtls_ssl_handshake( ssl );
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_get_early_data_status( ssl );
|
||||
if( ret < 0 )
|
||||
goto error;
|
||||
|
||||
if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED )
|
||||
early_data_written = 0;
|
||||
|
||||
ret = write_data( ssl, data_to_write + early_data_written,
|
||||
data_to_write_len - early_data_written, &data_written );
|
||||
if( ret < 0 )
|
||||
goto error;
|
||||
|
||||
data_written += early_data_written;
|
||||
```
|
||||
|
||||
Basically, the same holds for reading early data on the server side without the
|
||||
complication of possible rejection. An application function to read early data
|
||||
into a given buffer could plausibly look like:
|
||||
```
|
||||
int read_early_data( mbedtls_ssl_context *ssl,
|
||||
unsigned char *buffer,
|
||||
size_t buffer_size,
|
||||
size_t *data_len )
|
||||
{
|
||||
*data_len = 0;
|
||||
|
||||
while( *data_len < buffer_size )
|
||||
{
|
||||
ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len,
|
||||
buffer_size - *data_len );
|
||||
|
||||
if( ret < 0 &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*data_len += ret;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
```
|
||||
with again calls to read_early_data() expected to be done with a fresh SSL
|
||||
context.
|
||||
|
34
docs/conf.py
Normal file
34
docs/conf.py
Normal 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']
|
@ -1,894 +0,0 @@
|
||||
## Getting started with Mbed Crypto
|
||||
|
||||
### What is Mbed Crypto?
|
||||
|
||||
Mbed Crypto 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)
|
||||
|
||||
The Mbed Crypto library is a reference implementation of the cryptography interface of the Arm Platform Security Architecture (PSA). It is written in portable C.
|
||||
|
||||
The Mbed Crypto library 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 Crypto
|
||||
|
||||
* [Getting the Mbed Crypto library](#getting-the-mbed-crypto-library)
|
||||
* [Building the Mbed Crypto library](#building-the-mbed-crypto-library)
|
||||
* [Using the Mbed Crypto library](#using-the-mbed-crypto-library)
|
||||
* [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 Mbed Crypto library](#more-about-the-mbed-crypto-library)
|
||||
|
||||
### Getting the Mbed Crypto library
|
||||
|
||||
Mbed Crypto releases are available in the [public GitHub repository](https://github.com/ARMmbed/mbed-crypto).
|
||||
|
||||
### Building the Mbed Crypto library
|
||||
|
||||
**Prerequisites to building the library with the provided makefiles:**
|
||||
* GNU Make.
|
||||
* A C toolchain (compiler, linker, archiver).
|
||||
* Python 2 or Python 3 (either works) 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 Mbed Crypto library
|
||||
|
||||
To use the Mbed Crypto APIs, call `psa_crypto_init()` before calling any other API. This initializes the library.
|
||||
|
||||
### Importing a key
|
||||
|
||||
To use a key for cryptography operations in Mbed Crypto, 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
|
||||
|
||||
Mbed Crypto 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
|
||||
|
||||
Mbed Crypto 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.
|
||||
|
||||
Mbed Crypto 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
|
||||
|
||||
Mbed Crypto 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.
|
||||
|
||||
Mbed Crypto 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
|
||||
|
||||
Mbed Crypto 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
|
||||
|
||||
Mbed Crypto 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 TLS1.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
|
||||
|
||||
Mbed Crypto 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
|
||||
|
||||
Mbed Crypto 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://armmbed.github.io/mbed-crypto/html/index.html).
|
20
docs/index.rst
Normal file
20
docs/index.rst
Normal 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
|
@ -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
|
||||
|
||||
@ -36,6 +36,12 @@ A driver therefore consists of:
|
||||
|
||||
Mbed TLS calls driver entry points [as specified in the PSA Cryptography Driver Interface specification](psa-driver-interface.html#driver-entry-points) except as otherwise indicated in this section.
|
||||
|
||||
## Mbed TLS extensions
|
||||
|
||||
The driver description can include Mbed TLS extensions (marked by the namespace "mbedtls"). Mbed TLS extensions are meant to extend/help integrating the driver into the library's infrastructure.
|
||||
* `"mbedtls/h_condition"` (optional, string) can include complex preprocessor definitions to conditionally include header files for a given driver.
|
||||
* `"mbedtls/c_condition"` (optional, string) can include complex preprocessor definitions to conditionally enable dispatch capabilities for a driver.
|
||||
|
||||
## Building and testing your driver
|
||||
|
||||
<!-- TODO -->
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -13,20 +13,28 @@ During the process of implementation there might be minor variations wrt version
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Python3 and Jinja2 rev 2.10.1
|
||||
Python3, Jinja2 rev 2.10.1 and jsonschema rev 3.2.0
|
||||
|
||||
## Feature Version
|
||||
|
||||
1.0
|
||||
1.1
|
||||
|
||||
### What's critical for a migrating user
|
||||
|
||||
The Driver Wrapper auto generation project is designed to use a python templating library ( Jinja2 ) to render templates based on drivers that are defined using a Driver description JSON file(s).
|
||||
|
||||
While that is the larger goal, for version 1.0 here's what's changed
|
||||
While that is the larger goal, for version 1.1 here's what's changed
|
||||
|
||||
#### What's changed
|
||||
|
||||
(1) psa_crypto_driver_wrappers.c will from this point on be auto generated.
|
||||
(2) The auto generation is based on the template file at scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja.
|
||||
(3) So while all driver wrapper templating support is yet to come in, the library user will need to patch into the template file as needed, this could be read as replacing the template file with the current psa_crypto_driver_wrappers.c file maintained by the library user.
|
||||
(2) The auto generation is based on the template file at **scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja**.
|
||||
(3) The driver JSONS to be used for generating the psa_crypto_driver_wrappers.c file can be found at **scripts/data_files/driver_jsons/** as their default location, this path includes the schemas against which the driver schemas will be validated (driver_opaque_schema.json, driver_transparent_schema.json) and a driverlist.json which specifies the drivers to be considered and the order in which they want to be called into. The default location for driverlist.json and driver JSONS can be overloaded by passing an argument --json-dir while running the script generate_driver_wrappers.py.
|
||||
(4) While the complete driver wrapper templating support is yet to come in, if the library user sees a need to patch psa_crypto_driver_wrappers.c file, the user will need to patch into the template file as needed (psa_crypto_driver_wrappers.c.jinja).
|
||||
|
||||
#### How to set your driver up
|
||||
|
||||
Please refer to psa-driver-interface.md for information on how a driver schema can be written.
|
||||
One can also refer to the example test drivers/ JSON schemas under **scripts/data_files/driver_jsons/**.
|
||||
|
||||
The JSON file 'driverlist.json' is meant to be edited by the user to reflect the drivers one wants to use on a device. The order in which the drivers are passed is also essential if/when there are multiple transparent drivers on a given system to retain the same order in the templating.
|
||||
|
175
docs/psa-driver-example-and-guide.md
Normal file
175
docs/psa-driver-example-and-guide.md
Normal 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.
|
11
docs/redirects.yaml
Normal file
11
docs/redirects.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
# Readthedocs redirects
|
||||
# See https://docs.readthedocs.io/en/stable/user-defined-redirects.html
|
||||
#
|
||||
# Changes to this file do not take effect until they are merged into the
|
||||
# 'development' branch. This is because the API token (RTD_TOKEN) is not
|
||||
# made available in PR jobs - preventing bad actors from crafting PRs to
|
||||
# expose it.
|
||||
|
||||
- type: exact
|
||||
from_url: /projects/api/en/latest/$rest
|
||||
to_url: /projects/api/en/development/
|
3
docs/requirements.in
Normal file
3
docs/requirements.in
Normal file
@ -0,0 +1,3 @@
|
||||
breathe
|
||||
readthedocs-cli
|
||||
sphinx-rtd-theme
|
82
docs/requirements.txt
Normal file
82
docs/requirements.txt
Normal file
@ -0,0 +1,82 @@
|
||||
#
|
||||
# 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
|
||||
click==8.1.3
|
||||
# via readthedocs-cli
|
||||
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
|
||||
markdown-it-py==2.2.0
|
||||
# via rich
|
||||
markupsafe==2.1.2
|
||||
# via jinja2
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
packaging==23.0
|
||||
# via sphinx
|
||||
pygments==2.14.0
|
||||
# via
|
||||
# rich
|
||||
# sphinx
|
||||
pyyaml==6.0
|
||||
# via readthedocs-cli
|
||||
readthedocs-cli==4
|
||||
# via -r requirements.in
|
||||
requests==2.28.2
|
||||
# via
|
||||
# readthedocs-cli
|
||||
# sphinx
|
||||
rich==13.3.5
|
||||
# via readthedocs-cli
|
||||
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
|
@ -1,25 +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
|
||||
----------------------
|
||||
|
||||
**Compile-time:** enabling `MBEDTLS_USE_PSA_CRYPTO` requires
|
||||
`MBEDTLS_ECP_RESTARTABLE` to be disabled.
|
||||
|
||||
**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
|
||||
-------------------------
|
||||
@ -63,6 +106,19 @@ register a PSA key for use with a PSK key exchange.
|
||||
**Use in TLS:** opt-in. The application needs to register the key using one of
|
||||
the new APIs to get the benefits.
|
||||
|
||||
### PSA-held (opaque) keys for TLS 1.2 EC J-PAKE key exchange
|
||||
|
||||
**New API function:** `mbedtls_ssl_set_hs_ecjpake_password_opaque()`.
|
||||
Call this function from an application to register a PSA key for use with the
|
||||
TLS 1.2 EC J-PAKE key exchange.
|
||||
|
||||
**Benefits:** isolation of long-term secrets.
|
||||
|
||||
**Limitations:** none.
|
||||
|
||||
**Use in TLS:** opt-in. The application needs to register the key using one of
|
||||
the new APIs to get the benefits.
|
||||
|
||||
### PSA-based operations in the Cipher layer
|
||||
|
||||
There is a new API function `mbedtls_cipher_setup_psa()` to set up a context
|
||||
@ -86,30 +142,33 @@ is enabled, no change required on the application side.
|
||||
|
||||
Current exceptions:
|
||||
|
||||
- EC J-PAKE (when `MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED` is defined)
|
||||
- finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
|
||||
DHE-PSK)
|
||||
- Finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
|
||||
DHE-PSK).
|
||||
- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
|
||||
the documentation of that option).
|
||||
|
||||
Other than the above exceptions, all crypto operations are based on PSA when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
### X.509: most crypto operations based on PSA
|
||||
|
||||
Current exception:
|
||||
Current exceptions:
|
||||
|
||||
- verification of RSA-PSS signatures with a salt length that is different from
|
||||
the hash length.
|
||||
- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
|
||||
the documentation of that option).
|
||||
|
||||
Other than the above exception, all crypto operations are based on PSA when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
### PK layer: most crypto operations based on PSA
|
||||
|
||||
Current exception:
|
||||
Current exceptions:
|
||||
|
||||
- verification of RSA-PSS signatures with a salt length that is different from
|
||||
the hash length, or with an MGF hash that's different from the message hash.
|
||||
- Verification of RSA-PSS signatures with an MGF hash that's different from
|
||||
the message hash.
|
||||
- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
|
||||
the documentation of that option).
|
||||
|
||||
Other than the above exception, all crypto operations are based on PSA when
|
||||
Other than the above exceptions, all crypto operations are based on PSA when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
* All symmetric encryption algorithms are accessible via the generic cipher layer
|
||||
* (see \c mbedtls_cipher_setup()).
|
||||
*
|
||||
* The asymmetric encryptrion algorithms are accessible via the generic public
|
||||
* The asymmetric encryption algorithms are accessible via the generic public
|
||||
* key layer (see \c mbedtls_pk_init()).
|
||||
*
|
||||
* The following algorithms are provided:
|
||||
|
@ -22,73 +22,10 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage mbed TLS v3.2.1 source code documentation
|
||||
* @mainpage Mbed TLS v3.4.0 API Documentation
|
||||
*
|
||||
* This documentation describes the internal structure of mbed TLS. It was
|
||||
* This documentation describes the internal structure of Mbed TLS. It was
|
||||
* automatically generated from specially formatted comment blocks in
|
||||
* mbed TLS's source code using Doxygen. (See
|
||||
* http://www.stack.nl/~dimitri/doxygen/ for more information on Doxygen)
|
||||
*
|
||||
* mbed TLS has a simple setup: it provides the ingredients for an SSL/TLS
|
||||
* implementation. These ingredients are listed as modules in the
|
||||
* \ref mainpage_modules "Modules section". This "Modules section" introduces
|
||||
* the high-level module concepts used throughout this documentation.\n
|
||||
* Some examples of mbed TLS usage can be found in the \ref mainpage_examples
|
||||
* "Examples section".
|
||||
*
|
||||
* @section mainpage_modules Modules
|
||||
*
|
||||
* mbed TLS supports TLSv1.0 up to TLSv1.2 communication by providing the
|
||||
* following:
|
||||
* - TCP/IP communication functions: listen, connect, accept, read/write.
|
||||
* - SSL/TLS communication functions: init, handshake, read/write.
|
||||
* - X.509 functions: CRT, CRL and key handling
|
||||
* - Random number generation
|
||||
* - Hashing
|
||||
* - Encryption/decryption
|
||||
*
|
||||
* Above functions are split up neatly into logical interfaces. These can be
|
||||
* used separately to provide any of the above functions or to mix-and-match
|
||||
* into an SSL server/client solution that utilises a X.509 PKI. Examples of
|
||||
* such implementations are amply provided with the source code.
|
||||
*
|
||||
* Note that mbed TLS does not provide a control channel or (multiple) session
|
||||
* handling without additional work from the developer.
|
||||
*
|
||||
* @section mainpage_examples Examples
|
||||
*
|
||||
* Example server setup:
|
||||
*
|
||||
* \b Prerequisites:
|
||||
* - X.509 certificate and private key
|
||||
* - session handling functions
|
||||
*
|
||||
* \b Setup:
|
||||
* - Load your certificate and your private RSA key (X.509 interface)
|
||||
* - Setup the listening TCP socket (TCP/IP interface)
|
||||
* - Accept incoming client connection (TCP/IP interface)
|
||||
* - Initialise as an SSL-server (SSL/TLS interface)
|
||||
* - Set parameters, e.g. authentication, ciphers, CA-chain, key exchange
|
||||
* - Set callback functions RNG, IO, session handling
|
||||
* - Perform an SSL-handshake (SSL/TLS interface)
|
||||
* - Read/write data (SSL/TLS interface)
|
||||
* - Close and cleanup (all interfaces)
|
||||
*
|
||||
* Example client setup:
|
||||
*
|
||||
* \b Prerequisites:
|
||||
* - X.509 certificate and private key
|
||||
* - X.509 trusted CA certificates
|
||||
*
|
||||
* \b Setup:
|
||||
* - Load the trusted CA certificates (X.509 interface)
|
||||
* - Load your certificate and your private RSA key (X.509 interface)
|
||||
* - Setup a TCP/IP connection (TCP/IP interface)
|
||||
* - Initialise as an SSL-client (SSL/TLS interface)
|
||||
* - Set parameters, e.g. authentication mode, ciphers, CA-chain, session
|
||||
* - Set callback functions RNG, IO
|
||||
* - Perform an SSL-handshake (SSL/TLS interface)
|
||||
* - Verify the server certificate (SSL/TLS interface)
|
||||
* - Write/read data (SSL/TLS interface)
|
||||
* - Close and cleanup (all interfaces)
|
||||
* Mbed TLS's source code using Doxygen. (See
|
||||
* https://www.doxygen.nl for more information on Doxygen)
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
PROJECT_NAME = "mbed TLS v3.2.1"
|
||||
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
|
||||
@ -27,3 +28,27 @@ HAVE_DOT = YES
|
||||
DOT_GRAPH_MAX_NODES = 200
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
|
||||
# We mostly use \retval declarations to document which error codes a function
|
||||
# can return. The reader can follow the hyperlink to the definition of the
|
||||
# constant to get the generic documentation of that error code. If we don't
|
||||
# have anything to say about the specific error code for the specific
|
||||
# function, we can leave the description part of the \retval command blank.
|
||||
# This is perfectly valid as far as Doxygen is concerned. However, with
|
||||
# Clang >=15, the -Wdocumentation option emits a warning for empty
|
||||
# descriptions.
|
||||
# https://github.com/Mbed-TLS/mbedtls/issues/6960
|
||||
# https://github.com/llvm/llvm-project/issues/60315
|
||||
# As a workaround, you can write something like
|
||||
# \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)=" \
|
||||
|
||||
|
@ -61,11 +61,6 @@
|
||||
/** Invalid input data. */
|
||||
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021
|
||||
|
||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||
!defined(inline) && !defined(__cplusplus)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -77,19 +72,18 @@ extern "C" {
|
||||
/**
|
||||
* \brief The AES context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aes_context
|
||||
{
|
||||
typedef struct mbedtls_aes_context {
|
||||
int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */
|
||||
size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES
|
||||
round keys in the buffer. */
|
||||
round keys in the buffer. */
|
||||
uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can
|
||||
hold 32 extra Bytes, which can be used for
|
||||
one of the following purposes:
|
||||
<ul><li>Alignment if VIA padlock is
|
||||
used.</li>
|
||||
<li>Simplifying key expansion in the 256-bit
|
||||
case by generating an extra round key.
|
||||
</li></ul> */
|
||||
hold 32 extra Bytes, which can be used for
|
||||
one of the following purposes:
|
||||
<ul><li>Alignment if VIA padlock is
|
||||
used.</li>
|
||||
<li>Simplifying key expansion in the 256-bit
|
||||
case by generating an extra round key.
|
||||
</li></ul> */
|
||||
}
|
||||
mbedtls_aes_context;
|
||||
|
||||
@ -97,12 +91,11 @@ mbedtls_aes_context;
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aes_xts_context
|
||||
{
|
||||
typedef struct mbedtls_aes_xts_context {
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(crypt); /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
encryption or decryption. */
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(tweak); /*!< The AES context used for tweak
|
||||
computation. */
|
||||
computation. */
|
||||
} mbedtls_aes_xts_context;
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
@ -118,7 +111,7 @@ typedef struct mbedtls_aes_xts_context
|
||||
*
|
||||
* \param ctx The AES context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aes_init( mbedtls_aes_context *ctx );
|
||||
void mbedtls_aes_init(mbedtls_aes_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES context.
|
||||
@ -127,7 +120,7 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx );
|
||||
* If this is \c NULL, this function does nothing.
|
||||
* Otherwise, the context must have been at least initialized.
|
||||
*/
|
||||
void mbedtls_aes_free( mbedtls_aes_context *ctx );
|
||||
void mbedtls_aes_free(mbedtls_aes_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
@ -138,7 +131,7 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx );
|
||||
*
|
||||
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
|
||||
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES XTS context.
|
||||
@ -147,7 +140,7 @@ void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
|
||||
* If this is \c NULL, this function does nothing.
|
||||
* Otherwise, the context must have been at least initialized.
|
||||
*/
|
||||
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
|
||||
void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/**
|
||||
@ -166,8 +159,8 @@ void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
@ -185,8 +178,8 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
@ -206,9 +199,9 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function prepares an XTS context for decryption and
|
||||
@ -227,9 +220,9 @@ int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/**
|
||||
@ -256,10 +249,10 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
@ -304,12 +297,12 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
|
||||
* on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
@ -349,12 +342,12 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
|
||||
* length is larger than 2^20 blocks (16 MiB).
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
@ -398,13 +391,13 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function performs an AES-CFB8 encryption or decryption
|
||||
@ -443,12 +436,12 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
@ -498,12 +491,12 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
||||
|
||||
@ -581,13 +574,13 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
/**
|
||||
@ -602,9 +595,9 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
/**
|
||||
* \brief Internal AES block decryption function. This is only
|
||||
@ -618,9 +611,9 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
@ -630,7 +623,7 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_aes_self_test( int verbose );
|
||||
int mbedtls_aes_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
|
@ -61,8 +61,7 @@ extern "C" {
|
||||
/**
|
||||
* \brief The ARIA context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aria_context
|
||||
{
|
||||
typedef struct mbedtls_aria_context {
|
||||
unsigned char MBEDTLS_PRIVATE(nr); /*!< The number of rounds (12, 14 or 16) */
|
||||
/*! The ARIA round keys. */
|
||||
uint32_t MBEDTLS_PRIVATE(rk)[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
|
||||
@ -81,7 +80,7 @@ mbedtls_aria_context;
|
||||
*
|
||||
* \param ctx The ARIA context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aria_init( mbedtls_aria_context *ctx );
|
||||
void mbedtls_aria_init(mbedtls_aria_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified ARIA context.
|
||||
@ -90,7 +89,7 @@ void mbedtls_aria_init( mbedtls_aria_context *ctx );
|
||||
* case this function returns immediately. If it is not \c NULL,
|
||||
* it must point to an initialized ARIA context.
|
||||
*/
|
||||
void mbedtls_aria_free( mbedtls_aria_context *ctx );
|
||||
void mbedtls_aria_free(mbedtls_aria_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets the encryption key.
|
||||
@ -107,9 +106,9 @@ void mbedtls_aria_free( mbedtls_aria_context *ctx );
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
@ -126,9 +125,9 @@ int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits );
|
||||
int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function performs an ARIA single-block encryption or
|
||||
@ -150,9 +149,9 @@ int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
|
||||
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
|
||||
int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
|
||||
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
@ -196,12 +195,12 @@ int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
@ -246,13 +245,13 @@ int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
@ -333,13 +332,13 @@ int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
@ -348,7 +347,7 @@ int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
|
||||
*
|
||||
* \return \c 0 on success, or \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_aria_self_test( int verbose );
|
||||
int mbedtls_aria_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user