mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-06-06 05:25:18 +00:00
Move some files to framework repository
Signed-off-by: David Horstmann <david.horstmann@arm.com>
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
# Classify all '.function' files as C for syntax highlighting purposes
|
||||
*.function linguist-language=C
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: To report a bug, please fill this form.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Summary
|
||||
|
||||
|
||||
|
||||
### System information
|
||||
|
||||
Mbed TLS version (number or commit id):
|
||||
Operating system and version:
|
||||
Configuration (if not default, please attach `mbedtls_config.h`):
|
||||
Compiler and options (if you used a pre-built binary, please indicate how you obtained it):
|
||||
Additional environment information:
|
||||
|
||||
### Expected behavior
|
||||
|
||||
|
||||
|
||||
### Actual behavior
|
||||
|
||||
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
|
||||
|
||||
### Additional information
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Mbed TLS security team
|
||||
url: mailto:mbed-tls-security@lists.trustedfirmware.org
|
||||
about: Report a security vulnerability.
|
||||
- name: Mbed TLS mailing list
|
||||
url: https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org
|
||||
about: Mbed TLS community support and general discussion.
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Enhancement request
|
||||
about: To request an enhancement, please fill this form.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Suggested enhancement
|
||||
|
||||
|
||||
|
||||
### Justification
|
||||
|
||||
Mbed TLS needs this because
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
## Description
|
||||
|
||||
Please write a few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
|
||||
|
||||
## PR checklist
|
||||
|
||||
Please tick as appropriate and edit the reasons (e.g.: "backport: not needed because this is a new feature")
|
||||
|
||||
- [ ] **changelog** provided, or not required
|
||||
- [ ] **3.6 backport** done, or not required
|
||||
- [ ] **2.28 backport** done, or not required
|
||||
- [ ] **tests** provided, or not required
|
||||
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
Help make review efficient:
|
||||
* Multiple simple commits
|
||||
- please structure your PR into a series of small commits, each of which does one thing
|
||||
* Avoid force-push
|
||||
- please do not force-push to update your PR - just add new commit(s)
|
||||
* See our [Guidelines for Contributors](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/) for more details about the review process.
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
# Random seed file created by test scripts and sample programs
|
||||
seedfile
|
||||
# MBEDTLS_PSA_INJECT_ENTROPY seed file created by the test framework
|
||||
00000000ffffff52.psa_its
|
||||
|
||||
# CMake build artifacts:
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CTestTestfile.cmake
|
||||
cmake_install.cmake
|
||||
Testing
|
||||
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
|
||||
*.dir/
|
||||
# MSVC files generated by CMake:
|
||||
/*.sln
|
||||
/*.vcxproj
|
||||
/*.filters
|
||||
|
||||
# Test coverage build artifacts:
|
||||
Coverage
|
||||
*.gcno
|
||||
*.gcda
|
||||
coverage-summary.txt
|
||||
|
||||
# generated by scripts/memory.sh
|
||||
massif-*
|
||||
|
||||
# Eclipse project files
|
||||
.cproject
|
||||
.project
|
||||
/.settings
|
||||
|
||||
# Unix-like build artifacts:
|
||||
*.o
|
||||
|
||||
# MSVC build artifacts:
|
||||
*.exe
|
||||
*.pdb
|
||||
*.ilk
|
||||
*.lib
|
||||
|
||||
# Python build artifacts:
|
||||
*.pyc
|
||||
|
||||
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
|
||||
*.dir/
|
||||
|
||||
# Microsoft CMake extension for Visual Studio Code generates a build directory by default
|
||||
/build/
|
||||
|
||||
# Generated documentation:
|
||||
/apidoc
|
||||
|
||||
# PSA Crypto compliance test repo, cloned by test_psa_compliance.py
|
||||
/psa-arch-tests
|
||||
|
||||
# Editor navigation files:
|
||||
/GPATH
|
||||
/GRTAGS
|
||||
/GSYMS
|
||||
/GTAGS
|
||||
/TAGS
|
||||
/cscope*.out
|
||||
/tags
|
||||
|
||||
# clangd compilation database
|
||||
compile_commands.json
|
||||
# clangd index files
|
||||
/.cache/clangd/index/
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "framework"]
|
||||
path = framework
|
||||
url = https://github.com/Mbed-TLS/mbedtls-framework
|
||||
@@ -1,4 +0,0 @@
|
||||
[mypy]
|
||||
mypy_path = scripts
|
||||
namespace_packages = True
|
||||
warn_unused_configs = True
|
||||
@@ -1,80 +0,0 @@
|
||||
[MASTER]
|
||||
init-hook='import sys; sys.path.append("scripts")'
|
||||
min-similarity-lines=10
|
||||
|
||||
[BASIC]
|
||||
# We're ok with short funtion argument names.
|
||||
# [invalid-name]
|
||||
argument-rgx=[a-z_][a-z0-9_]*$
|
||||
|
||||
# Allow filter and map.
|
||||
# [bad-builtin]
|
||||
bad-functions=input
|
||||
|
||||
# We prefer docstrings, but we don't require them on all functions.
|
||||
# Require them only on long functions (for some value of long).
|
||||
# [missing-docstring]
|
||||
docstring-min-length=10
|
||||
|
||||
# No upper limit on method names. Pylint <2.1.0 has an upper limit of 30.
|
||||
# [invalid-name]
|
||||
method-rgx=[a-z_][a-z0-9_]{2,}$
|
||||
|
||||
# Allow module names containing a dash (but no underscore or uppercase letter).
|
||||
# They are whole programs, not meant to be included by another module.
|
||||
# [invalid-name]
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|[a-z][-0-9a-z]+)$
|
||||
|
||||
# Some functions don't need docstrings.
|
||||
# [missing-docstring]
|
||||
no-docstring-rgx=(run_)?main$
|
||||
|
||||
# We're ok with short local or global variable names.
|
||||
# [invalid-name]
|
||||
variable-rgx=[a-z_][a-z0-9_]*$
|
||||
|
||||
[DESIGN]
|
||||
# Allow more than the default 7 attributes.
|
||||
# [too-many-instance-attributes]
|
||||
max-attributes=15
|
||||
|
||||
[FORMAT]
|
||||
# Allow longer modules than the default recommended maximum.
|
||||
# [too-many-lines]
|
||||
max-module-lines=2000
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
# * locally-disabled, locally-enabled: If we disable or enable a message
|
||||
# locally, it's by design. There's no need to clutter the Pylint output
|
||||
# with this information.
|
||||
# * logging-format-interpolation: Pylint warns about things like
|
||||
# ``log.info('...'.format(...))``. It insists on ``log.info('...', ...)``.
|
||||
# This is of minor utility (mainly a performance gain when there are
|
||||
# many messages that use formatting and are below the log level).
|
||||
# Some versions of Pylint (including 1.8, which is the version on
|
||||
# Ubuntu 18.04) only recognize old-style format strings using '%',
|
||||
# and complain about something like ``log.info('{}', foo)`` with
|
||||
# logging-too-many-args (Pylint supports new-style formatting if
|
||||
# declared globally with logging_format_style under [LOGGING] but
|
||||
# this requires Pylint >=2.2).
|
||||
# * no-else-return: Allow the perfectly reasonable idiom
|
||||
# if condition1:
|
||||
# return value1
|
||||
# else:
|
||||
# return value2
|
||||
# * unnecessary-pass: If we take the trouble of adding a line with "pass",
|
||||
# it's because we think the code is clearer that way.
|
||||
disable=locally-disabled,locally-enabled,logging-format-interpolation,no-else-return,unnecessary-pass
|
||||
|
||||
[REPORTS]
|
||||
# Don't diplay statistics. Just the facts.
|
||||
reports=no
|
||||
|
||||
[VARIABLES]
|
||||
# Allow unused variables if their name starts with an underscore.
|
||||
# [unused-argument]
|
||||
dummy-variables-rgx=_.*
|
||||
|
||||
[SIMILARITIES]
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=yes
|
||||
@@ -1,37 +0,0 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Include the framework submodule in the build
|
||||
submodules:
|
||||
include:
|
||||
- framework
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.9"
|
||||
jobs:
|
||||
pre_build:
|
||||
- ./scripts/apidoc_full.sh
|
||||
- breathe-apidoc -o docs/api apidoc/xml
|
||||
post_build:
|
||||
- |
|
||||
# Work around Readthedocs bug: Command parsing fails if the 'if' statement is on the first line
|
||||
if [ "$READTHEDOCS_VERSION" = "development" ]; then
|
||||
"$READTHEDOCS_VIRTUALENV_PATH/bin/rtd" projects "Mbed TLS API" redirects sync --wet-run -f docs/redirects.yaml
|
||||
fi
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
builder: dirhtml
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
# Declare python as our language. This way we get our chosen Python version,
|
||||
# and pip is available. Gcc and clang are available anyway.
|
||||
dist: jammy
|
||||
os: linux
|
||||
language: python
|
||||
python: 3.10
|
||||
|
||||
cache: ccache
|
||||
|
||||
branches:
|
||||
only:
|
||||
coverity_scan
|
||||
|
||||
install:
|
||||
- $PYTHON scripts/min_requirements.py
|
||||
|
||||
env:
|
||||
global:
|
||||
- SEED=1
|
||||
- secure: "GF/Fde5fkm15T/RNykrjrPV5Uh1KJ70cP308igL6Xkk3eJmqkkmWCe9JqRH12J3TeWw2fu9PYPHt6iFSg6jasgqysfUyg+W03knRT5QNn3h5eHgt36cQJiJr6t3whPrRaiM6U9omE0evm+c0cAwlkA3GGSMw8Z+na4EnKI6OFCo="
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "ARMmbed/mbedtls"
|
||||
notification_email: support-mbedtls@arm.com
|
||||
build_command_prepend:
|
||||
build_command: make
|
||||
branch_pattern: coverity_scan
|
||||
-240
@@ -1,240 +0,0 @@
|
||||
# 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 OR GPL-2.0-or-later
|
||||
|
||||
|
||||
# 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
|
||||
@@ -1 +0,0 @@
|
||||
/Makefile
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
add_subdirectory(everest)
|
||||
add_subdirectory(p256-m)
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
THIRDPARTY_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
include $(THIRDPARTY_DIR)/everest/Makefile.inc
|
||||
include $(THIRDPARTY_DIR)/p256-m/Makefile.inc
|
||||
@@ -1 +0,0 @@
|
||||
Makefile
|
||||
Vendored
-42
@@ -1,42 +0,0 @@
|
||||
set(everest_target "${MBEDTLS_TARGET_PREFIX}everest")
|
||||
|
||||
add_library(${everest_target}
|
||||
library/everest.c
|
||||
library/x25519.c
|
||||
library/Hacl_Curve25519_joined.c)
|
||||
|
||||
target_include_directories(${everest_target}
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PRIVATE include/everest
|
||||
include/everest/kremlib
|
||||
${MBEDTLS_DIR}/library/)
|
||||
|
||||
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
|
||||
# This must be duplicated from library/CMakeLists.txt because
|
||||
# everest is not directly linked against any mbedtls targets
|
||||
# so does not inherit the compile definitions.
|
||||
if(MBEDTLS_CONFIG_FILE)
|
||||
target_compile_definitions(${everest_target}
|
||||
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
|
||||
endif()
|
||||
if(MBEDTLS_USER_CONFIG_FILE)
|
||||
target_compile_definitions(${everest_target}
|
||||
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
|
||||
endif()
|
||||
|
||||
if(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
install(DIRECTORY include/everest
|
||||
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 ${everest_target}
|
||||
EXPORT MbedTLSTargets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/everest/include -I$(THIRDPARTY_DIR)/everest/include/everest -I$(THIRDPARTY_DIR)/everest/include/everest/kremlib
|
||||
|
||||
THIRDPARTY_CRYPTO_OBJECTS+= \
|
||||
$(THIRDPARTY_DIR)/everest/library/everest.o \
|
||||
$(THIRDPARTY_DIR)/everest/library/x25519.o \
|
||||
$(THIRDPARTY_DIR)/everest/library/Hacl_Curve25519_joined.o
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
The files in this directory stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
|
||||
|
||||
This is a formally verified implementation of Curve25519-based handshakes. The C code is automatically derived from the (verified) [original implementation](https://github.com/project-everest/hacl-star/tree/master/code/curve25519) in the [F* language](https://github.com/fstarlang/fstar) by [KreMLin](https://github.com/fstarlang/kremlin). In addition to the improved safety and security of the implementation, it is also significantly faster than the default implementation of Curve25519 in mbedTLS.
|
||||
|
||||
The caveat is that not all platforms are supported, although the version in `everest/library/legacy` should work on most systems. The main issue is that some platforms do not provide a 128-bit integer type and KreMLin therefore has to use additional (also verified) code to simulate them, resulting in less of a performance gain overall. Explicitly supported platforms are currently `x86` and `x86_64` using gcc or clang, and Visual C (2010 and later).
|
||||
@@ -1,21 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fbuiltin-uint128 -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __Hacl_Curve25519_H
|
||||
#define __Hacl_Curve25519_H
|
||||
|
||||
|
||||
#include "kremlib.h"
|
||||
|
||||
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint);
|
||||
|
||||
#define __Hacl_Curve25519_H_DEFINED
|
||||
#endif
|
||||
-234
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Interface to code from Project Everest
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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 MBEDTLS_EVEREST_H
|
||||
#define MBEDTLS_EVEREST_H
|
||||
|
||||
#include "everest/x25519.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Defines the source of the imported EC key.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MBEDTLS_EVEREST_ECDH_OURS, /**< Our key. */
|
||||
MBEDTLS_EVEREST_ECDH_THEIRS, /**< The key of the peer. */
|
||||
} mbedtls_everest_ecdh_side;
|
||||
|
||||
typedef struct {
|
||||
mbedtls_x25519_context ctx;
|
||||
} mbedtls_ecdh_context_everest;
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function sets up the ECDH context with the information
|
||||
* given.
|
||||
*
|
||||
* This function should be called after mbedtls_ecdh_init() but
|
||||
* before mbedtls_ecdh_make_params(). There is no need to call
|
||||
* this function before mbedtls_ecdh_read_params().
|
||||
*
|
||||
* This is the first function used by a TLS server for ECDHE
|
||||
* ciphersuites.
|
||||
*
|
||||
* \param ctx The ECDH context to set up.
|
||||
* \param grp_id The group id of the group to set up the context for.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_everest_setup( mbedtls_ecdh_context_everest *ctx, int grp_id );
|
||||
|
||||
/**
|
||||
* \brief This function frees a context.
|
||||
*
|
||||
* \param ctx The context to free.
|
||||
*/
|
||||
void mbedtls_everest_free( mbedtls_ecdh_context_everest *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function generates a public key and a TLS
|
||||
* ServerKeyExchange payload.
|
||||
*
|
||||
* This is the second function used by a TLS server for ECDHE
|
||||
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
|
||||
*
|
||||
* \note This function assumes that the ECP group (grp) of the
|
||||
* \p ctx context has already been properly set,
|
||||
* for example, using mbedtls_ecp_group_load().
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param olen The number of characters written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The length of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_everest_make_params( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes a TLS ServerKeyExchange
|
||||
* payload.
|
||||
*
|
||||
* This is the first function used by a TLS client for ECDHE
|
||||
* ciphersuites.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param buf The pointer to the start of the input buffer.
|
||||
* \param end The address for one Byte past the end of the buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
|
||||
const unsigned char **buf, const unsigned char *end );
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes a TLS ServerKeyExchange
|
||||
* payload.
|
||||
*
|
||||
* This is the first function used by a TLS client for ECDHE
|
||||
* ciphersuites.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param buf The pointer to the start of the input buffer.
|
||||
* \param end The address for one Byte past the end of the buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
|
||||
const unsigned char **buf, const unsigned char *end );
|
||||
|
||||
/**
|
||||
* \brief This function sets up an ECDH context from an EC key.
|
||||
*
|
||||
* It is used by clients and servers in place of the
|
||||
* ServerKeyEchange for static ECDH, and imports ECDH
|
||||
* parameters from the EC key information of a certificate.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context to set up.
|
||||
* \param key The EC key to use.
|
||||
* \param side Defines the source of the key: 1: Our key, or
|
||||
* 0: The key of the peer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_everest_get_params( mbedtls_ecdh_context_everest *ctx, const mbedtls_ecp_keypair *key,
|
||||
mbedtls_everest_ecdh_side side );
|
||||
|
||||
/**
|
||||
* \brief This function generates a public key and a TLS
|
||||
* ClientKeyExchange payload.
|
||||
*
|
||||
* This is the second function used by a TLS client for ECDH(E)
|
||||
* ciphersuites.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param olen The number of Bytes written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The size of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_everest_make_public( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes a TLS ClientKeyExchange
|
||||
* payload.
|
||||
*
|
||||
* This is the third function used by a TLS server for ECDH(E)
|
||||
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
|
||||
* mbedtls_ecdh_make_params().)
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param buf The start of the input buffer.
|
||||
* \param blen The length of the input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_everest_read_public( mbedtls_ecdh_context_everest *ctx,
|
||||
const unsigned char *buf, size_t blen );
|
||||
|
||||
/**
|
||||
* \brief This function derives and exports the shared secret.
|
||||
*
|
||||
* This is the last function used by both TLS client
|
||||
* and servers.
|
||||
*
|
||||
* \note If \p f_rng is not NULL, it is used to implement
|
||||
* countermeasures against side-channel attacks.
|
||||
* For more information, see mbedtls_ecp_mul().
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context.
|
||||
* \param olen The number of Bytes written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The length of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_everest_calc_secret( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_EVEREST_H */
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
*
|
||||
* 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) and
|
||||
* originated from Project Everest (https://project-everest.github.io/)
|
||||
*/
|
||||
|
||||
#ifndef __KREMLIB_H
|
||||
#define __KREMLIB_H
|
||||
|
||||
#include "kremlin/internal/target.h"
|
||||
#include "kremlin/internal/types.h"
|
||||
#include "kremlin/c_endianness.h"
|
||||
|
||||
#endif /* __KREMLIB_H */
|
||||
@@ -1,124 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/uint128 -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/types.h" -bundle FStar.UInt128=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __FStar_UInt128_H
|
||||
#define __FStar_UInt128_H
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "kremlin/internal/types.h"
|
||||
|
||||
uint64_t FStar_UInt128___proj__Mkuint128__item__low(FStar_UInt128_uint128 projectee);
|
||||
|
||||
uint64_t FStar_UInt128___proj__Mkuint128__item__high(FStar_UInt128_uint128 projectee);
|
||||
|
||||
typedef FStar_UInt128_uint128 FStar_UInt128_t;
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s);
|
||||
|
||||
bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a);
|
||||
|
||||
uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Question_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Question_Hat)(
|
||||
FStar_UInt128_uint128 x0,
|
||||
FStar_UInt128_uint128 x1
|
||||
);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Amp_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Hat_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Bar_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Less_Less_Hat)(FStar_UInt128_uint128 x0, uint32_t x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Greater_Greater_Hat)(FStar_UInt128_uint128 x0, uint32_t x1);
|
||||
|
||||
extern bool (*FStar_UInt128_op_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern bool
|
||||
(*FStar_UInt128_op_Greater_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern bool (*FStar_UInt128_op_Less_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern bool
|
||||
(*FStar_UInt128_op_Greater_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern bool
|
||||
(*FStar_UInt128_op_Less_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y);
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y);
|
||||
|
||||
#define __FStar_UInt128_H_DEFINED
|
||||
#endif
|
||||
Vendored
-280
@@ -1,280 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/minimal -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/compat.h" -add-include "kremlin/internal/types.h" -bundle FStar.UInt64+FStar.UInt32+FStar.UInt16+FStar.UInt8=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H
|
||||
#define __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "kremlin/internal/compat.h"
|
||||
#include "kremlin/internal/types.h"
|
||||
|
||||
extern Prims_int FStar_UInt64_n;
|
||||
|
||||
extern Prims_int FStar_UInt64_v(uint64_t x0);
|
||||
|
||||
extern uint64_t FStar_UInt64_uint_to_t(Prims_int x0);
|
||||
|
||||
extern uint64_t FStar_UInt64_add(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_add_underspec(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_add_mod(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_sub(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_sub_underspec(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_sub_mod(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_mul(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_mul_underspec(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_mul_mod(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_mul_div(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_div(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_rem(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_logand(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_logxor(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_logor(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_lognot(uint64_t x0);
|
||||
|
||||
extern uint64_t FStar_UInt64_shift_right(uint64_t x0, uint32_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_shift_left(uint64_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt64_eq(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern bool FStar_UInt64_gt(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern bool FStar_UInt64_gte(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern bool FStar_UInt64_lt(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern bool FStar_UInt64_lte(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_minus(uint64_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt64_n_minus_one;
|
||||
|
||||
uint64_t FStar_UInt64_eq_mask(uint64_t a, uint64_t b);
|
||||
|
||||
uint64_t FStar_UInt64_gte_mask(uint64_t a, uint64_t b);
|
||||
|
||||
extern Prims_string FStar_UInt64_to_string(uint64_t x0);
|
||||
|
||||
extern uint64_t FStar_UInt64_of_string(Prims_string x0);
|
||||
|
||||
extern Prims_int FStar_UInt32_n;
|
||||
|
||||
extern Prims_int FStar_UInt32_v(uint32_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt32_uint_to_t(Prims_int x0);
|
||||
|
||||
extern uint32_t FStar_UInt32_add(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_add_underspec(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_add_mod(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_sub(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_sub_underspec(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_sub_mod(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_mul(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_mul_underspec(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_mul_mod(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_mul_div(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_div(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_rem(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_logand(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_logxor(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_logor(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_lognot(uint32_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt32_shift_right(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_shift_left(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt32_eq(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt32_gt(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt32_gte(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt32_lt(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt32_lte(uint32_t x0, uint32_t x1);
|
||||
|
||||
extern uint32_t FStar_UInt32_minus(uint32_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt32_n_minus_one;
|
||||
|
||||
uint32_t FStar_UInt32_eq_mask(uint32_t a, uint32_t b);
|
||||
|
||||
uint32_t FStar_UInt32_gte_mask(uint32_t a, uint32_t b);
|
||||
|
||||
extern Prims_string FStar_UInt32_to_string(uint32_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt32_of_string(Prims_string x0);
|
||||
|
||||
extern Prims_int FStar_UInt16_n;
|
||||
|
||||
extern Prims_int FStar_UInt16_v(uint16_t x0);
|
||||
|
||||
extern uint16_t FStar_UInt16_uint_to_t(Prims_int x0);
|
||||
|
||||
extern uint16_t FStar_UInt16_add(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_add_underspec(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_add_mod(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_sub(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_sub_underspec(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_sub_mod(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_mul(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_mul_underspec(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_mul_mod(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_mul_div(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_div(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_rem(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_logand(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_logxor(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_logor(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_lognot(uint16_t x0);
|
||||
|
||||
extern uint16_t FStar_UInt16_shift_right(uint16_t x0, uint32_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_shift_left(uint16_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt16_eq(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern bool FStar_UInt16_gt(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern bool FStar_UInt16_gte(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern bool FStar_UInt16_lt(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern bool FStar_UInt16_lte(uint16_t x0, uint16_t x1);
|
||||
|
||||
extern uint16_t FStar_UInt16_minus(uint16_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt16_n_minus_one;
|
||||
|
||||
uint16_t FStar_UInt16_eq_mask(uint16_t a, uint16_t b);
|
||||
|
||||
uint16_t FStar_UInt16_gte_mask(uint16_t a, uint16_t b);
|
||||
|
||||
extern Prims_string FStar_UInt16_to_string(uint16_t x0);
|
||||
|
||||
extern uint16_t FStar_UInt16_of_string(Prims_string x0);
|
||||
|
||||
extern Prims_int FStar_UInt8_n;
|
||||
|
||||
extern Prims_int FStar_UInt8_v(uint8_t x0);
|
||||
|
||||
extern uint8_t FStar_UInt8_uint_to_t(Prims_int x0);
|
||||
|
||||
extern uint8_t FStar_UInt8_add(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_add_underspec(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_add_mod(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_sub(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_sub_underspec(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_sub_mod(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_mul(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_mul_underspec(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_mul_mod(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_mul_div(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_div(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_rem(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_logand(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_logxor(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_logor(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_lognot(uint8_t x0);
|
||||
|
||||
extern uint8_t FStar_UInt8_shift_right(uint8_t x0, uint32_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_shift_left(uint8_t x0, uint32_t x1);
|
||||
|
||||
extern bool FStar_UInt8_eq(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern bool FStar_UInt8_gt(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern bool FStar_UInt8_gte(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern bool FStar_UInt8_lt(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern bool FStar_UInt8_lte(uint8_t x0, uint8_t x1);
|
||||
|
||||
extern uint8_t FStar_UInt8_minus(uint8_t x0);
|
||||
|
||||
extern uint32_t FStar_UInt8_n_minus_one;
|
||||
|
||||
uint8_t FStar_UInt8_eq_mask(uint8_t a, uint8_t b);
|
||||
|
||||
uint8_t FStar_UInt8_gte_mask(uint8_t a, uint8_t b);
|
||||
|
||||
extern Prims_string FStar_UInt8_to_string(uint8_t x0);
|
||||
|
||||
extern uint8_t FStar_UInt8_of_string(Prims_string x0);
|
||||
|
||||
typedef uint8_t FStar_UInt8_byte;
|
||||
|
||||
#define __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H_DEFINED
|
||||
#endif
|
||||
@@ -1,204 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef __KREMLIN_ENDIAN_H
|
||||
#define __KREMLIN_ENDIAN_H
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/* Implementing C.fst (part 2: endian-ness macros) */
|
||||
/******************************************************************************/
|
||||
|
||||
/* ... for Linux */
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
# include <endian.h>
|
||||
|
||||
/* ... for OSX */
|
||||
#elif defined(__APPLE__)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htole64(x) OSSwapHostToLittleInt64(x)
|
||||
# define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
|
||||
# define htole16(x) OSSwapHostToLittleInt16(x)
|
||||
# define le16toh(x) OSSwapLittleToHostInt16(x)
|
||||
# define htobe16(x) OSSwapHostToBigInt16(x)
|
||||
# define be16toh(x) OSSwapBigToHostInt16(x)
|
||||
|
||||
# define htole32(x) OSSwapHostToLittleInt32(x)
|
||||
# define le32toh(x) OSSwapLittleToHostInt32(x)
|
||||
# define htobe32(x) OSSwapHostToBigInt32(x)
|
||||
# define be32toh(x) OSSwapBigToHostInt32(x)
|
||||
|
||||
/* ... for Solaris */
|
||||
#elif defined(__sun__)
|
||||
# include <sys/byteorder.h>
|
||||
# define htole64(x) LE_64(x)
|
||||
# define le64toh(x) LE_64(x)
|
||||
# define htobe64(x) BE_64(x)
|
||||
# define be64toh(x) BE_64(x)
|
||||
|
||||
# define htole16(x) LE_16(x)
|
||||
# define le16toh(x) LE_16(x)
|
||||
# define htobe16(x) BE_16(x)
|
||||
# define be16toh(x) BE_16(x)
|
||||
|
||||
# define htole32(x) LE_32(x)
|
||||
# define le32toh(x) LE_32(x)
|
||||
# define htobe32(x) BE_32(x)
|
||||
# define be32toh(x) BE_32(x)
|
||||
|
||||
/* ... for the BSDs */
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
# include <sys/endian.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
# include <endian.h>
|
||||
|
||||
/* ... for Windows (MSVC)... not targeting XBOX 360! */
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# include <stdlib.h>
|
||||
# define htobe16(x) _byteswap_ushort(x)
|
||||
# define htole16(x) (x)
|
||||
# define be16toh(x) _byteswap_ushort(x)
|
||||
# define le16toh(x) (x)
|
||||
|
||||
# define htobe32(x) _byteswap_ulong(x)
|
||||
# define htole32(x) (x)
|
||||
# define be32toh(x) _byteswap_ulong(x)
|
||||
# define le32toh(x) (x)
|
||||
|
||||
# define htobe64(x) _byteswap_uint64(x)
|
||||
# define htole64(x) (x)
|
||||
# define be64toh(x) _byteswap_uint64(x)
|
||||
# define le64toh(x) (x)
|
||||
|
||||
/* ... for Windows (GCC-like, e.g. mingw or clang) */
|
||||
#elif (defined(_WIN32) || defined(_WIN64)) && \
|
||||
(defined(__GNUC__) || defined(__clang__))
|
||||
|
||||
# define htobe16(x) __builtin_bswap16(x)
|
||||
# define htole16(x) (x)
|
||||
# define be16toh(x) __builtin_bswap16(x)
|
||||
# define le16toh(x) (x)
|
||||
|
||||
# define htobe32(x) __builtin_bswap32(x)
|
||||
# define htole32(x) (x)
|
||||
# define be32toh(x) __builtin_bswap32(x)
|
||||
# define le32toh(x) (x)
|
||||
|
||||
# define htobe64(x) __builtin_bswap64(x)
|
||||
# define htole64(x) (x)
|
||||
# define be64toh(x) __builtin_bswap64(x)
|
||||
# define le64toh(x) (x)
|
||||
|
||||
/* ... generic big-endian fallback code */
|
||||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
/* byte swapping code inspired by:
|
||||
* https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h
|
||||
* */
|
||||
|
||||
# define htobe32(x) (x)
|
||||
# define be32toh(x) (x)
|
||||
# define htole32(x) \
|
||||
(__extension__({ \
|
||||
uint32_t _temp = (x); \
|
||||
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
|
||||
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
|
||||
}))
|
||||
# define le32toh(x) (htole32((x)))
|
||||
|
||||
# define htobe64(x) (x)
|
||||
# define be64toh(x) (x)
|
||||
# define htole64(x) \
|
||||
(__extension__({ \
|
||||
uint64_t __temp = (x); \
|
||||
uint32_t __low = htobe32((uint32_t)__temp); \
|
||||
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
|
||||
(((uint64_t)__low) << 32) | __high; \
|
||||
}))
|
||||
# define le64toh(x) (htole64((x)))
|
||||
|
||||
/* ... generic little-endian fallback code */
|
||||
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
||||
# define htole32(x) (x)
|
||||
# define le32toh(x) (x)
|
||||
# define htobe32(x) \
|
||||
(__extension__({ \
|
||||
uint32_t _temp = (x); \
|
||||
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
|
||||
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
|
||||
}))
|
||||
# define be32toh(x) (htobe32((x)))
|
||||
|
||||
# define htole64(x) (x)
|
||||
# define le64toh(x) (x)
|
||||
# define htobe64(x) \
|
||||
(__extension__({ \
|
||||
uint64_t __temp = (x); \
|
||||
uint32_t __low = htobe32((uint32_t)__temp); \
|
||||
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
|
||||
(((uint64_t)__low) << 32) | __high; \
|
||||
}))
|
||||
# define be64toh(x) (htobe64((x)))
|
||||
|
||||
/* ... couldn't determine endian-ness of the target platform */
|
||||
#else
|
||||
# error "Please define __BYTE_ORDER__!"
|
||||
|
||||
#endif /* defined(__linux__) || ... */
|
||||
|
||||
/* Loads and stores. These avoid undefined behavior due to unaligned memory
|
||||
* accesses, via memcpy. */
|
||||
|
||||
inline static uint16_t load16(uint8_t *b) {
|
||||
uint16_t x;
|
||||
memcpy(&x, b, 2);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline static uint32_t load32(uint8_t *b) {
|
||||
uint32_t x;
|
||||
memcpy(&x, b, 4);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline static uint64_t load64(uint8_t *b) {
|
||||
uint64_t x;
|
||||
memcpy(&x, b, 8);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline static void store16(uint8_t *b, uint16_t i) {
|
||||
memcpy(b, &i, 2);
|
||||
}
|
||||
|
||||
inline static void store32(uint8_t *b, uint32_t i) {
|
||||
memcpy(b, &i, 4);
|
||||
}
|
||||
|
||||
inline static void store64(uint8_t *b, uint64_t i) {
|
||||
memcpy(b, &i, 8);
|
||||
}
|
||||
|
||||
#define load16_le(b) (le16toh(load16(b)))
|
||||
#define store16_le(b, i) (store16(b, htole16(i)))
|
||||
#define load16_be(b) (be16toh(load16(b)))
|
||||
#define store16_be(b, i) (store16(b, htobe16(i)))
|
||||
|
||||
#define load32_le(b) (le32toh(load32(b)))
|
||||
#define store32_le(b, i) (store32(b, htole32(i)))
|
||||
#define load32_be(b) (be32toh(load32(b)))
|
||||
#define store32_be(b, i) (store32(b, htobe32(i)))
|
||||
|
||||
#define load64_le(b) (le64toh(load64(b)))
|
||||
#define store64_le(b, i) (store64(b, htole64(i)))
|
||||
#define load64_be(b) (be64toh(load64(b)))
|
||||
#define store64_be(b, i) (store64(b, htobe64(i)))
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef __KREMLIN_BUILTIN_H
|
||||
#define __KREMLIN_BUILTIN_H
|
||||
|
||||
/* For alloca, when using KreMLin's -falloca */
|
||||
#if (defined(_WIN32) || defined(_WIN64))
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* If some globals need to be initialized before the main, then kremlin will
|
||||
* generate and try to link last a function with this type: */
|
||||
void kremlinit_globals(void);
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef __KREMLIN_CALLCONV_H
|
||||
#define __KREMLIN_CALLCONV_H
|
||||
|
||||
/******************************************************************************/
|
||||
/* Some macros to ease compatibility */
|
||||
/******************************************************************************/
|
||||
|
||||
/* We want to generate __cdecl safely without worrying about it being undefined.
|
||||
* When using MSVC, these are always defined. When using MinGW, these are
|
||||
* defined too. They have no meaning for other platforms, so we define them to
|
||||
* be empty macros in other situations. */
|
||||
#ifndef _MSC_VER
|
||||
#ifndef __cdecl
|
||||
#define __cdecl
|
||||
#endif
|
||||
#ifndef __stdcall
|
||||
#define __stdcall
|
||||
#endif
|
||||
#ifndef __fastcall
|
||||
#define __fastcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Since KreMLin emits the inline keyword unconditionally, we follow the
|
||||
* guidelines at https://gcc.gnu.org/onlinedocs/gcc/Inline.html and make this
|
||||
* __inline__ to ensure the code compiles with -std=c90 and earlier. */
|
||||
#ifdef __GNUC__
|
||||
# define inline __inline__
|
||||
#endif
|
||||
|
||||
/* GCC-specific attribute syntax; everyone else gets the standard C inline
|
||||
* attribute. */
|
||||
#ifdef __GNU_C__
|
||||
# ifndef __clang__
|
||||
# define force_inline inline __attribute__((always_inline))
|
||||
# else
|
||||
# define force_inline inline
|
||||
# endif
|
||||
#else
|
||||
# define force_inline inline
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef KRML_COMPAT_H
|
||||
#define KRML_COMPAT_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/* A series of macros that define C implementations of types that are not Low*,
|
||||
* to facilitate porting programs to Low*. */
|
||||
|
||||
typedef const char *Prims_string;
|
||||
|
||||
typedef struct {
|
||||
uint32_t length;
|
||||
const char *data;
|
||||
} FStar_Bytes_bytes;
|
||||
|
||||
typedef int32_t Prims_pos, Prims_nat, Prims_nonzero, Prims_int,
|
||||
krml_checked_int_t;
|
||||
|
||||
#define RETURN_OR(x) \
|
||||
do { \
|
||||
int64_t __ret = x; \
|
||||
if (__ret < INT32_MIN || INT32_MAX < __ret) { \
|
||||
KRML_HOST_PRINTF( \
|
||||
"Prims.{int,nat,pos} integer overflow at %s:%d\n", __FILE__, \
|
||||
__LINE__); \
|
||||
KRML_HOST_EXIT(252); \
|
||||
} \
|
||||
return (int32_t)__ret; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef __KREMLIN_DEBUG_H
|
||||
#define __KREMLIN_DEBUG_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "kremlin/internal/target.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Debugging helpers - intended only for KreMLin developers */
|
||||
/******************************************************************************/
|
||||
|
||||
/* In support of "-wasm -d force-c": we might need this function to be
|
||||
* forward-declared, because the dependency on WasmSupport appears very late,
|
||||
* after SimplifyWasm, and sadly, after the topological order has been done. */
|
||||
void WasmSupport_check_buffer_size(uint32_t s);
|
||||
|
||||
/* A series of GCC atrocities to trace function calls (kremlin's [-d c-calls]
|
||||
* option). Useful when trying to debug, say, Wasm, to compare traces. */
|
||||
/* clang-format off */
|
||||
#ifdef __GNUC__
|
||||
#define KRML_FORMAT(X) _Generic((X), \
|
||||
uint8_t : "0x%08" PRIx8, \
|
||||
uint16_t: "0x%08" PRIx16, \
|
||||
uint32_t: "0x%08" PRIx32, \
|
||||
uint64_t: "0x%08" PRIx64, \
|
||||
int8_t : "0x%08" PRIx8, \
|
||||
int16_t : "0x%08" PRIx16, \
|
||||
int32_t : "0x%08" PRIx32, \
|
||||
int64_t : "0x%08" PRIx64, \
|
||||
default : "%s")
|
||||
|
||||
#define KRML_FORMAT_ARG(X) _Generic((X), \
|
||||
uint8_t : X, \
|
||||
uint16_t: X, \
|
||||
uint32_t: X, \
|
||||
uint64_t: X, \
|
||||
int8_t : X, \
|
||||
int16_t : X, \
|
||||
int32_t : X, \
|
||||
int64_t : X, \
|
||||
default : "unknown")
|
||||
/* clang-format on */
|
||||
|
||||
# define KRML_DEBUG_RETURN(X) \
|
||||
({ \
|
||||
__auto_type _ret = (X); \
|
||||
KRML_HOST_PRINTF("returning: "); \
|
||||
KRML_HOST_PRINTF(KRML_FORMAT(_ret), KRML_FORMAT_ARG(_ret)); \
|
||||
KRML_HOST_PRINTF(" \n"); \
|
||||
_ret; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef __KREMLIN_TARGET_H
|
||||
#define __KREMLIN_TARGET_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "kremlin/internal/callconv.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* Macros that KreMLin will generate. */
|
||||
/******************************************************************************/
|
||||
|
||||
/* For "bare" targets that do not have a C stdlib, the user might want to use
|
||||
* [-add-early-include '"mydefinitions.h"'] and override these. */
|
||||
#ifndef KRML_HOST_PRINTF
|
||||
# define KRML_HOST_PRINTF printf
|
||||
#endif
|
||||
|
||||
#if ( \
|
||||
(defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
||||
(!(defined KRML_HOST_EPRINTF)))
|
||||
# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef KRML_HOST_EXIT
|
||||
# define KRML_HOST_EXIT exit
|
||||
#endif
|
||||
|
||||
#ifndef KRML_HOST_MALLOC
|
||||
# define KRML_HOST_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef KRML_HOST_CALLOC
|
||||
# define KRML_HOST_CALLOC calloc
|
||||
#endif
|
||||
|
||||
#ifndef KRML_HOST_FREE
|
||||
# define KRML_HOST_FREE free
|
||||
#endif
|
||||
|
||||
#ifndef KRML_HOST_TIME
|
||||
|
||||
# include <time.h>
|
||||
|
||||
/* Prims_nat not yet in scope */
|
||||
inline static int32_t krml_time() {
|
||||
return (int32_t)time(NULL);
|
||||
}
|
||||
|
||||
# define KRML_HOST_TIME krml_time
|
||||
#endif
|
||||
|
||||
/* In statement position, exiting is easy. */
|
||||
#define KRML_EXIT \
|
||||
do { \
|
||||
KRML_HOST_PRINTF("Unimplemented function at %s:%d\n", __FILE__, __LINE__); \
|
||||
KRML_HOST_EXIT(254); \
|
||||
} while (0)
|
||||
|
||||
/* In expression position, use the comma-operator and a malloc to return an
|
||||
* expression of the right size. KreMLin passes t as the parameter to the macro.
|
||||
*/
|
||||
#define KRML_EABORT(t, msg) \
|
||||
(KRML_HOST_PRINTF("KreMLin abort at %s:%d\n%s\n", __FILE__, __LINE__, msg), \
|
||||
KRML_HOST_EXIT(255), *((t *)KRML_HOST_MALLOC(sizeof(t))))
|
||||
|
||||
/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of
|
||||
* *elements*. Do an ugly, run-time check (some of which KreMLin can eliminate).
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define _KRML_CHECK_SIZE_PRAGMA \
|
||||
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
|
||||
#else
|
||||
# define _KRML_CHECK_SIZE_PRAGMA
|
||||
#endif
|
||||
|
||||
#define KRML_CHECK_SIZE(size_elt, sz) \
|
||||
do { \
|
||||
_KRML_CHECK_SIZE_PRAGMA \
|
||||
if (((size_t)(sz)) > ((size_t)(SIZE_MAX / (size_elt)))) { \
|
||||
KRML_HOST_PRINTF( \
|
||||
"Maximum allocatable size exceeded, aborting before overflow at " \
|
||||
"%s:%d\n", \
|
||||
__FILE__, __LINE__); \
|
||||
KRML_HOST_EXIT(253); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) _snprintf_s(buf, sz, _TRUNCATE, fmt, arg)
|
||||
#else
|
||||
# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) snprintf(buf, sz, fmt, arg)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
#ifndef KRML_TYPES_H
|
||||
#define KRML_TYPES_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Types which are either abstract, meaning that have to be implemented in C, or
|
||||
* which are models, meaning that they are swapped out at compile-time for
|
||||
* hand-written C types (in which case they're marked as noextract). */
|
||||
|
||||
typedef uint64_t FStar_UInt64_t, FStar_UInt64_t_;
|
||||
typedef int64_t FStar_Int64_t, FStar_Int64_t_;
|
||||
typedef uint32_t FStar_UInt32_t, FStar_UInt32_t_;
|
||||
typedef int32_t FStar_Int32_t, FStar_Int32_t_;
|
||||
typedef uint16_t FStar_UInt16_t, FStar_UInt16_t_;
|
||||
typedef int16_t FStar_Int16_t, FStar_Int16_t_;
|
||||
typedef uint8_t FStar_UInt8_t, FStar_UInt8_t_;
|
||||
typedef int8_t FStar_Int8_t, FStar_Int8_t_;
|
||||
|
||||
/* Only useful when building Kremlib, because it's in the dependency graph of
|
||||
* FStar.Int.Cast. */
|
||||
typedef uint64_t FStar_UInt63_t, FStar_UInt63_t_;
|
||||
typedef int64_t FStar_Int63_t, FStar_Int63_t_;
|
||||
|
||||
typedef double FStar_Float_float;
|
||||
typedef uint32_t FStar_Char_char;
|
||||
typedef FILE *FStar_IO_fd_read, *FStar_IO_fd_write;
|
||||
|
||||
typedef void *FStar_Dyn_dyn;
|
||||
|
||||
typedef const char *C_String_t, *C_String_t_;
|
||||
|
||||
typedef int exit_code;
|
||||
typedef FILE *channel;
|
||||
|
||||
typedef unsigned long long TestLib_cycles;
|
||||
|
||||
typedef uint64_t FStar_Date_dateTime, FStar_Date_timeSpan;
|
||||
|
||||
/* The uint128 type is a special case since we offer several implementations of
|
||||
* it, depending on the compiler and whether the user wants the verified
|
||||
* implementation or not. */
|
||||
#if !defined(KRML_VERIFIED_UINT128) && defined(_MSC_VER) && defined(_M_X64)
|
||||
# include <emmintrin.h>
|
||||
typedef __m128i FStar_UInt128_uint128;
|
||||
#elif !defined(KRML_VERIFIED_UINT128) && !defined(_MSC_VER)
|
||||
typedef unsigned __int128 FStar_UInt128_uint128;
|
||||
#else
|
||||
typedef struct FStar_UInt128_uint128_s {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
} FStar_UInt128_uint128;
|
||||
#endif
|
||||
|
||||
typedef FStar_UInt128_uint128 FStar_UInt128_t, FStar_UInt128_t_, uint128_t;
|
||||
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file is automatically included when compiling with -wasm -d force-c */
|
||||
#define WasmSupport_check_buffer_size(X)
|
||||
@@ -1,21 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __Hacl_Curve25519_H
|
||||
#define __Hacl_Curve25519_H
|
||||
|
||||
|
||||
#include "kremlib.h"
|
||||
|
||||
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint);
|
||||
|
||||
#define __Hacl_Curve25519_H_DEFINED
|
||||
#endif
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Custom inttypes.h for VS2010 KreMLin requires these definitions,
|
||||
* but VS2010 doesn't provide them.
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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 _INTTYPES_H_VS2010
|
||||
#define _INTTYPES_H_VS2010
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* VS2010 unsigned long == 8 bytes */
|
||||
|
||||
#define PRIu64 "I64u"
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Custom stdbool.h for VS2010 KreMLin requires these definitions,
|
||||
* but VS2010 doesn't provide them.
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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 _STDBOOL_H_VS2010
|
||||
#define _STDBOOL_H_VS2010
|
||||
|
||||
typedef int bool;
|
||||
|
||||
static bool true = 1;
|
||||
static bool false = 0;
|
||||
|
||||
#endif
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* ECDH with curve-optimized implementation multiplexing
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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 MBEDTLS_X25519_H
|
||||
#define MBEDTLS_X25519_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_ECP_TLS_CURVE25519 0x1d
|
||||
#define MBEDTLS_X25519_KEY_SIZE_BYTES 32
|
||||
|
||||
/**
|
||||
* Defines the source of the imported EC key.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MBEDTLS_X25519_ECDH_OURS, /**< Our key. */
|
||||
MBEDTLS_X25519_ECDH_THEIRS, /**< The key of the peer. */
|
||||
} mbedtls_x25519_ecdh_side;
|
||||
|
||||
/**
|
||||
* \brief The x25519 context structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char our_secret[MBEDTLS_X25519_KEY_SIZE_BYTES];
|
||||
unsigned char peer_point[MBEDTLS_X25519_KEY_SIZE_BYTES];
|
||||
} mbedtls_x25519_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes an x25519 context.
|
||||
*
|
||||
* \param ctx The x25519 context to initialize.
|
||||
*/
|
||||
void mbedtls_x25519_init( mbedtls_x25519_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function frees a context.
|
||||
*
|
||||
* \param ctx The context to free.
|
||||
*/
|
||||
void mbedtls_x25519_free( mbedtls_x25519_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief This function generates a public key and a TLS
|
||||
* ServerKeyExchange payload.
|
||||
*
|
||||
* This is the first function used by a TLS server for x25519.
|
||||
*
|
||||
*
|
||||
* \param ctx The x25519 context.
|
||||
* \param olen The number of characters written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The length of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes a TLS ServerKeyExchange
|
||||
* payload.
|
||||
*
|
||||
*
|
||||
* \param ctx The x25519 context.
|
||||
* \param buf The pointer to the start of the input buffer.
|
||||
* \param end The address for one Byte past the end of the buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
|
||||
const unsigned char **buf, const unsigned char *end );
|
||||
|
||||
/**
|
||||
* \brief This function sets up an x25519 context from an EC key.
|
||||
*
|
||||
* It is used by clients and servers in place of the
|
||||
* ServerKeyEchange for static ECDH, and imports ECDH
|
||||
* parameters from the EC key information of a certificate.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The x25519 context to set up.
|
||||
* \param key The EC key to use.
|
||||
* \param side Defines the source of the key: 1: Our key, or
|
||||
* 0: The key of the peer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
|
||||
mbedtls_x25519_ecdh_side side );
|
||||
|
||||
/**
|
||||
* \brief This function derives and exports the shared secret.
|
||||
*
|
||||
* This is the last function used by both TLS client
|
||||
* and servers.
|
||||
*
|
||||
*
|
||||
* \param ctx The x25519 context.
|
||||
* \param olen The number of Bytes written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The length of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief This function generates a public key and a TLS
|
||||
* ClientKeyExchange payload.
|
||||
*
|
||||
* This is the second function used by a TLS client for x25519.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The x25519 context.
|
||||
* \param olen The number of Bytes written.
|
||||
* \param buf The destination buffer.
|
||||
* \param blen The size of the destination buffer.
|
||||
* \param f_rng The RNG function.
|
||||
* \param p_rng The RNG context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes a TLS ClientKeyExchange
|
||||
* payload.
|
||||
*
|
||||
* This is the second function used by a TLS server for x25519.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The x25519 context.
|
||||
* \param buf The start of the input buffer.
|
||||
* \param blen The length of the input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
|
||||
const unsigned char *buf, size_t blen );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* x25519.h */
|
||||
-760
@@ -1,760 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fbuiltin-uint128 -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
#include "Hacl_Curve25519.h"
|
||||
|
||||
extern uint64_t FStar_UInt64_eq_mask(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_gte_mask(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint128_t FStar_UInt128_add(uint128_t x0, uint128_t x1);
|
||||
|
||||
extern uint128_t FStar_UInt128_add_mod(uint128_t x0, uint128_t x1);
|
||||
|
||||
extern uint128_t FStar_UInt128_logand(uint128_t x0, uint128_t x1);
|
||||
|
||||
extern uint128_t FStar_UInt128_shift_right(uint128_t x0, uint32_t x1);
|
||||
|
||||
extern uint128_t FStar_UInt128_uint64_to_uint128(uint64_t x0);
|
||||
|
||||
extern uint64_t FStar_UInt128_uint128_to_uint64(uint128_t x0);
|
||||
|
||||
extern uint128_t FStar_UInt128_mul_wide(uint64_t x0, uint64_t x1);
|
||||
|
||||
static void Hacl_Bignum_Modulo_carry_top(uint64_t *b)
|
||||
{
|
||||
uint64_t b4 = b[4U];
|
||||
uint64_t b0 = b[0U];
|
||||
uint64_t b4_ = b4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t b0_ = b0 + (uint64_t)19U * (b4 >> (uint32_t)51U);
|
||||
b[4U] = b4_;
|
||||
b[0U] = b0_;
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, uint128_t *input)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint128_t xi = input[i];
|
||||
output[i] = (uint64_t)xi;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(uint128_t *output, uint64_t *input, uint64_t s)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint128_t xi = output[i];
|
||||
uint64_t yi = input[i];
|
||||
output[i] = xi + (uint128_t)yi * s;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fproduct_carry_wide_(uint128_t *tmp)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint32_t ctr = i;
|
||||
uint128_t tctr = tmp[ctr];
|
||||
uint128_t tctrp1 = tmp[ctr + (uint32_t)1U];
|
||||
uint64_t r0 = (uint64_t)tctr & (uint64_t)0x7ffffffffffffU;
|
||||
uint128_t c = tctr >> (uint32_t)51U;
|
||||
tmp[ctr] = (uint128_t)r0;
|
||||
tmp[ctr + (uint32_t)1U] = tctrp1 + c;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fmul_shift_reduce(uint64_t *output)
|
||||
{
|
||||
uint64_t tmp = output[4U];
|
||||
uint64_t b0;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint32_t ctr = (uint32_t)5U - i - (uint32_t)1U;
|
||||
uint64_t z = output[ctr - (uint32_t)1U];
|
||||
output[ctr] = z;
|
||||
}
|
||||
}
|
||||
output[0U] = tmp;
|
||||
b0 = output[0U];
|
||||
output[0U] = (uint64_t)19U * b0;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Bignum_Fmul_mul_shift_reduce_(uint128_t *output, uint64_t *input, uint64_t *input2)
|
||||
{
|
||||
uint32_t i;
|
||||
uint64_t input2i;
|
||||
{
|
||||
uint32_t i0;
|
||||
for (i0 = (uint32_t)0U; i0 < (uint32_t)4U; i0 = i0 + (uint32_t)1U)
|
||||
{
|
||||
uint64_t input2i0 = input2[i0];
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i0);
|
||||
Hacl_Bignum_Fmul_shift_reduce(input);
|
||||
}
|
||||
}
|
||||
i = (uint32_t)4U;
|
||||
input2i = input2[i];
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2)
|
||||
{
|
||||
uint64_t tmp[5U] = { 0U };
|
||||
memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]);
|
||||
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
|
||||
{
|
||||
uint128_t t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = (uint128_t)(uint64_t)0U;
|
||||
}
|
||||
{
|
||||
uint128_t b4;
|
||||
uint128_t b0;
|
||||
uint128_t b4_;
|
||||
uint128_t b0_;
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
|
||||
Hacl_Bignum_Fproduct_carry_wide_(t);
|
||||
b4 = t[4U];
|
||||
b0 = t[0U];
|
||||
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
|
||||
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
|
||||
t[4U] = b4_;
|
||||
t[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
|
||||
i0 = output[0U];
|
||||
i1 = output[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
output[0U] = i0_;
|
||||
output[1U] = i1_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare__(uint128_t *tmp, uint64_t *output)
|
||||
{
|
||||
uint64_t r0 = output[0U];
|
||||
uint64_t r1 = output[1U];
|
||||
uint64_t r2 = output[2U];
|
||||
uint64_t r3 = output[3U];
|
||||
uint64_t r4 = output[4U];
|
||||
uint64_t d0 = r0 * (uint64_t)2U;
|
||||
uint64_t d1 = r1 * (uint64_t)2U;
|
||||
uint64_t d2 = r2 * (uint64_t)2U * (uint64_t)19U;
|
||||
uint64_t d419 = r4 * (uint64_t)19U;
|
||||
uint64_t d4 = d419 * (uint64_t)2U;
|
||||
uint128_t s0 = (uint128_t)r0 * r0 + (uint128_t)d4 * r1 + (uint128_t)d2 * r3;
|
||||
uint128_t s1 = (uint128_t)d0 * r1 + (uint128_t)d4 * r2 + (uint128_t)(r3 * (uint64_t)19U) * r3;
|
||||
uint128_t s2 = (uint128_t)d0 * r2 + (uint128_t)r1 * r1 + (uint128_t)d4 * r3;
|
||||
uint128_t s3 = (uint128_t)d0 * r3 + (uint128_t)d1 * r2 + (uint128_t)r4 * d419;
|
||||
uint128_t s4 = (uint128_t)d0 * r4 + (uint128_t)d1 * r3 + (uint128_t)r2 * r2;
|
||||
tmp[0U] = s0;
|
||||
tmp[1U] = s1;
|
||||
tmp[2U] = s2;
|
||||
tmp[3U] = s3;
|
||||
tmp[4U] = s4;
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare_(uint128_t *tmp, uint64_t *output)
|
||||
{
|
||||
uint128_t b4;
|
||||
uint128_t b0;
|
||||
uint128_t b4_;
|
||||
uint128_t b0_;
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_Bignum_Fsquare_fsquare__(tmp, output);
|
||||
Hacl_Bignum_Fproduct_carry_wide_(tmp);
|
||||
b4 = tmp[4U];
|
||||
b0 = tmp[0U];
|
||||
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
|
||||
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
|
||||
tmp[4U] = b4_;
|
||||
tmp[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
|
||||
i0 = output[0U];
|
||||
i1 = output[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
output[0U] = i0_;
|
||||
output[1U] = i1_;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(uint64_t *input, uint128_t *tmp, uint32_t count1)
|
||||
{
|
||||
uint32_t i;
|
||||
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
|
||||
for (i = (uint32_t)1U; i < count1; i = i + (uint32_t)1U)
|
||||
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Bignum_Fsquare_fsquare_times(uint64_t *output, uint64_t *input, uint32_t count1)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
|
||||
{
|
||||
uint128_t t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = (uint128_t)(uint64_t)0U;
|
||||
}
|
||||
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare_times_inplace(uint64_t *output, uint32_t count1)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
|
||||
{
|
||||
uint128_t t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = (uint128_t)(uint64_t)0U;
|
||||
}
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Crecip_crecip(uint64_t *out, uint64_t *z)
|
||||
{
|
||||
uint64_t buf[20U] = { 0U };
|
||||
uint64_t *a0 = buf;
|
||||
uint64_t *t00 = buf + (uint32_t)5U;
|
||||
uint64_t *b0 = buf + (uint32_t)10U;
|
||||
uint64_t *t01;
|
||||
uint64_t *b1;
|
||||
uint64_t *c0;
|
||||
uint64_t *a;
|
||||
uint64_t *t0;
|
||||
uint64_t *b;
|
||||
uint64_t *c;
|
||||
Hacl_Bignum_Fsquare_fsquare_times(a0, z, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)2U);
|
||||
Hacl_Bignum_Fmul_fmul(b0, t00, z);
|
||||
Hacl_Bignum_Fmul_fmul(a0, b0, a0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)1U);
|
||||
Hacl_Bignum_Fmul_fmul(b0, t00, b0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, b0, (uint32_t)5U);
|
||||
t01 = buf + (uint32_t)5U;
|
||||
b1 = buf + (uint32_t)10U;
|
||||
c0 = buf + (uint32_t)15U;
|
||||
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)10U);
|
||||
Hacl_Bignum_Fmul_fmul(c0, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, c0, (uint32_t)20U);
|
||||
Hacl_Bignum_Fmul_fmul(t01, t01, c0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t01, (uint32_t)10U);
|
||||
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)50U);
|
||||
a = buf;
|
||||
t0 = buf + (uint32_t)5U;
|
||||
b = buf + (uint32_t)10U;
|
||||
c = buf + (uint32_t)15U;
|
||||
Hacl_Bignum_Fmul_fmul(c, t0, b);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t0, c, (uint32_t)100U);
|
||||
Hacl_Bignum_Fmul_fmul(t0, t0, c);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)50U);
|
||||
Hacl_Bignum_Fmul_fmul(t0, t0, b);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)5U);
|
||||
Hacl_Bignum_Fmul_fmul(out, t0, a);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fsum(uint64_t *a, uint64_t *b)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = a[i];
|
||||
uint64_t yi = b[i];
|
||||
a[i] = xi + yi;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fdifference(uint64_t *a, uint64_t *b)
|
||||
{
|
||||
uint64_t tmp[5U] = { 0U };
|
||||
uint64_t b0;
|
||||
uint64_t b1;
|
||||
uint64_t b2;
|
||||
uint64_t b3;
|
||||
uint64_t b4;
|
||||
memcpy(tmp, b, (uint32_t)5U * sizeof b[0U]);
|
||||
b0 = tmp[0U];
|
||||
b1 = tmp[1U];
|
||||
b2 = tmp[2U];
|
||||
b3 = tmp[3U];
|
||||
b4 = tmp[4U];
|
||||
tmp[0U] = b0 + (uint64_t)0x3fffffffffff68U;
|
||||
tmp[1U] = b1 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[2U] = b2 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[3U] = b3 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[4U] = b4 + (uint64_t)0x3ffffffffffff8U;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = a[i];
|
||||
uint64_t yi = tmp[i];
|
||||
a[i] = yi - xi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fscalar(uint64_t *output, uint64_t *b, uint64_t s)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
|
||||
{
|
||||
uint128_t tmp[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
tmp[_i] = (uint128_t)(uint64_t)0U;
|
||||
}
|
||||
{
|
||||
uint128_t b4;
|
||||
uint128_t b0;
|
||||
uint128_t b4_;
|
||||
uint128_t b0_;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = b[i];
|
||||
tmp[i] = (uint128_t)xi * s;
|
||||
}
|
||||
}
|
||||
Hacl_Bignum_Fproduct_carry_wide_(tmp);
|
||||
b4 = tmp[4U];
|
||||
b0 = tmp[0U];
|
||||
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
|
||||
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
|
||||
tmp[4U] = b4_;
|
||||
tmp[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fmul(uint64_t *output, uint64_t *a, uint64_t *b)
|
||||
{
|
||||
Hacl_Bignum_Fmul_fmul(output, a, b);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_crecip(uint64_t *output, uint64_t *input)
|
||||
{
|
||||
Hacl_Bignum_Crecip_crecip(output, input);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Point_swap_conditional_step(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
|
||||
{
|
||||
uint32_t i = ctr - (uint32_t)1U;
|
||||
uint64_t ai = a[i];
|
||||
uint64_t bi = b[i];
|
||||
uint64_t x = swap1 & (ai ^ bi);
|
||||
uint64_t ai1 = ai ^ x;
|
||||
uint64_t bi1 = bi ^ x;
|
||||
a[i] = ai1;
|
||||
b[i] = bi1;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Point_swap_conditional_(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
|
||||
{
|
||||
if (!(ctr == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i;
|
||||
Hacl_EC_Point_swap_conditional_step(a, b, swap1, ctr);
|
||||
i = ctr - (uint32_t)1U;
|
||||
Hacl_EC_Point_swap_conditional_(a, b, swap1, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void Hacl_EC_Point_swap_conditional(uint64_t *a, uint64_t *b, uint64_t iswap)
|
||||
{
|
||||
uint64_t swap1 = (uint64_t)0U - iswap;
|
||||
Hacl_EC_Point_swap_conditional_(a, b, swap1, (uint32_t)5U);
|
||||
Hacl_EC_Point_swap_conditional_(a + (uint32_t)5U, b + (uint32_t)5U, swap1, (uint32_t)5U);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Point_copy(uint64_t *output, uint64_t *input)
|
||||
{
|
||||
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
|
||||
memcpy(output + (uint32_t)5U,
|
||||
input + (uint32_t)5U,
|
||||
(uint32_t)5U * sizeof (input + (uint32_t)5U)[0U]);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fexpand(uint64_t *output, uint8_t *input)
|
||||
{
|
||||
uint64_t i0 = load64_le(input);
|
||||
uint8_t *x00 = input + (uint32_t)6U;
|
||||
uint64_t i1 = load64_le(x00);
|
||||
uint8_t *x01 = input + (uint32_t)12U;
|
||||
uint64_t i2 = load64_le(x01);
|
||||
uint8_t *x02 = input + (uint32_t)19U;
|
||||
uint64_t i3 = load64_le(x02);
|
||||
uint8_t *x0 = input + (uint32_t)24U;
|
||||
uint64_t i4 = load64_le(x0);
|
||||
uint64_t output0 = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output1 = i1 >> (uint32_t)3U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output2 = i2 >> (uint32_t)6U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output3 = i3 >> (uint32_t)1U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output4 = i4 >> (uint32_t)12U & (uint64_t)0x7ffffffffffffU;
|
||||
output[0U] = output0;
|
||||
output[1U] = output1;
|
||||
output[2U] = output2;
|
||||
output[3U] = output3;
|
||||
output[4U] = output4;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_first_carry_pass(uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
|
||||
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
|
||||
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
|
||||
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
|
||||
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
|
||||
input[0U] = t0_;
|
||||
input[1U] = t1__;
|
||||
input[2U] = t2__;
|
||||
input[3U] = t3__;
|
||||
input[4U] = t4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_first_carry_full(uint64_t *input)
|
||||
{
|
||||
Hacl_EC_Format_fcontract_first_carry_pass(input);
|
||||
Hacl_Bignum_Modulo_carry_top(input);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_second_carry_pass(uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
|
||||
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
|
||||
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
|
||||
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
|
||||
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
|
||||
input[0U] = t0_;
|
||||
input[1U] = t1__;
|
||||
input[2U] = t2__;
|
||||
input[3U] = t3__;
|
||||
input[4U] = t4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_second_carry_full(uint64_t *input)
|
||||
{
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_EC_Format_fcontract_second_carry_pass(input);
|
||||
Hacl_Bignum_Modulo_carry_top(input);
|
||||
i0 = input[0U];
|
||||
i1 = input[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
input[0U] = i0_;
|
||||
input[1U] = i1_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_trim(uint64_t *input)
|
||||
{
|
||||
uint64_t a0 = input[0U];
|
||||
uint64_t a1 = input[1U];
|
||||
uint64_t a2 = input[2U];
|
||||
uint64_t a3 = input[3U];
|
||||
uint64_t a4 = input[4U];
|
||||
uint64_t mask0 = FStar_UInt64_gte_mask(a0, (uint64_t)0x7ffffffffffedU);
|
||||
uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask3 = FStar_UInt64_eq_mask(a3, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask4 = FStar_UInt64_eq_mask(a4, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4;
|
||||
uint64_t a0_ = a0 - ((uint64_t)0x7ffffffffffedU & mask);
|
||||
uint64_t a1_ = a1 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a2_ = a2 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a3_ = a3 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a4_ = a4 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
input[0U] = a0_;
|
||||
input[1U] = a1_;
|
||||
input[2U] = a2_;
|
||||
input[3U] = a3_;
|
||||
input[4U] = a4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_store(uint8_t *output, uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t o0 = t1 << (uint32_t)51U | t0;
|
||||
uint64_t o1 = t2 << (uint32_t)38U | t1 >> (uint32_t)13U;
|
||||
uint64_t o2 = t3 << (uint32_t)25U | t2 >> (uint32_t)26U;
|
||||
uint64_t o3 = t4 << (uint32_t)12U | t3 >> (uint32_t)39U;
|
||||
uint8_t *b0 = output;
|
||||
uint8_t *b1 = output + (uint32_t)8U;
|
||||
uint8_t *b2 = output + (uint32_t)16U;
|
||||
uint8_t *b3 = output + (uint32_t)24U;
|
||||
store64_le(b0, o0);
|
||||
store64_le(b1, o1);
|
||||
store64_le(b2, o2);
|
||||
store64_le(b3, o3);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract(uint8_t *output, uint64_t *input)
|
||||
{
|
||||
Hacl_EC_Format_fcontract_first_carry_full(input);
|
||||
Hacl_EC_Format_fcontract_second_carry_full(input);
|
||||
Hacl_EC_Format_fcontract_trim(input);
|
||||
Hacl_EC_Format_fcontract_store(output, input);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_scalar_of_point(uint8_t *scalar, uint64_t *point)
|
||||
{
|
||||
uint64_t *x = point;
|
||||
uint64_t *z = point + (uint32_t)5U;
|
||||
uint64_t buf[10U] = { 0U };
|
||||
uint64_t *zmone = buf;
|
||||
uint64_t *sc = buf + (uint32_t)5U;
|
||||
Hacl_Bignum_crecip(zmone, z);
|
||||
Hacl_Bignum_fmul(sc, x, zmone);
|
||||
Hacl_EC_Format_fcontract(scalar, sc);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_AddAndDouble_fmonty(
|
||||
uint64_t *pp,
|
||||
uint64_t *ppq,
|
||||
uint64_t *p,
|
||||
uint64_t *pq,
|
||||
uint64_t *qmqp
|
||||
)
|
||||
{
|
||||
uint64_t *qx = qmqp;
|
||||
uint64_t *x2 = pp;
|
||||
uint64_t *z2 = pp + (uint32_t)5U;
|
||||
uint64_t *x3 = ppq;
|
||||
uint64_t *z3 = ppq + (uint32_t)5U;
|
||||
uint64_t *x = p;
|
||||
uint64_t *z = p + (uint32_t)5U;
|
||||
uint64_t *xprime = pq;
|
||||
uint64_t *zprime = pq + (uint32_t)5U;
|
||||
uint64_t buf[40U] = { 0U };
|
||||
uint64_t *origx = buf;
|
||||
uint64_t *origxprime0 = buf + (uint32_t)5U;
|
||||
uint64_t *xxprime0 = buf + (uint32_t)25U;
|
||||
uint64_t *zzprime0 = buf + (uint32_t)30U;
|
||||
uint64_t *origxprime;
|
||||
uint64_t *xx0;
|
||||
uint64_t *zz0;
|
||||
uint64_t *xxprime;
|
||||
uint64_t *zzprime;
|
||||
uint64_t *zzzprime;
|
||||
uint64_t *zzz;
|
||||
uint64_t *xx;
|
||||
uint64_t *zz;
|
||||
uint64_t scalar;
|
||||
memcpy(origx, x, (uint32_t)5U * sizeof x[0U]);
|
||||
Hacl_Bignum_fsum(x, z);
|
||||
Hacl_Bignum_fdifference(z, origx);
|
||||
memcpy(origxprime0, xprime, (uint32_t)5U * sizeof xprime[0U]);
|
||||
Hacl_Bignum_fsum(xprime, zprime);
|
||||
Hacl_Bignum_fdifference(zprime, origxprime0);
|
||||
Hacl_Bignum_fmul(xxprime0, xprime, z);
|
||||
Hacl_Bignum_fmul(zzprime0, x, zprime);
|
||||
origxprime = buf + (uint32_t)5U;
|
||||
xx0 = buf + (uint32_t)15U;
|
||||
zz0 = buf + (uint32_t)20U;
|
||||
xxprime = buf + (uint32_t)25U;
|
||||
zzprime = buf + (uint32_t)30U;
|
||||
zzzprime = buf + (uint32_t)35U;
|
||||
memcpy(origxprime, xxprime, (uint32_t)5U * sizeof xxprime[0U]);
|
||||
Hacl_Bignum_fsum(xxprime, zzprime);
|
||||
Hacl_Bignum_fdifference(zzprime, origxprime);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(x3, xxprime, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(zzzprime, zzprime, (uint32_t)1U);
|
||||
Hacl_Bignum_fmul(z3, zzzprime, qx);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(xx0, x, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(zz0, z, (uint32_t)1U);
|
||||
zzz = buf + (uint32_t)10U;
|
||||
xx = buf + (uint32_t)15U;
|
||||
zz = buf + (uint32_t)20U;
|
||||
Hacl_Bignum_fmul(x2, xx, zz);
|
||||
Hacl_Bignum_fdifference(zz, xx);
|
||||
scalar = (uint64_t)121665U;
|
||||
Hacl_Bignum_fscalar(zzz, zz, scalar);
|
||||
Hacl_Bignum_fsum(zzz, xx);
|
||||
Hacl_Bignum_fmul(z2, zzz, zz);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt
|
||||
)
|
||||
{
|
||||
uint64_t bit0 = (uint64_t)(byt >> (uint32_t)7U);
|
||||
uint64_t bit;
|
||||
Hacl_EC_Point_swap_conditional(nq, nqpq, bit0);
|
||||
Hacl_EC_AddAndDouble_fmonty(nq2, nqpq2, nq, nqpq, q);
|
||||
bit = (uint64_t)(byt >> (uint32_t)7U);
|
||||
Hacl_EC_Point_swap_conditional(nq2, nqpq2, bit);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt
|
||||
)
|
||||
{
|
||||
uint8_t byt1;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt);
|
||||
byt1 = byt << (uint32_t)1U;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt,
|
||||
uint32_t i
|
||||
)
|
||||
{
|
||||
if (!(i == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i_ = i - (uint32_t)1U;
|
||||
uint8_t byt_;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt);
|
||||
byt_ = byt << (uint32_t)2U;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byt_, i_);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(
|
||||
uint8_t *n1,
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint32_t i
|
||||
)
|
||||
{
|
||||
if (!(i == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i1 = i - (uint32_t)1U;
|
||||
uint8_t byte = n1[i1];
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, (uint32_t)4U);
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, i1);
|
||||
}
|
||||
}
|
||||
|
||||
static void Hacl_EC_Ladder_cmult(uint64_t *result, uint8_t *n1, uint64_t *q)
|
||||
{
|
||||
uint64_t point_buf[40U] = { 0U };
|
||||
uint64_t *nq = point_buf;
|
||||
uint64_t *nqpq = point_buf + (uint32_t)10U;
|
||||
uint64_t *nq2 = point_buf + (uint32_t)20U;
|
||||
uint64_t *nqpq2 = point_buf + (uint32_t)30U;
|
||||
Hacl_EC_Point_copy(nqpq, q);
|
||||
nq[0U] = (uint64_t)1U;
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, (uint32_t)32U);
|
||||
Hacl_EC_Point_copy(result, nq);
|
||||
}
|
||||
|
||||
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint)
|
||||
{
|
||||
uint64_t buf0[10U] = { 0U };
|
||||
uint64_t *x0 = buf0;
|
||||
uint64_t *z = buf0 + (uint32_t)5U;
|
||||
uint64_t *q;
|
||||
Hacl_EC_Format_fexpand(x0, basepoint);
|
||||
z[0U] = (uint64_t)1U;
|
||||
q = buf0;
|
||||
{
|
||||
uint8_t e[32U] = { 0U };
|
||||
uint8_t e0;
|
||||
uint8_t e31;
|
||||
uint8_t e01;
|
||||
uint8_t e311;
|
||||
uint8_t e312;
|
||||
uint8_t *scalar;
|
||||
memcpy(e, secret, (uint32_t)32U * sizeof secret[0U]);
|
||||
e0 = e[0U];
|
||||
e31 = e[31U];
|
||||
e01 = e0 & (uint8_t)248U;
|
||||
e311 = e31 & (uint8_t)127U;
|
||||
e312 = e311 | (uint8_t)64U;
|
||||
e[0U] = e01;
|
||||
e[31U] = e312;
|
||||
scalar = e;
|
||||
{
|
||||
uint64_t buf[15U] = { 0U };
|
||||
uint64_t *nq = buf;
|
||||
uint64_t *x = nq;
|
||||
x[0U] = (uint64_t)1U;
|
||||
Hacl_EC_Ladder_cmult(nq, scalar, q);
|
||||
Hacl_EC_Format_scalar_of_point(mypublic, nq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Interface to code from Project Everest
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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 _BSD_SOURCE
|
||||
/* Required to get htole64() from gcc/glibc's endian.h (older systems)
|
||||
* when we compile with -std=c99 */
|
||||
#define _BSD_SOURCE
|
||||
#endif
|
||||
#ifndef _DEFAULT_SOURCE
|
||||
/* (modern version of _BSD_SOURCE) */
|
||||
#define _DEFAULT_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
|
||||
#if defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16)
|
||||
#define MBEDTLS_HAVE_INT128
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_INT128)
|
||||
#include "Hacl_Curve25519.c"
|
||||
#else
|
||||
#define KRML_VERIFIED_UINT128
|
||||
#include "kremlib/FStar_UInt128_extracted.c"
|
||||
#include "legacy/Hacl_Curve25519.c"
|
||||
#endif
|
||||
|
||||
#include "kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.c"
|
||||
|
||||
#endif /* defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) */
|
||||
|
||||
Vendored
-102
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Interface to code from Project Everest
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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).
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/ecdh.h"
|
||||
|
||||
#include "everest/x25519.h"
|
||||
#include "everest/everest.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
|
||||
int mbedtls_everest_setup( mbedtls_ecdh_context_everest *ctx, int grp_id )
|
||||
{
|
||||
if( grp_id != MBEDTLS_ECP_DP_CURVE25519 )
|
||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
mbedtls_x25519_init( &ctx->ctx );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_everest_free( mbedtls_ecdh_context_everest *ctx )
|
||||
{
|
||||
mbedtls_x25519_free( &ctx->ctx );
|
||||
}
|
||||
|
||||
int mbedtls_everest_make_params( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
return mbedtls_x25519_make_params( x25519_ctx, olen, buf, blen, f_rng, p_rng );
|
||||
}
|
||||
|
||||
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
|
||||
const unsigned char **buf,
|
||||
const unsigned char *end )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
return mbedtls_x25519_read_params( x25519_ctx, buf, end );
|
||||
}
|
||||
|
||||
int mbedtls_everest_get_params( mbedtls_ecdh_context_everest *ctx,
|
||||
const mbedtls_ecp_keypair *key,
|
||||
mbedtls_everest_ecdh_side side )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
mbedtls_x25519_ecdh_side s = side == MBEDTLS_EVEREST_ECDH_OURS ?
|
||||
MBEDTLS_X25519_ECDH_OURS :
|
||||
MBEDTLS_X25519_ECDH_THEIRS;
|
||||
return mbedtls_x25519_get_params( x25519_ctx, key, s );
|
||||
}
|
||||
|
||||
int mbedtls_everest_make_public( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
return mbedtls_x25519_make_public( x25519_ctx, olen, buf, blen, f_rng, p_rng );
|
||||
}
|
||||
|
||||
int mbedtls_everest_read_public( mbedtls_ecdh_context_everest *ctx,
|
||||
const unsigned char *buf, size_t blen )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
return mbedtls_x25519_read_public ( x25519_ctx, buf, blen );
|
||||
}
|
||||
|
||||
int mbedtls_everest_calc_secret( mbedtls_ecdh_context_everest *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )( void *, unsigned char *, size_t ),
|
||||
void *p_rng )
|
||||
{
|
||||
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
|
||||
return mbedtls_x25519_calc_secret( x25519_ctx, olen, buf, blen, f_rng, p_rng );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir extracted -warn-error +9+11 -skip-compilation -extract-uints -add-include <inttypes.h> -add-include "kremlib.h" -add-include "kremlin/internal/compat.h" extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
#include "FStar_UInt128.h"
|
||||
#include "kremlin/c_endianness.h"
|
||||
#include "FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h"
|
||||
|
||||
uint64_t FStar_UInt128___proj__Mkuint128__item__low(FStar_UInt128_uint128 projectee)
|
||||
{
|
||||
return projectee.low;
|
||||
}
|
||||
|
||||
uint64_t FStar_UInt128___proj__Mkuint128__item__high(FStar_UInt128_uint128 projectee)
|
||||
{
|
||||
return projectee.high;
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b)
|
||||
{
|
||||
return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U;
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_carry(uint64_t a, uint64_t b)
|
||||
{
|
||||
return FStar_UInt128_constant_time_carry(a, b);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return FStar_UInt128_sub_mod_impl(a, b);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { a.low & b.low, a.high & b.high };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { a.low ^ b.low, a.high ^ b.high };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { a.low | b.low, a.high | b.high };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { ~a.low, ~a.high };
|
||||
return flat;
|
||||
}
|
||||
|
||||
static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U;
|
||||
|
||||
static uint64_t FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s));
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return FStar_UInt128_add_u64_shift_left(hi, lo, s);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s == (uint32_t)0U)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
else
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { a.low << s, FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s) };
|
||||
return flat;
|
||||
}
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { (uint64_t)0U, a.low << (s - FStar_UInt128_u32_64) };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s < FStar_UInt128_u32_64)
|
||||
{
|
||||
return FStar_UInt128_shift_left_small(a, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FStar_UInt128_shift_left_large(a, s);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s));
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s)
|
||||
{
|
||||
return FStar_UInt128_add_u64_shift_right(hi, lo, s);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s == (uint32_t)0U)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
else
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat = { FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s), a.high >> s };
|
||||
return flat;
|
||||
}
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128
|
||||
FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { a.high >> (s - FStar_UInt128_u32_64), (uint64_t)0U };
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s)
|
||||
{
|
||||
if (s < FStar_UInt128_u32_64)
|
||||
{
|
||||
return FStar_UInt128_shift_right_small(a, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FStar_UInt128_shift_right_large(a, s);
|
||||
}
|
||||
}
|
||||
|
||||
bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return a.low == b.low && a.high == b.high;
|
||||
}
|
||||
|
||||
bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return a.high > b.high || (a.high == b.high && a.low > b.low);
|
||||
}
|
||||
|
||||
bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return a.high < b.high || (a.high == b.high && a.low < b.low);
|
||||
}
|
||||
|
||||
bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return a.high > b.high || (a.high == b.high && a.low >= b.low);
|
||||
}
|
||||
|
||||
bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
return a.high < b.high || (a.high == b.high && a.low <= b.low);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat =
|
||||
{
|
||||
FStar_UInt64_eq_mask(a.low,
|
||||
b.low)
|
||||
& FStar_UInt64_eq_mask(a.high, b.high),
|
||||
FStar_UInt64_eq_mask(a.low,
|
||||
b.low)
|
||||
& FStar_UInt64_eq_mask(a.high, b.high)
|
||||
};
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat =
|
||||
{
|
||||
(FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
|
||||
| (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)),
|
||||
(FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
|
||||
| (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low))
|
||||
};
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a)
|
||||
{
|
||||
FStar_UInt128_uint128 flat = { a, (uint64_t)0U };
|
||||
return flat;
|
||||
}
|
||||
|
||||
uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a)
|
||||
{
|
||||
return a.low;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_add;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Question_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_add_underspec;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Plus_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_add_mod;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_sub;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Question_Hat)(
|
||||
FStar_UInt128_uint128 x0,
|
||||
FStar_UInt128_uint128 x1
|
||||
) = FStar_UInt128_sub_underspec;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Subtraction_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_sub_mod;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Amp_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_logand;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Hat_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_logxor;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Bar_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_logor;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Less_Less_Hat)(FStar_UInt128_uint128 x0, uint32_t x1) =
|
||||
FStar_UInt128_shift_left;
|
||||
|
||||
FStar_UInt128_uint128
|
||||
(*FStar_UInt128_op_Greater_Greater_Hat)(FStar_UInt128_uint128 x0, uint32_t x1) =
|
||||
FStar_UInt128_shift_right;
|
||||
|
||||
bool
|
||||
(*FStar_UInt128_op_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_eq;
|
||||
|
||||
bool
|
||||
(*FStar_UInt128_op_Greater_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_gt;
|
||||
|
||||
bool
|
||||
(*FStar_UInt128_op_Less_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_lt;
|
||||
|
||||
bool
|
||||
(*FStar_UInt128_op_Greater_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_gte;
|
||||
|
||||
bool
|
||||
(*FStar_UInt128_op_Less_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
|
||||
FStar_UInt128_lte;
|
||||
|
||||
static uint64_t FStar_UInt128_u64_mod_32(uint64_t a)
|
||||
{
|
||||
return a & (uint64_t)0xffffffffU;
|
||||
}
|
||||
|
||||
static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U;
|
||||
|
||||
static uint64_t FStar_UInt128_u32_combine(uint64_t hi, uint64_t lo)
|
||||
{
|
||||
return lo + (hi << FStar_UInt128_u32_32);
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y)
|
||||
{
|
||||
FStar_UInt128_uint128
|
||||
flat =
|
||||
{
|
||||
FStar_UInt128_u32_combine((x >> FStar_UInt128_u32_32)
|
||||
* (uint64_t)y
|
||||
+ (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32),
|
||||
FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * (uint64_t)y)),
|
||||
((x >> FStar_UInt128_u32_32)
|
||||
* (uint64_t)y
|
||||
+ (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32))
|
||||
>> FStar_UInt128_u32_32
|
||||
};
|
||||
return flat;
|
||||
}
|
||||
|
||||
typedef struct K___uint64_t_uint64_t_uint64_t_uint64_t_s
|
||||
{
|
||||
uint64_t fst;
|
||||
uint64_t snd;
|
||||
uint64_t thd;
|
||||
uint64_t f3;
|
||||
}
|
||||
K___uint64_t_uint64_t_uint64_t_uint64_t;
|
||||
|
||||
static K___uint64_t_uint64_t_uint64_t_uint64_t
|
||||
FStar_UInt128_mul_wide_impl_t_(uint64_t x, uint64_t y)
|
||||
{
|
||||
K___uint64_t_uint64_t_uint64_t_uint64_t
|
||||
flat =
|
||||
{
|
||||
FStar_UInt128_u64_mod_32(x),
|
||||
FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y)),
|
||||
x
|
||||
>> FStar_UInt128_u32_32,
|
||||
(x >> FStar_UInt128_u32_32)
|
||||
* FStar_UInt128_u64_mod_32(y)
|
||||
+ (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)
|
||||
};
|
||||
return flat;
|
||||
}
|
||||
|
||||
static uint64_t FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo)
|
||||
{
|
||||
return lo + (hi << FStar_UInt128_u32_32);
|
||||
}
|
||||
|
||||
static FStar_UInt128_uint128 FStar_UInt128_mul_wide_impl(uint64_t x, uint64_t y)
|
||||
{
|
||||
K___uint64_t_uint64_t_uint64_t_uint64_t scrut = FStar_UInt128_mul_wide_impl_t_(x, y);
|
||||
uint64_t u1 = scrut.fst;
|
||||
uint64_t w3 = scrut.snd;
|
||||
uint64_t x_ = scrut.thd;
|
||||
uint64_t t_ = scrut.f3;
|
||||
FStar_UInt128_uint128
|
||||
flat =
|
||||
{
|
||||
FStar_UInt128_u32_combine_(u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_),
|
||||
w3),
|
||||
x_
|
||||
* (y >> FStar_UInt128_u32_32)
|
||||
+ (t_ >> FStar_UInt128_u32_32)
|
||||
+ ((u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_)) >> FStar_UInt128_u32_32)
|
||||
};
|
||||
return flat;
|
||||
}
|
||||
|
||||
FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y)
|
||||
{
|
||||
return FStar_UInt128_mul_wide_impl(x, y);
|
||||
}
|
||||
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/minimal -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/compat.h" -add-include "kremlin/internal/types.h" -bundle FStar.UInt64+FStar.UInt32+FStar.UInt16+FStar.UInt8=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
#include "FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h"
|
||||
|
||||
uint64_t FStar_UInt64_eq_mask(uint64_t a, uint64_t b)
|
||||
{
|
||||
uint64_t x = a ^ b;
|
||||
uint64_t minus_x = ~x + (uint64_t)1U;
|
||||
uint64_t x_or_minus_x = x | minus_x;
|
||||
uint64_t xnx = x_or_minus_x >> (uint32_t)63U;
|
||||
return xnx - (uint64_t)1U;
|
||||
}
|
||||
|
||||
uint64_t FStar_UInt64_gte_mask(uint64_t a, uint64_t b)
|
||||
{
|
||||
uint64_t x = a;
|
||||
uint64_t y = b;
|
||||
uint64_t x_xor_y = x ^ y;
|
||||
uint64_t x_sub_y = x - y;
|
||||
uint64_t x_sub_y_xor_y = x_sub_y ^ y;
|
||||
uint64_t q = x_xor_y | x_sub_y_xor_y;
|
||||
uint64_t x_xor_q = x ^ q;
|
||||
uint64_t x_xor_q_ = x_xor_q >> (uint32_t)63U;
|
||||
return x_xor_q_ - (uint64_t)1U;
|
||||
}
|
||||
|
||||
uint32_t FStar_UInt32_eq_mask(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t x = a ^ b;
|
||||
uint32_t minus_x = ~x + (uint32_t)1U;
|
||||
uint32_t x_or_minus_x = x | minus_x;
|
||||
uint32_t xnx = x_or_minus_x >> (uint32_t)31U;
|
||||
return xnx - (uint32_t)1U;
|
||||
}
|
||||
|
||||
uint32_t FStar_UInt32_gte_mask(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t x = a;
|
||||
uint32_t y = b;
|
||||
uint32_t x_xor_y = x ^ y;
|
||||
uint32_t x_sub_y = x - y;
|
||||
uint32_t x_sub_y_xor_y = x_sub_y ^ y;
|
||||
uint32_t q = x_xor_y | x_sub_y_xor_y;
|
||||
uint32_t x_xor_q = x ^ q;
|
||||
uint32_t x_xor_q_ = x_xor_q >> (uint32_t)31U;
|
||||
return x_xor_q_ - (uint32_t)1U;
|
||||
}
|
||||
|
||||
uint16_t FStar_UInt16_eq_mask(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint16_t x = a ^ b;
|
||||
uint16_t minus_x = ~x + (uint16_t)1U;
|
||||
uint16_t x_or_minus_x = x | minus_x;
|
||||
uint16_t xnx = x_or_minus_x >> (uint32_t)15U;
|
||||
return xnx - (uint16_t)1U;
|
||||
}
|
||||
|
||||
uint16_t FStar_UInt16_gte_mask(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint16_t x = a;
|
||||
uint16_t y = b;
|
||||
uint16_t x_xor_y = x ^ y;
|
||||
uint16_t x_sub_y = x - y;
|
||||
uint16_t x_sub_y_xor_y = x_sub_y ^ y;
|
||||
uint16_t q = x_xor_y | x_sub_y_xor_y;
|
||||
uint16_t x_xor_q = x ^ q;
|
||||
uint16_t x_xor_q_ = x_xor_q >> (uint32_t)15U;
|
||||
return x_xor_q_ - (uint16_t)1U;
|
||||
}
|
||||
|
||||
uint8_t FStar_UInt8_eq_mask(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint8_t x = a ^ b;
|
||||
uint8_t minus_x = ~x + (uint8_t)1U;
|
||||
uint8_t x_or_minus_x = x | minus_x;
|
||||
uint8_t xnx = x_or_minus_x >> (uint32_t)7U;
|
||||
return xnx - (uint8_t)1U;
|
||||
}
|
||||
|
||||
uint8_t FStar_UInt8_gte_mask(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint8_t x = a;
|
||||
uint8_t y = b;
|
||||
uint8_t x_xor_y = x ^ y;
|
||||
uint8_t x_sub_y = x - y;
|
||||
uint8_t x_sub_y_xor_y = x_sub_y ^ y;
|
||||
uint8_t q = x_xor_y | x_sub_y_xor_y;
|
||||
uint8_t x_xor_q = x ^ q;
|
||||
uint8_t x_xor_q_ = x_xor_q >> (uint32_t)7U;
|
||||
return x_xor_q_ - (uint8_t)1U;
|
||||
}
|
||||
|
||||
-805
@@ -1,805 +0,0 @@
|
||||
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache 2.0 License. */
|
||||
|
||||
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
|
||||
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
|
||||
* F* version: 059db0c8
|
||||
* KreMLin version: 916c37ac
|
||||
*/
|
||||
|
||||
|
||||
#include "Hacl_Curve25519.h"
|
||||
|
||||
extern uint64_t FStar_UInt64_eq_mask(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern uint64_t FStar_UInt64_gte_mask(uint64_t x0, uint64_t x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
FStar_UInt128_add(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
FStar_UInt128_add_mod(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128
|
||||
FStar_UInt128_logand(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
|
||||
|
||||
extern FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 x0, uint32_t x1);
|
||||
|
||||
extern FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t x0);
|
||||
|
||||
extern uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 x0);
|
||||
|
||||
extern FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x0, uint64_t x1);
|
||||
|
||||
static void Hacl_Bignum_Modulo_carry_top(uint64_t *b)
|
||||
{
|
||||
uint64_t b4 = b[4U];
|
||||
uint64_t b0 = b[0U];
|
||||
uint64_t b4_ = b4 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t b0_ = b0 + (uint64_t)19U * (b4 >> (uint32_t)51U);
|
||||
b[4U] = b4_;
|
||||
b[0U] = b0_;
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, FStar_UInt128_uint128 *input)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
FStar_UInt128_uint128 xi = input[i];
|
||||
output[i] = FStar_UInt128_uint128_to_uint64(xi);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(
|
||||
FStar_UInt128_uint128 *output,
|
||||
uint64_t *input,
|
||||
uint64_t s
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
FStar_UInt128_uint128 xi = output[i];
|
||||
uint64_t yi = input[i];
|
||||
output[i] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s));
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fproduct_carry_wide_(FStar_UInt128_uint128 *tmp)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint32_t ctr = i;
|
||||
FStar_UInt128_uint128 tctr = tmp[ctr];
|
||||
FStar_UInt128_uint128 tctrp1 = tmp[ctr + (uint32_t)1U];
|
||||
uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU;
|
||||
FStar_UInt128_uint128 c = FStar_UInt128_shift_right(tctr, (uint32_t)51U);
|
||||
tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0);
|
||||
tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fmul_shift_reduce(uint64_t *output)
|
||||
{
|
||||
uint64_t tmp = output[4U];
|
||||
uint64_t b0;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint32_t ctr = (uint32_t)5U - i - (uint32_t)1U;
|
||||
uint64_t z = output[ctr - (uint32_t)1U];
|
||||
output[ctr] = z;
|
||||
}
|
||||
}
|
||||
output[0U] = tmp;
|
||||
b0 = output[0U];
|
||||
output[0U] = (uint64_t)19U * b0;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Bignum_Fmul_mul_shift_reduce_(
|
||||
FStar_UInt128_uint128 *output,
|
||||
uint64_t *input,
|
||||
uint64_t *input2
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint64_t input2i;
|
||||
{
|
||||
uint32_t i0;
|
||||
for (i0 = (uint32_t)0U; i0 < (uint32_t)4U; i0 = i0 + (uint32_t)1U)
|
||||
{
|
||||
uint64_t input2i0 = input2[i0];
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i0);
|
||||
Hacl_Bignum_Fmul_shift_reduce(input);
|
||||
}
|
||||
}
|
||||
i = (uint32_t)4U;
|
||||
input2i = input2[i];
|
||||
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2)
|
||||
{
|
||||
uint64_t tmp[5U] = { 0U };
|
||||
memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]);
|
||||
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
|
||||
{
|
||||
FStar_UInt128_uint128 t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
|
||||
}
|
||||
{
|
||||
FStar_UInt128_uint128 b4;
|
||||
FStar_UInt128_uint128 b0;
|
||||
FStar_UInt128_uint128 b4_;
|
||||
FStar_UInt128_uint128 b0_;
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
|
||||
Hacl_Bignum_Fproduct_carry_wide_(t);
|
||||
b4 = t[4U];
|
||||
b0 = t[0U];
|
||||
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
|
||||
b0_ =
|
||||
FStar_UInt128_add(b0,
|
||||
FStar_UInt128_mul_wide((uint64_t)19U,
|
||||
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
|
||||
t[4U] = b4_;
|
||||
t[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
|
||||
i0 = output[0U];
|
||||
i1 = output[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
output[0U] = i0_;
|
||||
output[1U] = i1_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare__(FStar_UInt128_uint128 *tmp, uint64_t *output)
|
||||
{
|
||||
uint64_t r0 = output[0U];
|
||||
uint64_t r1 = output[1U];
|
||||
uint64_t r2 = output[2U];
|
||||
uint64_t r3 = output[3U];
|
||||
uint64_t r4 = output[4U];
|
||||
uint64_t d0 = r0 * (uint64_t)2U;
|
||||
uint64_t d1 = r1 * (uint64_t)2U;
|
||||
uint64_t d2 = r2 * (uint64_t)2U * (uint64_t)19U;
|
||||
uint64_t d419 = r4 * (uint64_t)19U;
|
||||
uint64_t d4 = d419 * (uint64_t)2U;
|
||||
FStar_UInt128_uint128
|
||||
s0 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(r0, r0),
|
||||
FStar_UInt128_mul_wide(d4, r1)),
|
||||
FStar_UInt128_mul_wide(d2, r3));
|
||||
FStar_UInt128_uint128
|
||||
s1 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r1),
|
||||
FStar_UInt128_mul_wide(d4, r2)),
|
||||
FStar_UInt128_mul_wide(r3 * (uint64_t)19U, r3));
|
||||
FStar_UInt128_uint128
|
||||
s2 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r2),
|
||||
FStar_UInt128_mul_wide(r1, r1)),
|
||||
FStar_UInt128_mul_wide(d4, r3));
|
||||
FStar_UInt128_uint128
|
||||
s3 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r3),
|
||||
FStar_UInt128_mul_wide(d1, r2)),
|
||||
FStar_UInt128_mul_wide(r4, d419));
|
||||
FStar_UInt128_uint128
|
||||
s4 =
|
||||
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r4),
|
||||
FStar_UInt128_mul_wide(d1, r3)),
|
||||
FStar_UInt128_mul_wide(r2, r2));
|
||||
tmp[0U] = s0;
|
||||
tmp[1U] = s1;
|
||||
tmp[2U] = s2;
|
||||
tmp[3U] = s3;
|
||||
tmp[4U] = s4;
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare_(FStar_UInt128_uint128 *tmp, uint64_t *output)
|
||||
{
|
||||
FStar_UInt128_uint128 b4;
|
||||
FStar_UInt128_uint128 b0;
|
||||
FStar_UInt128_uint128 b4_;
|
||||
FStar_UInt128_uint128 b0_;
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_Bignum_Fsquare_fsquare__(tmp, output);
|
||||
Hacl_Bignum_Fproduct_carry_wide_(tmp);
|
||||
b4 = tmp[4U];
|
||||
b0 = tmp[0U];
|
||||
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
|
||||
b0_ =
|
||||
FStar_UInt128_add(b0,
|
||||
FStar_UInt128_mul_wide((uint64_t)19U,
|
||||
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
|
||||
tmp[4U] = b4_;
|
||||
tmp[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
|
||||
i0 = output[0U];
|
||||
i1 = output[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
output[0U] = i0_;
|
||||
output[1U] = i1_;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(
|
||||
uint64_t *input,
|
||||
FStar_UInt128_uint128 *tmp,
|
||||
uint32_t count1
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
|
||||
for (i = (uint32_t)1U; i < count1; i = i + (uint32_t)1U)
|
||||
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
|
||||
}
|
||||
|
||||
inline static void
|
||||
Hacl_Bignum_Fsquare_fsquare_times(uint64_t *output, uint64_t *input, uint32_t count1)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
|
||||
{
|
||||
FStar_UInt128_uint128 t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
|
||||
}
|
||||
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Fsquare_fsquare_times_inplace(uint64_t *output, uint32_t count1)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
|
||||
{
|
||||
FStar_UInt128_uint128 t[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
|
||||
}
|
||||
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_Crecip_crecip(uint64_t *out, uint64_t *z)
|
||||
{
|
||||
uint64_t buf[20U] = { 0U };
|
||||
uint64_t *a0 = buf;
|
||||
uint64_t *t00 = buf + (uint32_t)5U;
|
||||
uint64_t *b0 = buf + (uint32_t)10U;
|
||||
uint64_t *t01;
|
||||
uint64_t *b1;
|
||||
uint64_t *c0;
|
||||
uint64_t *a;
|
||||
uint64_t *t0;
|
||||
uint64_t *b;
|
||||
uint64_t *c;
|
||||
Hacl_Bignum_Fsquare_fsquare_times(a0, z, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)2U);
|
||||
Hacl_Bignum_Fmul_fmul(b0, t00, z);
|
||||
Hacl_Bignum_Fmul_fmul(a0, b0, a0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)1U);
|
||||
Hacl_Bignum_Fmul_fmul(b0, t00, b0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t00, b0, (uint32_t)5U);
|
||||
t01 = buf + (uint32_t)5U;
|
||||
b1 = buf + (uint32_t)10U;
|
||||
c0 = buf + (uint32_t)15U;
|
||||
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)10U);
|
||||
Hacl_Bignum_Fmul_fmul(c0, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, c0, (uint32_t)20U);
|
||||
Hacl_Bignum_Fmul_fmul(t01, t01, c0);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t01, (uint32_t)10U);
|
||||
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)50U);
|
||||
a = buf;
|
||||
t0 = buf + (uint32_t)5U;
|
||||
b = buf + (uint32_t)10U;
|
||||
c = buf + (uint32_t)15U;
|
||||
Hacl_Bignum_Fmul_fmul(c, t0, b);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(t0, c, (uint32_t)100U);
|
||||
Hacl_Bignum_Fmul_fmul(t0, t0, c);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)50U);
|
||||
Hacl_Bignum_Fmul_fmul(t0, t0, b);
|
||||
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)5U);
|
||||
Hacl_Bignum_Fmul_fmul(out, t0, a);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fsum(uint64_t *a, uint64_t *b)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = a[i];
|
||||
uint64_t yi = b[i];
|
||||
a[i] = xi + yi;
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fdifference(uint64_t *a, uint64_t *b)
|
||||
{
|
||||
uint64_t tmp[5U] = { 0U };
|
||||
uint64_t b0;
|
||||
uint64_t b1;
|
||||
uint64_t b2;
|
||||
uint64_t b3;
|
||||
uint64_t b4;
|
||||
memcpy(tmp, b, (uint32_t)5U * sizeof b[0U]);
|
||||
b0 = tmp[0U];
|
||||
b1 = tmp[1U];
|
||||
b2 = tmp[2U];
|
||||
b3 = tmp[3U];
|
||||
b4 = tmp[4U];
|
||||
tmp[0U] = b0 + (uint64_t)0x3fffffffffff68U;
|
||||
tmp[1U] = b1 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[2U] = b2 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[3U] = b3 + (uint64_t)0x3ffffffffffff8U;
|
||||
tmp[4U] = b4 + (uint64_t)0x3ffffffffffff8U;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = a[i];
|
||||
uint64_t yi = tmp[i];
|
||||
a[i] = yi - xi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fscalar(uint64_t *output, uint64_t *b, uint64_t s)
|
||||
{
|
||||
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
|
||||
{
|
||||
FStar_UInt128_uint128 tmp[5U];
|
||||
{
|
||||
uint32_t _i;
|
||||
for (_i = 0U; _i < (uint32_t)5U; ++_i)
|
||||
tmp[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
|
||||
}
|
||||
{
|
||||
FStar_UInt128_uint128 b4;
|
||||
FStar_UInt128_uint128 b0;
|
||||
FStar_UInt128_uint128 b4_;
|
||||
FStar_UInt128_uint128 b0_;
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
|
||||
{
|
||||
uint64_t xi = b[i];
|
||||
tmp[i] = FStar_UInt128_mul_wide(xi, s);
|
||||
}
|
||||
}
|
||||
Hacl_Bignum_Fproduct_carry_wide_(tmp);
|
||||
b4 = tmp[4U];
|
||||
b0 = tmp[0U];
|
||||
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
|
||||
b0_ =
|
||||
FStar_UInt128_add(b0,
|
||||
FStar_UInt128_mul_wide((uint64_t)19U,
|
||||
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
|
||||
tmp[4U] = b4_;
|
||||
tmp[0U] = b0_;
|
||||
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_fmul(uint64_t *output, uint64_t *a, uint64_t *b)
|
||||
{
|
||||
Hacl_Bignum_Fmul_fmul(output, a, b);
|
||||
}
|
||||
|
||||
inline static void Hacl_Bignum_crecip(uint64_t *output, uint64_t *input)
|
||||
{
|
||||
Hacl_Bignum_Crecip_crecip(output, input);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Point_swap_conditional_step(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
|
||||
{
|
||||
uint32_t i = ctr - (uint32_t)1U;
|
||||
uint64_t ai = a[i];
|
||||
uint64_t bi = b[i];
|
||||
uint64_t x = swap1 & (ai ^ bi);
|
||||
uint64_t ai1 = ai ^ x;
|
||||
uint64_t bi1 = bi ^ x;
|
||||
a[i] = ai1;
|
||||
b[i] = bi1;
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Point_swap_conditional_(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
|
||||
{
|
||||
if (!(ctr == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i;
|
||||
Hacl_EC_Point_swap_conditional_step(a, b, swap1, ctr);
|
||||
i = ctr - (uint32_t)1U;
|
||||
Hacl_EC_Point_swap_conditional_(a, b, swap1, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void Hacl_EC_Point_swap_conditional(uint64_t *a, uint64_t *b, uint64_t iswap)
|
||||
{
|
||||
uint64_t swap1 = (uint64_t)0U - iswap;
|
||||
Hacl_EC_Point_swap_conditional_(a, b, swap1, (uint32_t)5U);
|
||||
Hacl_EC_Point_swap_conditional_(a + (uint32_t)5U, b + (uint32_t)5U, swap1, (uint32_t)5U);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Point_copy(uint64_t *output, uint64_t *input)
|
||||
{
|
||||
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
|
||||
memcpy(output + (uint32_t)5U,
|
||||
input + (uint32_t)5U,
|
||||
(uint32_t)5U * sizeof (input + (uint32_t)5U)[0U]);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fexpand(uint64_t *output, uint8_t *input)
|
||||
{
|
||||
uint64_t i0 = load64_le(input);
|
||||
uint8_t *x00 = input + (uint32_t)6U;
|
||||
uint64_t i1 = load64_le(x00);
|
||||
uint8_t *x01 = input + (uint32_t)12U;
|
||||
uint64_t i2 = load64_le(x01);
|
||||
uint8_t *x02 = input + (uint32_t)19U;
|
||||
uint64_t i3 = load64_le(x02);
|
||||
uint8_t *x0 = input + (uint32_t)24U;
|
||||
uint64_t i4 = load64_le(x0);
|
||||
uint64_t output0 = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output1 = i1 >> (uint32_t)3U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output2 = i2 >> (uint32_t)6U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output3 = i3 >> (uint32_t)1U & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t output4 = i4 >> (uint32_t)12U & (uint64_t)0x7ffffffffffffU;
|
||||
output[0U] = output0;
|
||||
output[1U] = output1;
|
||||
output[2U] = output2;
|
||||
output[3U] = output3;
|
||||
output[4U] = output4;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_first_carry_pass(uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
|
||||
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
|
||||
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
|
||||
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
|
||||
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
|
||||
input[0U] = t0_;
|
||||
input[1U] = t1__;
|
||||
input[2U] = t2__;
|
||||
input[3U] = t3__;
|
||||
input[4U] = t4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_first_carry_full(uint64_t *input)
|
||||
{
|
||||
Hacl_EC_Format_fcontract_first_carry_pass(input);
|
||||
Hacl_Bignum_Modulo_carry_top(input);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_second_carry_pass(uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
|
||||
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
|
||||
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
|
||||
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
|
||||
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
|
||||
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
|
||||
input[0U] = t0_;
|
||||
input[1U] = t1__;
|
||||
input[2U] = t2__;
|
||||
input[3U] = t3__;
|
||||
input[4U] = t4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_second_carry_full(uint64_t *input)
|
||||
{
|
||||
uint64_t i0;
|
||||
uint64_t i1;
|
||||
uint64_t i0_;
|
||||
uint64_t i1_;
|
||||
Hacl_EC_Format_fcontract_second_carry_pass(input);
|
||||
Hacl_Bignum_Modulo_carry_top(input);
|
||||
i0 = input[0U];
|
||||
i1 = input[1U];
|
||||
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
|
||||
i1_ = i1 + (i0 >> (uint32_t)51U);
|
||||
input[0U] = i0_;
|
||||
input[1U] = i1_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_trim(uint64_t *input)
|
||||
{
|
||||
uint64_t a0 = input[0U];
|
||||
uint64_t a1 = input[1U];
|
||||
uint64_t a2 = input[2U];
|
||||
uint64_t a3 = input[3U];
|
||||
uint64_t a4 = input[4U];
|
||||
uint64_t mask0 = FStar_UInt64_gte_mask(a0, (uint64_t)0x7ffffffffffedU);
|
||||
uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask3 = FStar_UInt64_eq_mask(a3, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask4 = FStar_UInt64_eq_mask(a4, (uint64_t)0x7ffffffffffffU);
|
||||
uint64_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4;
|
||||
uint64_t a0_ = a0 - ((uint64_t)0x7ffffffffffedU & mask);
|
||||
uint64_t a1_ = a1 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a2_ = a2 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a3_ = a3 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
uint64_t a4_ = a4 - ((uint64_t)0x7ffffffffffffU & mask);
|
||||
input[0U] = a0_;
|
||||
input[1U] = a1_;
|
||||
input[2U] = a2_;
|
||||
input[3U] = a3_;
|
||||
input[4U] = a4_;
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract_store(uint8_t *output, uint64_t *input)
|
||||
{
|
||||
uint64_t t0 = input[0U];
|
||||
uint64_t t1 = input[1U];
|
||||
uint64_t t2 = input[2U];
|
||||
uint64_t t3 = input[3U];
|
||||
uint64_t t4 = input[4U];
|
||||
uint64_t o0 = t1 << (uint32_t)51U | t0;
|
||||
uint64_t o1 = t2 << (uint32_t)38U | t1 >> (uint32_t)13U;
|
||||
uint64_t o2 = t3 << (uint32_t)25U | t2 >> (uint32_t)26U;
|
||||
uint64_t o3 = t4 << (uint32_t)12U | t3 >> (uint32_t)39U;
|
||||
uint8_t *b0 = output;
|
||||
uint8_t *b1 = output + (uint32_t)8U;
|
||||
uint8_t *b2 = output + (uint32_t)16U;
|
||||
uint8_t *b3 = output + (uint32_t)24U;
|
||||
store64_le(b0, o0);
|
||||
store64_le(b1, o1);
|
||||
store64_le(b2, o2);
|
||||
store64_le(b3, o3);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_fcontract(uint8_t *output, uint64_t *input)
|
||||
{
|
||||
Hacl_EC_Format_fcontract_first_carry_full(input);
|
||||
Hacl_EC_Format_fcontract_second_carry_full(input);
|
||||
Hacl_EC_Format_fcontract_trim(input);
|
||||
Hacl_EC_Format_fcontract_store(output, input);
|
||||
}
|
||||
|
||||
static void Hacl_EC_Format_scalar_of_point(uint8_t *scalar, uint64_t *point)
|
||||
{
|
||||
uint64_t *x = point;
|
||||
uint64_t *z = point + (uint32_t)5U;
|
||||
uint64_t buf[10U] = { 0U };
|
||||
uint64_t *zmone = buf;
|
||||
uint64_t *sc = buf + (uint32_t)5U;
|
||||
Hacl_Bignum_crecip(zmone, z);
|
||||
Hacl_Bignum_fmul(sc, x, zmone);
|
||||
Hacl_EC_Format_fcontract(scalar, sc);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_AddAndDouble_fmonty(
|
||||
uint64_t *pp,
|
||||
uint64_t *ppq,
|
||||
uint64_t *p,
|
||||
uint64_t *pq,
|
||||
uint64_t *qmqp
|
||||
)
|
||||
{
|
||||
uint64_t *qx = qmqp;
|
||||
uint64_t *x2 = pp;
|
||||
uint64_t *z2 = pp + (uint32_t)5U;
|
||||
uint64_t *x3 = ppq;
|
||||
uint64_t *z3 = ppq + (uint32_t)5U;
|
||||
uint64_t *x = p;
|
||||
uint64_t *z = p + (uint32_t)5U;
|
||||
uint64_t *xprime = pq;
|
||||
uint64_t *zprime = pq + (uint32_t)5U;
|
||||
uint64_t buf[40U] = { 0U };
|
||||
uint64_t *origx = buf;
|
||||
uint64_t *origxprime0 = buf + (uint32_t)5U;
|
||||
uint64_t *xxprime0 = buf + (uint32_t)25U;
|
||||
uint64_t *zzprime0 = buf + (uint32_t)30U;
|
||||
uint64_t *origxprime;
|
||||
uint64_t *xx0;
|
||||
uint64_t *zz0;
|
||||
uint64_t *xxprime;
|
||||
uint64_t *zzprime;
|
||||
uint64_t *zzzprime;
|
||||
uint64_t *zzz;
|
||||
uint64_t *xx;
|
||||
uint64_t *zz;
|
||||
uint64_t scalar;
|
||||
memcpy(origx, x, (uint32_t)5U * sizeof x[0U]);
|
||||
Hacl_Bignum_fsum(x, z);
|
||||
Hacl_Bignum_fdifference(z, origx);
|
||||
memcpy(origxprime0, xprime, (uint32_t)5U * sizeof xprime[0U]);
|
||||
Hacl_Bignum_fsum(xprime, zprime);
|
||||
Hacl_Bignum_fdifference(zprime, origxprime0);
|
||||
Hacl_Bignum_fmul(xxprime0, xprime, z);
|
||||
Hacl_Bignum_fmul(zzprime0, x, zprime);
|
||||
origxprime = buf + (uint32_t)5U;
|
||||
xx0 = buf + (uint32_t)15U;
|
||||
zz0 = buf + (uint32_t)20U;
|
||||
xxprime = buf + (uint32_t)25U;
|
||||
zzprime = buf + (uint32_t)30U;
|
||||
zzzprime = buf + (uint32_t)35U;
|
||||
memcpy(origxprime, xxprime, (uint32_t)5U * sizeof xxprime[0U]);
|
||||
Hacl_Bignum_fsum(xxprime, zzprime);
|
||||
Hacl_Bignum_fdifference(zzprime, origxprime);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(x3, xxprime, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(zzzprime, zzprime, (uint32_t)1U);
|
||||
Hacl_Bignum_fmul(z3, zzzprime, qx);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(xx0, x, (uint32_t)1U);
|
||||
Hacl_Bignum_Fsquare_fsquare_times(zz0, z, (uint32_t)1U);
|
||||
zzz = buf + (uint32_t)10U;
|
||||
xx = buf + (uint32_t)15U;
|
||||
zz = buf + (uint32_t)20U;
|
||||
Hacl_Bignum_fmul(x2, xx, zz);
|
||||
Hacl_Bignum_fdifference(zz, xx);
|
||||
scalar = (uint64_t)121665U;
|
||||
Hacl_Bignum_fscalar(zzz, zz, scalar);
|
||||
Hacl_Bignum_fsum(zzz, xx);
|
||||
Hacl_Bignum_fmul(z2, zzz, zz);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt
|
||||
)
|
||||
{
|
||||
uint64_t bit0 = (uint64_t)(byt >> (uint32_t)7U);
|
||||
uint64_t bit;
|
||||
Hacl_EC_Point_swap_conditional(nq, nqpq, bit0);
|
||||
Hacl_EC_AddAndDouble_fmonty(nq2, nqpq2, nq, nqpq, q);
|
||||
bit = (uint64_t)(byt >> (uint32_t)7U);
|
||||
Hacl_EC_Point_swap_conditional(nq2, nqpq2, bit);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt
|
||||
)
|
||||
{
|
||||
uint8_t byt1;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt);
|
||||
byt1 = byt << (uint32_t)1U;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1);
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint8_t byt,
|
||||
uint32_t i
|
||||
)
|
||||
{
|
||||
if (!(i == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i_ = i - (uint32_t)1U;
|
||||
uint8_t byt_;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt);
|
||||
byt_ = byt << (uint32_t)2U;
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byt_, i_);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(
|
||||
uint8_t *n1,
|
||||
uint64_t *nq,
|
||||
uint64_t *nqpq,
|
||||
uint64_t *nq2,
|
||||
uint64_t *nqpq2,
|
||||
uint64_t *q,
|
||||
uint32_t i
|
||||
)
|
||||
{
|
||||
if (!(i == (uint32_t)0U))
|
||||
{
|
||||
uint32_t i1 = i - (uint32_t)1U;
|
||||
uint8_t byte = n1[i1];
|
||||
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, (uint32_t)4U);
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, i1);
|
||||
}
|
||||
}
|
||||
|
||||
static void Hacl_EC_Ladder_cmult(uint64_t *result, uint8_t *n1, uint64_t *q)
|
||||
{
|
||||
uint64_t point_buf[40U] = { 0U };
|
||||
uint64_t *nq = point_buf;
|
||||
uint64_t *nqpq = point_buf + (uint32_t)10U;
|
||||
uint64_t *nq2 = point_buf + (uint32_t)20U;
|
||||
uint64_t *nqpq2 = point_buf + (uint32_t)30U;
|
||||
Hacl_EC_Point_copy(nqpq, q);
|
||||
nq[0U] = (uint64_t)1U;
|
||||
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, (uint32_t)32U);
|
||||
Hacl_EC_Point_copy(result, nq);
|
||||
}
|
||||
|
||||
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint)
|
||||
{
|
||||
uint64_t buf0[10U] = { 0U };
|
||||
uint64_t *x0 = buf0;
|
||||
uint64_t *z = buf0 + (uint32_t)5U;
|
||||
uint64_t *q;
|
||||
Hacl_EC_Format_fexpand(x0, basepoint);
|
||||
z[0U] = (uint64_t)1U;
|
||||
q = buf0;
|
||||
{
|
||||
uint8_t e[32U] = { 0U };
|
||||
uint8_t e0;
|
||||
uint8_t e31;
|
||||
uint8_t e01;
|
||||
uint8_t e311;
|
||||
uint8_t e312;
|
||||
uint8_t *scalar;
|
||||
memcpy(e, secret, (uint32_t)32U * sizeof secret[0U]);
|
||||
e0 = e[0U];
|
||||
e31 = e[31U];
|
||||
e01 = e0 & (uint8_t)248U;
|
||||
e311 = e31 & (uint8_t)127U;
|
||||
e312 = e311 | (uint8_t)64U;
|
||||
e[0U] = e01;
|
||||
e[31U] = e312;
|
||||
scalar = e;
|
||||
{
|
||||
uint64_t buf[15U] = { 0U };
|
||||
uint64_t *nq = buf;
|
||||
uint64_t *x = nq;
|
||||
x[0U] = (uint64_t)1U;
|
||||
Hacl_EC_Ladder_cmult(nq, scalar, q);
|
||||
Hacl_EC_Format_scalar_of_point(mypublic, nq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-186
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* ECDH with curve-optimized implementation multiplexing
|
||||
*
|
||||
* Copyright 2016-2018 INRIA and Microsoft Corporation
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
|
||||
#include <mbedtls/ecdh.h>
|
||||
|
||||
#if !(defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16))
|
||||
#define KRML_VERIFIED_UINT128
|
||||
#endif
|
||||
|
||||
#include <Hacl_Curve25519.h>
|
||||
#include <mbedtls/platform_util.h>
|
||||
|
||||
#include "x25519.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Initialize context
|
||||
*/
|
||||
void mbedtls_x25519_init( mbedtls_x25519_context *ctx )
|
||||
{
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x25519_context ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Free context
|
||||
*/
|
||||
void mbedtls_x25519_free( mbedtls_x25519_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
mbedtls_platform_zeroize( ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
}
|
||||
|
||||
int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
uint8_t base[MBEDTLS_X25519_KEY_SIZE_BYTES] = {0};
|
||||
|
||||
if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
|
||||
return ret;
|
||||
|
||||
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 4;
|
||||
if( blen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
*buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
|
||||
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 >> 8;
|
||||
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 & 0xFF;
|
||||
*buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
|
||||
|
||||
base[0] = 9;
|
||||
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
|
||||
|
||||
base[0] = 0;
|
||||
if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
|
||||
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
|
||||
const unsigned char **buf, const unsigned char *end )
|
||||
{
|
||||
if( end - *buf < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ( *(*buf)++ != MBEDTLS_X25519_KEY_SIZE_BYTES ) )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
memcpy( ctx->peer_point, *buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
*buf += MBEDTLS_X25519_KEY_SIZE_BYTES;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
|
||||
mbedtls_x25519_ecdh_side side )
|
||||
{
|
||||
size_t olen = 0;
|
||||
|
||||
switch( side ) {
|
||||
case MBEDTLS_X25519_ECDH_THEIRS:
|
||||
return mbedtls_ecp_point_write_binary( &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
case MBEDTLS_X25519_ECDH_OURS:
|
||||
return mbedtls_mpi_write_binary_le( &key->d, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
default:
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
/* f_rng and p_rng are not used here because this implementation does not
|
||||
need blinding since it has constant trace. */
|
||||
(( void )f_rng);
|
||||
(( void )p_rng);
|
||||
|
||||
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES;
|
||||
|
||||
if( blen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, ctx->peer_point);
|
||||
|
||||
/* Wipe the DH secret and don't let the peer chose a small subgroup point */
|
||||
mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
|
||||
if( memcmp( buf, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
|
||||
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int( *f_rng )(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char base[MBEDTLS_X25519_KEY_SIZE_BYTES] = { 0 };
|
||||
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
|
||||
return ret;
|
||||
|
||||
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 1;
|
||||
if( blen < *olen )
|
||||
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
|
||||
*buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
|
||||
|
||||
base[0] = 9;
|
||||
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
|
||||
|
||||
base[0] = 0;
|
||||
if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES ) == 0 )
|
||||
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
|
||||
const unsigned char *buf, size_t blen )
|
||||
{
|
||||
if( blen < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
|
||||
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
|
||||
if( (*buf++ != MBEDTLS_X25519_KEY_SIZE_BYTES) )
|
||||
return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
|
||||
memcpy( ctx->peer_point, buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
#endif /* MBEDTLS_ECDH_C && MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */
|
||||
Vendored
-40
@@ -1,40 +0,0 @@
|
||||
set(p256m_target ${MBEDTLS_TARGET_PREFIX}p256m)
|
||||
|
||||
add_library(${p256m_target}
|
||||
p256-m_driver_entrypoints.c
|
||||
p256-m/p256-m.c)
|
||||
|
||||
target_include_directories(${p256m_target}
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/p256-m>
|
||||
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
PRIVATE ${MBEDTLS_DIR}/library/)
|
||||
|
||||
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
|
||||
# This must be duplicated from library/CMakeLists.txt because
|
||||
# p256m is not directly linked against any mbedtls targets
|
||||
# so does not inherit the compile definitions.
|
||||
if(MBEDTLS_CONFIG_FILE)
|
||||
target_compile_definitions(${p256m_target}
|
||||
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
|
||||
endif()
|
||||
if(MBEDTLS_USER_CONFIG_FILE)
|
||||
target_compile_definitions(${p256m_target}
|
||||
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
|
||||
endif()
|
||||
|
||||
if(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
install(DIRECTORY :${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DESTINATION include
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
endif(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
install(TARGETS ${p256m_target}
|
||||
EXPORT MbedTLSTargets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/p256-m/p256-m/include -I$(THIRDPARTY_DIR)/p256-m/p256-m/include/p256-m -I$(THIRDPARTY_DIR)/p256-m/p256-m_driver_interface
|
||||
|
||||
THIRDPARTY_CRYPTO_OBJECTS+= \
|
||||
$(THIRDPARTY_DIR)/p256-m//p256-m_driver_entrypoints.o \
|
||||
$(THIRDPARTY_DIR)/p256-m//p256-m/p256-m.o
|
||||
Vendored
-4
@@ -1,4 +0,0 @@
|
||||
The files within the `p256-m/` subdirectory originate from the [p256-m GitHub repository](https://github.com/mpg/p256-m). They are distributed here under a dual Apache-2.0 OR GPL-2.0-or-later license. They are authored by Manuel Pégourié-Gonnard. p256-m is a minimalistic implementation of ECDH and ECDSA on NIST P-256, especially suited to constrained 32-bit environments. Mbed TLS documentation for integrating drivers uses p256-m as an example of a software accelerator, and describes how it can be integrated alongside Mbed TLS. It should be noted that p256-m files in the Mbed TLS repo will not be updated regularly, so they may not have fixes and improvements present in the upstream project.
|
||||
|
||||
The files `p256-m.c`, `p256-m.h` and `README.md` have been taken from the `p256-m` repository.
|
||||
It should be noted that p256-m deliberately does not supply its own cryptographically secure RNG function. As a result, the PSA RNG is used, with `p256_generate_random()` wrapping `psa_generate_random()`.
|
||||
Vendored
-544
@@ -1,544 +0,0 @@
|
||||
*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).
|
||||
Vendored
-1514
File diff suppressed because it is too large
Load Diff
Vendored
-135
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Interface of curve P-256 (ECDH and ECDSA)
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* Author: Manuel Pégourié-Gonnard.
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef P256_M_H
|
||||
#define P256_M_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Status codes */
|
||||
#define P256_SUCCESS 0
|
||||
#define P256_RANDOM_FAILED -1
|
||||
#define P256_INVALID_PUBKEY -2
|
||||
#define P256_INVALID_PRIVKEY -3
|
||||
#define P256_INVALID_SIGNATURE -4
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RNG function - must be provided externally and be cryptographically secure.
|
||||
*
|
||||
* in: output - must point to a writable buffer of at least output_size bytes.
|
||||
* output_size - the number of random bytes to write to output.
|
||||
* out: output is filled with output_size random bytes.
|
||||
* return 0 on success, non-zero on errors.
|
||||
*/
|
||||
extern int p256_generate_random(uint8_t * output, unsigned output_size);
|
||||
|
||||
/*
|
||||
* ECDH/ECDSA generate key pair
|
||||
*
|
||||
* [in] draws from p256_generate_random()
|
||||
* [out] priv: on success, holds the private key, as a big-endian integer
|
||||
* [out] pub: on success, holds the public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_RANDOM_FAILED on failure
|
||||
*/
|
||||
int p256_gen_keypair(uint8_t priv[32], uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* ECDH compute shared secret
|
||||
*
|
||||
* [out] secret: on success, holds the shared secret, as a big-endian integer
|
||||
* [in] priv: our private key as a big-endian integer
|
||||
* [in] pub: the peer's public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
*/
|
||||
int p256_ecdh_shared_secret(uint8_t secret[32],
|
||||
const uint8_t priv[32], const uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* ECDSA sign
|
||||
*
|
||||
* [in] draws from p256_generate_random()
|
||||
* [out] sig: on success, holds the signature, as two big-endian integers
|
||||
* [in] priv: our private key as a big-endian integer
|
||||
* [in] hash: the hash of the message to be signed
|
||||
* [in] hlen: the size of hash in bytes
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_RANDOM_FAILED on failure
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_ecdsa_sign(uint8_t sig[64], const uint8_t priv[32],
|
||||
const uint8_t *hash, size_t hlen);
|
||||
|
||||
/*
|
||||
* ECDSA verify
|
||||
*
|
||||
* [in] sig: the signature to be verified, as two big-endian integers
|
||||
* [in] pub: the associated public key, as two big-endian integers
|
||||
* [in] hash: the hash of the message that was signed
|
||||
* [in] hlen: the size of hash in bytes
|
||||
*
|
||||
* return: P256_SUCCESS on success - the signature was verified as valid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
* P256_INVALID_SIGNATURE if the signature was found to be invalid
|
||||
*/
|
||||
int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
|
||||
const uint8_t *hash, size_t hlen);
|
||||
|
||||
/*
|
||||
* Public key validation
|
||||
*
|
||||
* Note: you never need to call this function, as all other functions always
|
||||
* validate their input; however it's availabe if you want to validate the key
|
||||
* without performing an operation.
|
||||
*
|
||||
* [in] pub: the public key, as two big-endian integers
|
||||
*
|
||||
* return: P256_SUCCESS if the key is valid
|
||||
* P256_INVALID_PUBKEY if pub is invalid
|
||||
*/
|
||||
int p256_validate_pubkey(const uint8_t pub[64]);
|
||||
|
||||
/*
|
||||
* Private key validation
|
||||
*
|
||||
* Note: you never need to call this function, as all other functions always
|
||||
* validate their input; however it's availabe if you want to validate the key
|
||||
* without performing an operation.
|
||||
*
|
||||
* [in] priv: the private key, as a big-endian integer
|
||||
*
|
||||
* return: P256_SUCCESS if the key is valid
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_validate_privkey(const uint8_t priv[32]);
|
||||
|
||||
/*
|
||||
* Compute public key from private key
|
||||
*
|
||||
* [out] pub: the associated public key, as two big-endian integers
|
||||
* [in] priv: the private key, as a big-endian integer
|
||||
*
|
||||
* return: P256_SUCCESS on success
|
||||
* P256_INVALID_PRIVKEY if priv is invalid
|
||||
*/
|
||||
int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* P256_M_H */
|
||||
-312
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
* Driver entry points for p256-m
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "p256-m_driver_entrypoints.h"
|
||||
#include "p256-m/p256-m.h"
|
||||
#include "psa/crypto.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "psa_crypto_driver_wrappers_no_static.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
|
||||
/* INFORMATION ON PSA KEY EXPORT FORMATS:
|
||||
*
|
||||
* PSA exports SECP256R1 keys in two formats:
|
||||
* 1. Keypair format: 32 byte string which is just the private key (public key
|
||||
* can be calculated from the private key)
|
||||
* 2. Public Key format: A leading byte 0x04 (indicating uncompressed format),
|
||||
* followed by the 64 byte public key. This results in a
|
||||
* total of 65 bytes.
|
||||
*
|
||||
* p256-m's internal format for private keys matches PSA. Its format for public
|
||||
* keys is only 64 bytes: the same as PSA but without the leading byte (0x04).
|
||||
* Hence, when passing public keys from PSA to p256-m, the leading byte is
|
||||
* removed.
|
||||
*
|
||||
* Shared secret and signature have the same format between PSA and p256-m.
|
||||
*/
|
||||
#define PSA_PUBKEY_SIZE 65
|
||||
#define PSA_PUBKEY_HEADER_BYTE 0x04
|
||||
#define P256_PUBKEY_SIZE 64
|
||||
#define PRIVKEY_SIZE 32
|
||||
#define SHARED_SECRET_SIZE 32
|
||||
#define SIGNATURE_SIZE 64
|
||||
|
||||
#define CURVE_BITS 256
|
||||
|
||||
/* Convert between p256-m and PSA error codes */
|
||||
static psa_status_t p256_to_psa_error(int ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case P256_SUCCESS:
|
||||
return PSA_SUCCESS;
|
||||
case P256_INVALID_PUBKEY:
|
||||
case P256_INVALID_PRIVKEY:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case P256_INVALID_SIGNATURE:
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
case P256_RANDOM_FAILED:
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits)
|
||||
{
|
||||
/* Check the key size */
|
||||
if (*bits != 0 && *bits != CURVE_BITS) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Validate the key (and its type and size) */
|
||||
psa_key_type_t type = psa_get_key_type(attributes);
|
||||
if (type == PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
if (data_length != PSA_PUBKEY_SIZE) {
|
||||
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
if (p256_validate_pubkey(data + 1) != P256_SUCCESS) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else if (type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
if (data_length != PRIVKEY_SIZE) {
|
||||
return *bits == 0 ? PSA_ERROR_NOT_SUPPORTED : PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (p256_validate_privkey(data) != P256_SUCCESS) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*bits = CURVE_BITS;
|
||||
|
||||
/* We only support the export format for input, so just copy. */
|
||||
if (key_buffer_size < data_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(key_buffer, data, data_length);
|
||||
*key_buffer_length = data_length;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
/* Is this the right curve? */
|
||||
size_t bits = psa_get_key_bits(attributes);
|
||||
psa_key_type_t type = psa_get_key_type(attributes);
|
||||
if (bits != CURVE_BITS || type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (data_size < PSA_PUBKEY_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
data[0] = PSA_PUBKEY_HEADER_BYTE;
|
||||
int ret = p256_public_from_private(data + 1, key_buffer);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*data_length = PSA_PUBKEY_SIZE;
|
||||
}
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length)
|
||||
{
|
||||
/* We don't use this argument, but the specification mandates the signature
|
||||
* of driver entry-points. (void) used to avoid compiler warning. */
|
||||
(void) attributes;
|
||||
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/*
|
||||
* p256-m's keypair generation function outputs both public and private
|
||||
* keys. Allocate a buffer to which the public key will be written. The
|
||||
* private key will be written to key_buffer, which is passed to this
|
||||
* function as an argument. */
|
||||
uint8_t public_key_buffer[P256_PUBKEY_SIZE];
|
||||
|
||||
int ret = p256_gen_keypair(key_buffer, public_key_buffer);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*key_buffer_length = PRIVKEY_SIZE;
|
||||
}
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
/* We don't use these arguments, but the specification mandates the
|
||||
* sginature of driver entry-points. (void) used to avoid compiler
|
||||
* warning. */
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE || peer_key_length != PSA_PUBKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (shared_secret_size < SHARED_SECRET_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
const uint8_t *peer_key_p256m = peer_key + 1;
|
||||
int ret = p256_ecdh_shared_secret(shared_secret, key_buffer, peer_key_p256m);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*shared_secret_length = SHARED_SECRET_SIZE;
|
||||
}
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
/* We don't use these arguments, but the specification mandates the
|
||||
* sginature of driver entry-points. (void) used to avoid compiler
|
||||
* warning. */
|
||||
(void) attributes;
|
||||
(void) alg;
|
||||
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PRIVKEY_SIZE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (signature_size < SIGNATURE_SIZE) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
int ret = p256_ecdsa_sign(signature, key_buffer, hash, hash_length);
|
||||
if (ret == P256_SUCCESS) {
|
||||
*signature_length = SIGNATURE_SIZE;
|
||||
}
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
/* This function expects the key buffer to contain a PSA public key,
|
||||
* as exported by psa_export_public_key() */
|
||||
static psa_status_t p256_verify_hash_with_public_key(
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
/* Validate sizes, as p256-m expects fixed-size buffers */
|
||||
if (key_buffer_size != PSA_PUBKEY_SIZE || *key_buffer != PSA_PUBKEY_HEADER_BYTE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (signature_length != SIGNATURE_SIZE) {
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
/* See INFORMATION ON PSA KEY EXPORT FORMATS near top of file */
|
||||
const uint8_t *public_key_p256m = key_buffer + 1;
|
||||
int ret = p256_ecdsa_verify(signature, public_key_p256m, hash, hash_length);
|
||||
|
||||
return p256_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
/* We don't use this argument, but the specification mandates the signature
|
||||
* of driver entry-points. (void) used to avoid compiler warning. */
|
||||
(void) alg;
|
||||
|
||||
psa_status_t status;
|
||||
uint8_t public_key_buffer[PSA_PUBKEY_SIZE];
|
||||
size_t public_key_buffer_size = PSA_PUBKEY_SIZE;
|
||||
|
||||
size_t public_key_length = PSA_PUBKEY_SIZE;
|
||||
/* As p256-m doesn't require dynamic allocation, we want to avoid it in
|
||||
* the entrypoint functions as well. psa_driver_wrapper_export_public_key()
|
||||
* requires size_t*, so we use a pointer to a stack variable. */
|
||||
size_t *public_key_length_ptr = &public_key_length;
|
||||
|
||||
/* The contents of key_buffer may either be the 32 byte private key
|
||||
* (keypair format), or 0x04 followed by the 64 byte public key (public
|
||||
* key format). To ensure the key is in the latter format, the public key
|
||||
* is exported. */
|
||||
status = psa_driver_wrapper_export_public_key(
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
public_key_buffer,
|
||||
public_key_buffer_size,
|
||||
public_key_length_ptr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = p256_verify_hash_with_public_key(
|
||||
public_key_buffer,
|
||||
public_key_buffer_size,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_length);
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Driver entry points for p256-m
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef P256M_DRIVER_ENTRYPOINTS_H
|
||||
#define P256M_DRIVER_ENTRYPOINTS_H
|
||||
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
|
||||
|
||||
#include "psa/crypto_types.h"
|
||||
|
||||
/** Import SECP256R1 key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] data The raw key material. For private keys
|
||||
* this must be a big-endian integer of 32
|
||||
* bytes; for public key this must be an
|
||||
* uncompressed ECPoint (65 bytes).
|
||||
* \param[in] data_length The size of the raw key material.
|
||||
* \param[out] key_buffer The buffer to contain the key data in
|
||||
* output format upon successful return.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
* \param[out] bits The bitsize of the key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The input is not supported by this driver (not SECP256R1).
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_import_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length,
|
||||
size_t *bits);
|
||||
|
||||
/** Export SECP256R1 public key, from the private key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The private key in the export format.
|
||||
* \param[in] key_buffer_size The size of the private key in bytes.
|
||||
* \param[out] data The buffer to contain the public key in
|
||||
* the export format upon successful return.
|
||||
* \param[in] data_size The size of the \p data buffer in bytes.
|
||||
* \param[out] data_length The length written to \p data in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The input is not supported by this driver (not SECP256R1).
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_export_public_key(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Generate SECP256R1 ECC Key Pair.
|
||||
* Interface function which calls the p256-m key generation function and
|
||||
* places it in the key buffer provided by the caller (Mbed TLS) in the
|
||||
* correct format. For a SECP256R1 curve this is the 32 bit private key.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[out] key_buffer The buffer to contain the key data in
|
||||
* output format upon successful return.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[out] key_buffer_length The length of the data written in \p
|
||||
* key_buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Keypair generated and stored in buffer.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p key_buffer_size is too small.
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* The internal RNG failed.
|
||||
*/
|
||||
psa_status_t p256_transparent_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
|
||||
/** Perform raw key agreement using p256-m's ECDH implementation
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A key agreement algorithm that is
|
||||
* compatible with the type of the key.
|
||||
* \param[in] peer_key The buffer containing the peer's public
|
||||
* key in format specified by PSA.
|
||||
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret The buffer to which the shared secret
|
||||
* is to be written.
|
||||
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||
* bytes.
|
||||
* \param[out] shared_secret_length On success, the number of bytes that
|
||||
* make up the returned shared secret.
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Shared secret successfully calculated.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p shared_secret_size is too small.
|
||||
*/
|
||||
psa_status_t p256_transparent_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length);
|
||||
|
||||
/** Sign an already-calculated hash with a private key using p256-m's ECDSA
|
||||
* implementation
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
* \param[in] key_buffer The buffer containing the private key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible
|
||||
* with the type of the key.
|
||||
* \param[in] hash The hash to sign.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[out] signature Buffer where signature is to be written.
|
||||
* \param[in] signature_size Size of the \p signature buffer in bytes.
|
||||
* \param[out] signature_length On success, the number of bytes
|
||||
* that make up the returned signature value.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success. Hash was signed successfully.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* \p signature_size is too small.
|
||||
* \retval #PSA_ERROR_GENERIC_ERROR
|
||||
* The internal RNG failed.
|
||||
*/
|
||||
psa_status_t p256_transparent_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length);
|
||||
|
||||
/** Verify the signature of a hash using a SECP256R1 public key using p256-m's
|
||||
* ECDSA implementation.
|
||||
*
|
||||
* \note p256-m expects a 64 byte public key, but the contents of the key
|
||||
buffer may be the 32 byte keypair representation or the 65 byte
|
||||
public key representation. As a result, this function calls
|
||||
psa_driver_wrapper_export_public_key() to ensure the public key
|
||||
can be passed to p256-m.
|
||||
*
|
||||
* \param[in] attributes The attributes of the key to use for the
|
||||
* operation.
|
||||
*
|
||||
* \param[in] key_buffer The buffer containing the key
|
||||
* in the format specified by PSA.
|
||||
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
* the type of the key.
|
||||
* \param[in] hash The hash whose signature is to be
|
||||
* verified.
|
||||
* \param[in] hash_length Size of the \p hash buffer in bytes.
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
* The calculation was performed successfully, but the passed
|
||||
* signature is not a valid signature.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The input is invalid.
|
||||
*/
|
||||
psa_status_t p256_transparent_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length);
|
||||
|
||||
#endif /* P256M_DRIVER_ENTRYPOINTS_H */
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
# Maintained branches
|
||||
|
||||
At any point in time, we have a number of maintained branches, currently consisting of:
|
||||
|
||||
- The [`main`](https://github.com/Mbed-TLS/mbedtls/tree/main) branch:
|
||||
this always contains the latest release, including all publicly available
|
||||
security fixes.
|
||||
- The [`development`](https://github.com/Mbed-TLS/mbedtls/tree/development) branch:
|
||||
this is where the next major version of Mbed TLS (version 4.0) is being
|
||||
prepared. It has API changes that make it incompatible with Mbed TLS 3.x,
|
||||
as well as all the new features and bug fixes and security fixes.
|
||||
- One or more long-time support (LTS) branches: these only get bug fixes and
|
||||
security fixes. Currently, the supported LTS branches are:
|
||||
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28).
|
||||
- [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6).
|
||||
|
||||
We retain a number of historical branches, whose names are prefixed by `archive/`,
|
||||
such as [`archive/mbedtls-2.7`](https://github.com/Mbed-TLS/mbedtls/tree/archive/mbedtls-2.7).
|
||||
These branches will not receive any changes or updates.
|
||||
|
||||
We use [Semantic Versioning](https://semver.org/). In particular, we maintain
|
||||
API compatibility in the `main` branch across minor version changes (e.g.
|
||||
the API of 3.(x+1) is backward compatible with 3.x). We only break API
|
||||
compatibility on major version changes (e.g. from 3.x to 4.0). We also maintain
|
||||
ABI compatibility within LTS branches; see the next section for details.
|
||||
|
||||
We will make regular LTS releases on an 18-month cycle, each of which will have
|
||||
a 3 year support lifetime. On this basis, 3.6 LTS (released March 2024) will be
|
||||
supported until March 2027. The next LTS release will be a 4.x release, which is
|
||||
planned for September 2025.
|
||||
|
||||
## Backwards Compatibility for application code
|
||||
|
||||
We maintain API compatibility in released versions of Mbed TLS. If you have
|
||||
code that's working and secure with Mbed TLS x.y.z and does not rely on
|
||||
undocumented features, then you should be able to re-compile it without
|
||||
modification with any later release x.y'.z' with the same major version
|
||||
number, and your code will still build, be secure, and work.
|
||||
|
||||
Note that this guarantee only applies if you either use the default
|
||||
compile-time configuration (`mbedtls/mbedtls_config.h`) or the same modified
|
||||
compile-time configuration. Changing compile-time configuration options can
|
||||
result in an incompatible API or ABI, although features will generally not
|
||||
affect unrelated features (for example, enabling or disabling a
|
||||
cryptographic algorithm does not break code that does not use that
|
||||
algorithm).
|
||||
|
||||
Note that new releases of Mbed TLS may extend the API. Here are some
|
||||
examples of changes that are common in minor releases of Mbed TLS, and are
|
||||
not considered API compatibility breaks:
|
||||
|
||||
* Adding or reordering fields in a structure or union.
|
||||
* Removing a field from a structure, unless the field is documented as public.
|
||||
* Adding items to an enum.
|
||||
* Returning an error code that was not previously documented for a function
|
||||
when a new error condition arises.
|
||||
* Changing which error code is returned in a case where multiple error
|
||||
conditions apply.
|
||||
* Changing the behavior of a function from failing to succeeding, when the
|
||||
change is a reasonable extension of the current behavior, i.e. the
|
||||
addition of a new feature.
|
||||
|
||||
There are rare exceptions where we break API compatibility: code that was
|
||||
relying on something that became insecure in the meantime (for example,
|
||||
crypto that was found to be weak) may need to be changed. In case security
|
||||
comes in conflict with backwards compatibility, we will put security first,
|
||||
but always attempt to provide a compatibility option.
|
||||
|
||||
## Backward compatibility for the key store
|
||||
|
||||
We maintain backward compatibility with previous versions of the
|
||||
PSA Crypto persistent storage since Mbed TLS 2.25.0, provided that the
|
||||
storage backend (PSA ITS implementation) is configured in a compatible way.
|
||||
We intend to maintain this backward compatibility throughout a major version
|
||||
of Mbed TLS (for example, all Mbed TLS 3.y versions will be able to read
|
||||
keys written under any Mbed TLS 3.x with x <= y).
|
||||
|
||||
Mbed TLS 3.x can also read keys written by Mbed TLS 2.25.0 through 2.28.x
|
||||
LTS, but future major version upgrades (for example from 2.28.x/3.x to 4.y)
|
||||
may require the use of an upgrade tool.
|
||||
|
||||
Note that this guarantee does not currently fully extend to drivers, which
|
||||
are an experimental feature. We intend to maintain compatibility with the
|
||||
basic use of drivers from Mbed TLS 2.28.0 onwards, even if driver APIs
|
||||
change. However, for more experimental parts of the driver interface, such
|
||||
as the use of driver state, we do not yet guarantee backward compatibility.
|
||||
|
||||
## Long-time support branches
|
||||
|
||||
For the LTS branches, additionally we try very hard to also maintain ABI
|
||||
compatibility (same definition as API except with re-linking instead of
|
||||
re-compiling) and to avoid any increase in code size or RAM usage, or in the
|
||||
minimum version of tools needed to build the code. The only exception, as
|
||||
before, is in case those goals would conflict with fixing a security issue, we
|
||||
will put security first but provide a compatibility option. (So far we never
|
||||
had to break ABI compatibility in an LTS branch, but we occasionally had to
|
||||
increase code size for a security fix.)
|
||||
|
||||
For contributors, see the [Backwards Compatibility section of
|
||||
CONTRIBUTING](CONTRIBUTING.md#backwards-compatibility).
|
||||
|
||||
## Current Branches
|
||||
|
||||
The following branches are currently maintained:
|
||||
|
||||
- [main](https://github.com/Mbed-TLS/mbedtls/tree/main)
|
||||
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
|
||||
- [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6)
|
||||
maintained until March 2027, see
|
||||
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v3.6.0>.
|
||||
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
|
||||
maintained until the end of 2024, see
|
||||
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.8>.
|
||||
|
||||
Users are urged to always use the latest version of a maintained branch.
|
||||
@@ -1,20 +0,0 @@
|
||||
## Known issues
|
||||
|
||||
Known issues in Mbed TLS are [tracked on GitHub](https://github.com/Mbed-TLS/mbedtls/issues).
|
||||
|
||||
## Reporting a bug
|
||||
|
||||
If you think you've found a bug in Mbed TLS, please follow these steps:
|
||||
|
||||
1. Make sure you're using the latest version of a
|
||||
[maintained branch](BRANCHES.md): `main`, `development`,
|
||||
or a long-time support branch.
|
||||
2. Check [GitHub](https://github.com/Mbed-TLS/mbedtls/issues) to see if
|
||||
your issue has already been reported. If not, …
|
||||
3. If the issue is a security risk (for example: buffer overflow,
|
||||
data leak), please report it confidentially as described in
|
||||
[`SECURITY.md`](SECURITY.md). If not, …
|
||||
4. Please [create an issue on on GitHub](https://github.com/Mbed-TLS/mbedtls/issues).
|
||||
|
||||
Please do not use GitHub for support questions. If you want to know
|
||||
how to do something with Mbed TLS, please see [`SUPPORT.md`](SUPPORT.md) for available documentation and support channels.
|
||||
-429
@@ -1,429 +0,0 @@
|
||||
#
|
||||
# CMake build system design considerations:
|
||||
#
|
||||
# - Include directories:
|
||||
# + Do not define include directories globally using the include_directories
|
||||
# command but rather at the target level using the
|
||||
# target_include_directories command. That way, it is easier to guarantee
|
||||
# that targets are built using the proper list of include directories.
|
||||
# + Use the PUBLIC and PRIVATE keywords to specify the scope of include
|
||||
# directories. That way, a target linking to a library (using the
|
||||
# target_link_libraries command) inherits from the library PUBLIC include
|
||||
# directories and not from the PRIVATE ones.
|
||||
# - MBEDTLS_TARGET_PREFIX: CMake targets are designed to be alterable by calling
|
||||
# CMake in order to avoid target name clashes, via the use of
|
||||
# MBEDTLS_TARGET_PREFIX. The value of this variable is prefixed to the
|
||||
# mbedtls, mbedx509, mbedcrypto and apidoc targets.
|
||||
#
|
||||
|
||||
# We specify a minimum requirement of 3.10.2, but for now use 3.5.1 here
|
||||
# until our infrastructure catches up.
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0011.html
|
||||
# Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
|
||||
# policy setting is deprecated, and will be removed in future versions.
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0012.html
|
||||
# Setting the CMP0012 policy to NEW is required for FindPython3 to work with CMake 3.18.2
|
||||
# (there is a bug in this particular version), otherwise, setting the CMP0012 policy is required
|
||||
# for CMake versions >= 3.18.3 otherwise a deprecated warning is generated. The OLD policy setting
|
||||
# is deprecated and will be removed in future versions.
|
||||
cmake_policy(SET CMP0012 NEW)
|
||||
|
||||
if(TEST_CPP)
|
||||
project("Mbed TLS"
|
||||
LANGUAGES C CXX
|
||||
VERSION 3.6.0
|
||||
)
|
||||
else()
|
||||
project("Mbed TLS"
|
||||
LANGUAGES C
|
||||
VERSION 3.6.0
|
||||
)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Determine if Mbed TLS is being built as a subproject using add_subdirectory()
|
||||
if(NOT DEFINED MBEDTLS_AS_SUBPROJECT)
|
||||
set(MBEDTLS_AS_SUBPROJECT ON)
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(MBEDTLS_AS_SUBPROJECT OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set the project root directory.
|
||||
set(MBEDTLS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
option(ENABLE_PROGRAMS "Build Mbed TLS programs." ON)
|
||||
|
||||
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
|
||||
option(MBEDTLS_FATAL_WARNINGS "Compiler warnings treated as errors" ON)
|
||||
if(CMAKE_HOST_WIN32)
|
||||
# N.B. The comment on the next line is significant! If you change it,
|
||||
# edit the sed command in prepare_release.sh that modifies
|
||||
# CMakeLists.txt.
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" OFF) # off in development
|
||||
else()
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" ON)
|
||||
endif()
|
||||
|
||||
option(DISABLE_PACKAGE_CONFIG_AND_INSTALL "Disable package configuration, target export and installation" ${MBEDTLS_AS_SUBPROJECT})
|
||||
|
||||
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
|
||||
string(REGEX MATCH "GNU" CMAKE_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}")
|
||||
string(REGEX MATCH "IAR" CMAKE_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}")
|
||||
string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${CMAKE_C_COMPILER_ID}")
|
||||
|
||||
# the test suites currently have compile errors with MSVC
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
option(ENABLE_TESTING "Build Mbed TLS tests." OFF)
|
||||
else()
|
||||
option(ENABLE_TESTING "Build Mbed TLS tests." ON)
|
||||
endif()
|
||||
|
||||
# Warning string - created as a list for compatibility with CMake 2.8
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L1 "**** WARNING! MBEDTLS_CTR_DRBG_USE_128_BIT_KEY defined!\n")
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L2 "**** Using 128-bit keys for CTR_DRBG limits the security of generated\n")
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L3 "**** keys and operations that use random values generated to 128-bit security\n")
|
||||
|
||||
set(CTR_DRBG_128_BIT_KEY_WARNING "${WARNING_BORDER}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L1}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L2}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L3}"
|
||||
"${WARNING_BORDER}")
|
||||
|
||||
# Python 3 is only needed here to check for configuration warnings.
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.15.0)
|
||||
set(Python3_FIND_STRATEGY LOCATION)
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
if(Python3_Interpreter_FOUND)
|
||||
set(MBEDTLS_PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
|
||||
endif()
|
||||
else()
|
||||
find_package(PythonInterp 3)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
set(MBEDTLS_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
endif()
|
||||
endif()
|
||||
if(MBEDTLS_PYTHON_EXECUTABLE)
|
||||
|
||||
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
|
||||
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_CTR_DRBG_USE_128_BIT_KEY
|
||||
RESULT_VARIABLE result)
|
||||
if(${result} EQUAL 0)
|
||||
message(WARNING ${CTR_DRBG_128_BIT_KEY_WARNING})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# We now potentially need to link all executables against PThreads, if available
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads)
|
||||
|
||||
# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan TSanDbg"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
# Make MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE into PATHs
|
||||
set(MBEDTLS_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS config file (overrides default).")
|
||||
set(MBEDTLS_USER_CONFIG_FILE "" CACHE FILEPATH "Mbed TLS user config file (appended to default).")
|
||||
|
||||
# Create a symbolic link from ${base_name} in the binary directory
|
||||
# to the corresponding path in the source directory.
|
||||
# Note: Copies the file(s) on Windows.
|
||||
function(link_to_source base_name)
|
||||
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)
|
||||
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})
|
||||
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()
|
||||
configure_file(${target} ${link} COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction(link_to_source)
|
||||
|
||||
# Get the filename without the final extension (i.e. convert "a.b.c" to "a.b")
|
||||
function(get_name_without_last_ext dest_var full_name)
|
||||
# Split into a list on '.' (but a cmake list is just a ';'-separated string)
|
||||
string(REPLACE "." ";" ext_parts "${full_name}")
|
||||
# Remove the last item if there are more than one
|
||||
list(LENGTH ext_parts ext_parts_len)
|
||||
if (${ext_parts_len} GREATER "1")
|
||||
math(EXPR ext_parts_last_item "${ext_parts_len} - 1")
|
||||
list(REMOVE_AT ext_parts ${ext_parts_last_item})
|
||||
endif()
|
||||
# Convert back to a string by replacing separators with '.'
|
||||
string(REPLACE ";" "." no_ext_name "${ext_parts}")
|
||||
# Copy into the desired variable
|
||||
set(${dest_var} ${no_ext_name} PARENT_SCOPE)
|
||||
endfunction(get_name_without_last_ext)
|
||||
|
||||
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNU)
|
||||
# some warnings we want are not available with old GCC versions
|
||||
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings")
|
||||
if (GCC_VERSION VERSION_GREATER 3.0 OR GCC_VERSION VERSION_EQUAL 3.0)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2 -Wno-format-nonliteral")
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla")
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 5.0)
|
||||
CHECK_C_COMPILER_FLAG("-Wformat-signedness" C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
|
||||
if(C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-signedness")
|
||||
endif()
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 7.0 OR GCC_VERSION VERSION_EQUAL 7.0)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-overflow=2 -Wformat-truncation")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
|
||||
set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
|
||||
set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3")
|
||||
set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_CHECK "-Os")
|
||||
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
|
||||
endif(CMAKE_COMPILER_IS_GNU)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
|
||||
set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
|
||||
set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_MEMSAN "-fsanitize=memory -O3")
|
||||
set(CMAKE_C_FLAGS_MEMSANDBG "-fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
|
||||
set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3")
|
||||
set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(CMAKE_C_FLAGS_CHECK "-Os")
|
||||
endif(CMAKE_COMPILER_IS_CLANG)
|
||||
|
||||
if(CMAKE_COMPILER_IS_IAR)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Ohz")
|
||||
set(CMAKE_C_FLAGS_DEBUG "--debug -On")
|
||||
endif(CMAKE_COMPILER_IS_IAR)
|
||||
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
# Strictest warnings, UTF-8 source and execution charset
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /utf-8")
|
||||
endif(CMAKE_COMPILER_IS_MSVC)
|
||||
|
||||
if(MBEDTLS_FATAL_WARNINGS)
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
|
||||
endif(CMAKE_COMPILER_IS_MSVC)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNU)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||
if(UNSAFE_BUILD)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=cpp")
|
||||
set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_ASAN} -Wno-error=cpp")
|
||||
set(CMAKE_C_FLAGS_ASANDBG "${CMAKE_C_FLAGS_ASANDBG} -Wno-error=cpp")
|
||||
endif(UNSAFE_BUILD)
|
||||
endif(CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNU)
|
||||
|
||||
if (CMAKE_COMPILER_IS_IAR)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warnings_are_errors")
|
||||
endif(CMAKE_COMPILER_IS_IAR)
|
||||
endif(MBEDTLS_FATAL_WARNINGS)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||
if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
|
||||
endif(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||
|
||||
if(LIB_INSTALL_DIR)
|
||||
set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt")
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.")
|
||||
endif()
|
||||
add_subdirectory(framework)
|
||||
|
||||
add_subdirectory(include)
|
||||
|
||||
add_subdirectory(3rdparty)
|
||||
|
||||
add_subdirectory(library)
|
||||
|
||||
add_subdirectory(pkgconfig)
|
||||
|
||||
#
|
||||
# The C files in tests/src directory contain test code shared among test suites
|
||||
# and programs. This shared test code is compiled and linked to test suites and
|
||||
# programs objects as a set of compiled objects. The compiled objects are NOT
|
||||
# built into a library that the test suite and program objects would link
|
||||
# against as they link against the mbedcrypto, mbedx509 and mbedtls libraries.
|
||||
# The reason is that such library is expected to have mutual dependencies with
|
||||
# the aforementioned libraries and that there is as of today no portable way of
|
||||
# handling such dependencies (only toolchain specific solutions).
|
||||
#
|
||||
# Thus the below definition of the `mbedtls_test` CMake library of objects
|
||||
# target. This library of objects is used by tests and programs CMake files
|
||||
# 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)
|
||||
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)
|
||||
# Request C11, needed for memory poisoning tests
|
||||
set_target_properties(mbedtls_test PROPERTIES C_STANDARD 11)
|
||||
|
||||
file(GLOB MBEDTLS_TEST_HELPER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/src/test_helpers/*.c)
|
||||
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)
|
||||
|
||||
# Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE
|
||||
if(MBEDTLS_CONFIG_FILE)
|
||||
target_compile_definitions(mbedtls_test
|
||||
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
|
||||
target_compile_definitions(mbedtls_test_helpers
|
||||
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
|
||||
endif()
|
||||
if(MBEDTLS_USER_CONFIG_FILE)
|
||||
target_compile_definitions(mbedtls_test
|
||||
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
|
||||
target_compile_definitions(mbedtls_test_helpers
|
||||
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_PROGRAMS)
|
||||
add_subdirectory(programs)
|
||||
endif()
|
||||
|
||||
ADD_CUSTOM_TARGET(${MBEDTLS_TARGET_PREFIX}apidoc
|
||||
COMMAND doxygen mbedtls.doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
|
||||
|
||||
if(ENABLE_TESTING)
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
||||
# additional convenience targets for Unix only
|
||||
if(UNIX)
|
||||
|
||||
# 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 scripts/lcov.sh
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(memcheck
|
||||
COMMAND sed -i.bak s+/usr/bin/valgrind+`which valgrind`+ DartConfiguration.tcl
|
||||
COMMAND ctest -O memcheck.log -D ExperimentalMemCheck
|
||||
COMMAND tail -n1 memcheck.log | grep 'Memory checking results:' > /dev/null
|
||||
COMMAND rm -f memcheck.log
|
||||
COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
|
||||
)
|
||||
endif(UNIX)
|
||||
|
||||
# Make scripts needed for testing available in an out-of-source build.
|
||||
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_to_source(scripts)
|
||||
# Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
|
||||
# keep things simple with the sed commands in the memcheck target.
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
configure_package_config_file(
|
||||
"cmake/MbedTLSConfig.cmake.in"
|
||||
"cmake/MbedTLSConfig.cmake"
|
||||
INSTALL_DESTINATION "cmake")
|
||||
|
||||
write_basic_package_version_file(
|
||||
"cmake/MbedTLSConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
VERSION 3.6.0)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfigVersion.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS")
|
||||
|
||||
export(
|
||||
EXPORT MbedTLSTargets
|
||||
NAMESPACE MbedTLS::
|
||||
FILE "cmake/MbedTLSTargets.cmake")
|
||||
|
||||
install(
|
||||
EXPORT MbedTLSTargets
|
||||
NAMESPACE MbedTLS::
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MbedTLS"
|
||||
FILE "MbedTLSTargets.cmake")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15)
|
||||
# Do not export the package by default
|
||||
cmake_policy(SET CMP0090 NEW)
|
||||
|
||||
# Make this package visible to the system
|
||||
export(PACKAGE MbedTLS)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,97 +0,0 @@
|
||||
Contributing
|
||||
============
|
||||
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.
|
||||
|
||||
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
|
||||
----------------
|
||||
- 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.
|
||||
|
||||
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. See our [review process guidelines](https://mbed-tls.readthedocs.io/en/latest/reviews/review-for-contributors/).
|
||||
1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
|
||||
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. If there is an API change, the contribution, if accepted, will be merged only when there is a major release.
|
||||
|
||||
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.
|
||||
|
||||
Long Term Support Branches
|
||||
--------------------------
|
||||
Mbed TLS maintains several LTS (Long Term Support) branches, which are maintained continuously for a given period. The LTS branches are provided to allow users of the library to have a maintained, stable version of the library which contains only security fixes and fixes for other defects, without encountering additional features or API extensions which may introduce issues or change the code size or RAM usage, which can be significant considerations on some platforms. To allow users to take advantage of the LTS branches, these branches maintain backwards compatibility for both the public API and ABI.
|
||||
|
||||
When backporting to these branches please observe the following rules:
|
||||
|
||||
1. Any change to the library which changes the API or ABI cannot be backported.
|
||||
1. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted.
|
||||
1. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be additional test cases or quality improvements such as changes to build or test scripts.
|
||||
|
||||
It would be highly appreciated if contributions are backported to LTS branches in addition to the [development branch](https://github.com/Mbed-TLS/mbedtls/tree/development) by contributors.
|
||||
|
||||
The list of maintained branches can be found in the [Current Branches section
|
||||
of BRANCHES.md](BRANCHES.md#current-branches).
|
||||
|
||||
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_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://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.
|
||||
|
||||
Sample applications, if needed, should be modified as well.
|
||||
|
||||
Continuous Integration Tests
|
||||
----------------------------
|
||||
Once a PR has been made, the Continuous Integration (CI) tests are triggered and run. You should follow the result of the CI tests, and fix failures.
|
||||
|
||||
It is advised to enable the [githooks scripts](https://github.com/Mbed-TLS/mbedtls/tree/development/tests/git-scripts) prior to pushing your changes, for catching some of the issues as early as possible.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
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://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
|
||||
---------------------
|
||||
|
||||
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license. See the [LICENSE](LICENSE) file for the full text of these licenses. This means that users may choose which of these licenses they take the code under.
|
||||
|
||||
Contributors must accept that their contributions are made under both the Apache-2.0 AND [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) licenses.
|
||||
|
||||
All new files should include the standard SPDX license identifier where possible, i.e. "SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later".
|
||||
|
||||
The copyright on contributions is retained by the original authors of the code. Where possible for new files, this should be noted in a comment at the top of the file in the form: "Copyright The Mbed TLS Contributors".
|
||||
|
||||
When contributing code to us, the committer and all authors are required to make the submission under the terms of the [Developer Certificate of Origin](dco.txt), confirming that the code submitted can (legally) become part of the project, and is submitted under both the Apache-2.0 AND GPL-2.0-or-later licenses.
|
||||
|
||||
This is done by including the standard Git `Signed-off-by:` line in every commit message. If more than one person contributed to the commit, they should also add their own `Signed-off-by:` line.
|
||||
@@ -1,91 +0,0 @@
|
||||
# Pending changelog entry directory
|
||||
|
||||
This directory contains changelog entries that have not yet been merged
|
||||
to the changelog file ([`../ChangeLog`](../ChangeLog)).
|
||||
|
||||
## What requires a changelog entry?
|
||||
|
||||
Write a changelog entry if there is a user-visible change. This includes:
|
||||
|
||||
* Bug fixes in the library or in sample programs: fixing a security hole,
|
||||
fixing broken behavior, fixing the build in some configuration or on some
|
||||
platform, etc.
|
||||
* New features in the library, new sample programs, or new platform support.
|
||||
* Changes in existing behavior. These should be rare. Changes in features
|
||||
that are documented as experimental may or may not be announced, depending
|
||||
on the extent of the change and how widely we expect the feature to be used.
|
||||
|
||||
We generally don't include changelog entries for:
|
||||
|
||||
* Documentation improvements.
|
||||
* Performance improvements, unless they are particularly significant.
|
||||
* Changes to parts of the code base that users don't interact with directly,
|
||||
such as test code and test data.
|
||||
* Fixes for compiler warnings. Releases typically contain a number of fixes
|
||||
of this kind, so we will only mention them in the Changelog if they are
|
||||
particularly significant.
|
||||
|
||||
Until Mbed TLS 2.24.0, we required changelog entries in more cases.
|
||||
Looking at older changelog entries is good practice for how to write a
|
||||
changelog entry, but not for deciding whether to write one.
|
||||
|
||||
## Changelog entry file format
|
||||
|
||||
A changelog entry file must have the extension `*.txt` and must have the
|
||||
following format:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Security
|
||||
* Change description.
|
||||
* Another change description.
|
||||
|
||||
Features
|
||||
* Yet another change description. This is a long change description that
|
||||
spans multiple lines.
|
||||
* Yet again another change description.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The permitted changelog entry categories are as follows:
|
||||
<!-- Keep this synchronized with STANDARD_CATEGORIES in assemble_changelog.py! -->
|
||||
|
||||
API changes
|
||||
Default behavior changes
|
||||
Requirement changes
|
||||
New deprecations
|
||||
Removals
|
||||
Features
|
||||
Security
|
||||
Bugfix
|
||||
Changes
|
||||
|
||||
Use “Changes” for anything that doesn't fit in the other categories.
|
||||
|
||||
## How to write a changelog entry
|
||||
|
||||
Each entry starts with three spaces, an asterisk and a space. Continuation
|
||||
lines start with 5 spaces. Lines wrap at 79 characters.
|
||||
|
||||
Write full English sentences with proper capitalization and punctuation. Use
|
||||
the present tense. Use the imperative where applicable. For example: “Fix a
|
||||
bug in mbedtls_xxx() ….”
|
||||
|
||||
Include GitHub issue numbers where relevant. Use the format “#1234” for an
|
||||
Mbed TLS issue. Add other external references such as CVE numbers where
|
||||
applicable.
|
||||
|
||||
Credit bug reporters where applicable.
|
||||
|
||||
**Explain why, not how**. Remember that the audience is the users of the
|
||||
library, not its developers. In particular, for a bug fix, explain the
|
||||
consequences of the bug, not how the bug was fixed. For a new feature, explain
|
||||
why one might be interested in the feature. For an API change or a deprecation,
|
||||
explain how to update existing applications.
|
||||
|
||||
See [existing entries](../ChangeLog) for examples.
|
||||
|
||||
## How `ChangeLog` is updated
|
||||
|
||||
Run [`../scripts/assemble_changelog.py`](../scripts/assemble_changelog.py)
|
||||
from a Git working copy
|
||||
to move the entries from files in `ChangeLog.d` to the main `ChangeLog` file.
|
||||
@@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* MBEDTLS_ASN1_PARSE_C and MBEDTLS_ASN1_WRITE_C are now automatically enabled
|
||||
as soon as MBEDTLS_RSA_C is enabled. Fixes #9041.
|
||||
@@ -1,2 +0,0 @@
|
||||
Bugfix
|
||||
* Fix compilation error when memcpy() is a function-like macros. Fixes #8994.
|
||||
@@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix rare concurrent access bug where attempting to operate on a
|
||||
non-existent key while concurrently creating a new key could potentially
|
||||
corrupt the key store.
|
||||
@@ -1,5 +0,0 @@
|
||||
Bugfix
|
||||
* Fix error handling when creating a key in a dynamic secure element
|
||||
(feature enabled by MBEDTLS_PSA_CRYPTO_SE_C). In a low memory condition,
|
||||
the creation could return PSA_SUCCESS but using or destroying the key
|
||||
would not work. Fixes #8537.
|
||||
@@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix undefined behaviour (incrementing a NULL pointer by zero length) when
|
||||
passing in zero length additional data to multipart AEAD.
|
||||
@@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix TLS 1.3 client build and runtime when support for session tickets is
|
||||
disabled (MBEDTLS_SSL_SESSION_TICKETS configuration option). Fixes #6395.
|
||||
@@ -1,4 +0,0 @@
|
||||
Site: localhost
|
||||
BuildName: Mbed TLS-test
|
||||
CoverageCommand: /usr/bin/gcov
|
||||
MemoryCheckCommand: /usr/bin/valgrind
|
||||
@@ -1,553 +0,0 @@
|
||||
Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)
|
||||
OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license.
|
||||
This means that users may choose which of these licenses they take the code
|
||||
under.
|
||||
|
||||
The full text of each of these licenses is given below.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
===============================================================================
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -1,217 +0,0 @@
|
||||
DESTDIR=/usr/local
|
||||
PREFIX=mbedtls_
|
||||
PERL ?= perl
|
||||
|
||||
ifneq (,$(filter-out lib library/%,$(or $(MAKECMDGOALS),all)))
|
||||
ifeq (,$(wildcard framework/exported.make))
|
||||
# Use the define keyword to get a multi-line message.
|
||||
# GNU make appends ". Stop.", so tweak the ending of our message accordingly.
|
||||
define error_message
|
||||
$(MBEDTLS_PATH)/framework/exported.make not found.
|
||||
Run `git submodule update --init` to fetch the submodule contents.
|
||||
This is a fatal error
|
||||
endef
|
||||
$(error $(error_message))
|
||||
endif
|
||||
include framework/exported.make
|
||||
endif
|
||||
|
||||
.SILENT:
|
||||
|
||||
.PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean
|
||||
|
||||
all: programs tests
|
||||
$(MAKE) post_build
|
||||
|
||||
no_test: programs
|
||||
|
||||
programs: lib mbedtls_test
|
||||
$(MAKE) -C programs
|
||||
|
||||
lib:
|
||||
$(MAKE) -C library
|
||||
|
||||
tests: lib mbedtls_test
|
||||
$(MAKE) -C tests
|
||||
|
||||
mbedtls_test:
|
||||
$(MAKE) -C tests mbedtls_test
|
||||
|
||||
library/%:
|
||||
$(MAKE) -C library $*
|
||||
programs/%:
|
||||
$(MAKE) -C programs $*
|
||||
tests/%:
|
||||
$(MAKE) -C tests $*
|
||||
|
||||
.PHONY: generated_files
|
||||
generated_files: library/generated_files
|
||||
generated_files: programs/generated_files
|
||||
generated_files: tests/generated_files
|
||||
generated_files: visualc_files
|
||||
|
||||
# Set GEN_FILES to the empty string to disable dependencies on generated
|
||||
# source files. Then `make generated_files` will only build files that
|
||||
# are missing, it will not rebuilt files that are present but out of date.
|
||||
# This is useful, for example, if you have a source tree where
|
||||
# `make generated_files` has already run and file timestamps reflect the
|
||||
# time the files were copied or extracted, and you are now in an environment
|
||||
# that lacks some of the necessary tools to re-generate the files.
|
||||
# If $(GEN_FILES) is non-empty, the generated source files' dependencies
|
||||
# are treated ordinarily, based on file timestamps.
|
||||
GEN_FILES ?= yes
|
||||
|
||||
# In dependencies where the target is a configuration-independent generated
|
||||
# file, use `TARGET: $(gen_file_dep) DEPENDENCY1 DEPENDENCY2 ...`
|
||||
# rather than directly `TARGET: DEPENDENCY1 DEPENDENCY2 ...`. This
|
||||
# enables the re-generation to be turned off when GEN_FILES is disabled.
|
||||
ifdef GEN_FILES
|
||||
gen_file_dep =
|
||||
else
|
||||
# Order-only dependency: generate the target if it's absent, but don't
|
||||
# re-generate it if it's present but older than its dependencies.
|
||||
gen_file_dep = |
|
||||
endif
|
||||
|
||||
.PHONY: visualc_files
|
||||
VISUALC_FILES = visualc/VS2017/mbedTLS.sln visualc/VS2017/mbedTLS.vcxproj
|
||||
# TODO: $(app).vcxproj for each $(app) in programs/
|
||||
visualc_files: $(VISUALC_FILES)
|
||||
|
||||
# Ensure that the .c files that generate_visualc_files.pl enumerates are
|
||||
# present before it runs. It doesn't matter if the files aren't up-to-date,
|
||||
# they just need to be present.
|
||||
$(VISUALC_FILES): | library/generated_files
|
||||
$(VISUALC_FILES): $(gen_file_dep) scripts/generate_visualc_files.pl
|
||||
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-app-template.vcxproj
|
||||
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-main-template.vcxproj
|
||||
$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-sln-template.sln
|
||||
# TODO: also the list of .c and .h source files, but not their content
|
||||
$(VISUALC_FILES):
|
||||
echo " Gen $@ ..."
|
||||
$(PERL) scripts/generate_visualc_files.pl
|
||||
|
||||
ifndef WINDOWS
|
||||
install: no_test
|
||||
mkdir -p $(DESTDIR)/include/mbedtls
|
||||
cp -rp include/mbedtls $(DESTDIR)/include
|
||||
mkdir -p $(DESTDIR)/include/psa
|
||||
cp -rp include/psa $(DESTDIR)/include
|
||||
|
||||
mkdir -p $(DESTDIR)/lib
|
||||
cp -RP library/libmbedtls.* $(DESTDIR)/lib
|
||||
cp -RP library/libmbedx509.* $(DESTDIR)/lib
|
||||
cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
|
||||
|
||||
mkdir -p $(DESTDIR)/bin
|
||||
for p in programs/*/* ; do \
|
||||
if [ -x $$p ] && [ ! -d $$p ] ; \
|
||||
then \
|
||||
f=$(PREFIX)`basename $$p` ; \
|
||||
cp $$p $(DESTDIR)/bin/$$f ; \
|
||||
fi \
|
||||
done
|
||||
|
||||
uninstall:
|
||||
rm -rf $(DESTDIR)/include/mbedtls
|
||||
rm -rf $(DESTDIR)/include/psa
|
||||
rm -f $(DESTDIR)/lib/libmbedtls.*
|
||||
rm -f $(DESTDIR)/lib/libmbedx509.*
|
||||
rm -f $(DESTDIR)/lib/libmbedcrypto.*
|
||||
|
||||
for p in programs/*/* ; do \
|
||||
if [ -x $$p ] && [ ! -d $$p ] ; \
|
||||
then \
|
||||
f=$(PREFIX)`basename $$p` ; \
|
||||
rm -f $(DESTDIR)/bin/$$f ; \
|
||||
fi \
|
||||
done
|
||||
endif
|
||||
|
||||
|
||||
WARNING_BORDER_LONG =**********************************************************************************\n
|
||||
CTR_DRBG_128_BIT_KEY_WARN_L1=**** WARNING! MBEDTLS_CTR_DRBG_USE_128_BIT_KEY defined! ****\n
|
||||
CTR_DRBG_128_BIT_KEY_WARN_L2=**** Using 128-bit keys for CTR_DRBG limits the security of generated ****\n
|
||||
CTR_DRBG_128_BIT_KEY_WARN_L3=**** keys and operations that use random values generated to 128-bit security ****\n
|
||||
|
||||
CTR_DRBG_128_BIT_KEY_WARNING=\n$(WARNING_BORDER_LONG)$(CTR_DRBG_128_BIT_KEY_WARN_L1)$(CTR_DRBG_128_BIT_KEY_WARN_L2)$(CTR_DRBG_128_BIT_KEY_WARN_L3)$(WARNING_BORDER_LONG)
|
||||
|
||||
# Post build steps
|
||||
post_build:
|
||||
ifndef WINDOWS
|
||||
|
||||
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
|
||||
-scripts/config.py get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY && ([ $$? -eq 0 ]) && \
|
||||
echo '$(CTR_DRBG_128_BIT_KEY_WARNING)'
|
||||
|
||||
endif
|
||||
|
||||
clean: clean_more_on_top
|
||||
$(MAKE) -C library clean
|
||||
$(MAKE) -C programs clean
|
||||
$(MAKE) -C tests clean
|
||||
|
||||
clean_more_on_top:
|
||||
ifndef WINDOWS
|
||||
find . \( -name \*.gcno -o -name \*.gcda -o -name \*.info \) -exec rm {} +
|
||||
endif
|
||||
|
||||
neat: clean_more_on_top
|
||||
$(MAKE) -C library neat
|
||||
$(MAKE) -C programs neat
|
||||
$(MAKE) -C tests neat
|
||||
ifndef WINDOWS
|
||||
rm -f visualc/VS2017/*.vcxproj visualc/VS2017/mbedTLS.sln
|
||||
else
|
||||
if exist visualc\VS2017\*.vcxproj del /Q /F visualc\VS2017\*.vcxproj
|
||||
if exist visualc\VS2017\mbedTLS.sln del /Q /F visualc\VS2017\mbedTLS.sln
|
||||
endif
|
||||
|
||||
check: lib tests
|
||||
$(MAKE) -C tests check
|
||||
|
||||
test: check
|
||||
|
||||
ifndef WINDOWS
|
||||
# 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:
|
||||
scripts/lcov.sh
|
||||
|
||||
apidoc:
|
||||
mkdir -p apidoc
|
||||
cd doxygen && doxygen mbedtls.doxyfile
|
||||
|
||||
apidoc_clean:
|
||||
rm -rf apidoc
|
||||
endif
|
||||
|
||||
## Editor navigation files
|
||||
C_SOURCE_FILES = $(wildcard \
|
||||
3rdparty/*/include/*/*.h 3rdparty/*/include/*/*/*.h 3rdparty/*/include/*/*/*/*.h \
|
||||
3rdparty/*/*.c 3rdparty/*/*/*.c 3rdparty/*/*/*/*.c 3rdparty/*/*/*/*/*.c \
|
||||
include/*/*.h \
|
||||
library/*.[hc] \
|
||||
programs/*/*.[hc] \
|
||||
tests/include/*/*.h tests/include/*/*/*.h \
|
||||
tests/src/*.c tests/src/*/*.c \
|
||||
tests/suites/*.function \
|
||||
)
|
||||
# Exuberant-ctags invocation. Other ctags implementations may require different options.
|
||||
CTAGS = ctags --langmap=c:+.h.function --line-directives=no -o
|
||||
tags: $(C_SOURCE_FILES)
|
||||
$(CTAGS) $@ $(C_SOURCE_FILES)
|
||||
TAGS: $(C_SOURCE_FILES)
|
||||
etags --no-line-directive -o $@ $(C_SOURCE_FILES)
|
||||
global: GPATH GRTAGS GSYMS GTAGS
|
||||
GPATH GRTAGS GSYMS GTAGS: $(C_SOURCE_FILES)
|
||||
ls $(C_SOURCE_FILES) | gtags -f - --gtagsconf .globalrc
|
||||
cscope: cscope.in.out cscope.po.out cscope.out
|
||||
cscope.in.out cscope.po.out cscope.out: $(C_SOURCE_FILES)
|
||||
cscope -bq -u -Iinclude -Ilibrary $(patsubst %,-I%,$(wildcard 3rdparty/*/include)) -Itests/include $(C_SOURCE_FILES)
|
||||
.PHONY: cscope global
|
||||
@@ -1,333 +0,0 @@
|
||||
README for Mbed TLS
|
||||
===================
|
||||
|
||||
Mbed TLS is a C library that implements cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols. Its small code footprint makes it suitable for embedded systems.
|
||||
|
||||
Mbed TLS includes a reference implementation of the [PSA Cryptography API](#psa-cryptography-api). This is currently a preview for evaluation purposes only.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/mbedtls_config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Python 3 script `scripts/config.py` (use `--help` for usage instructions).
|
||||
|
||||
Compiler options can be set using conventional environment variables such as `CC` and `CFLAGS` when using the Make and CMake build system (see below).
|
||||
|
||||
We provide some non-standard configurations focused on specific use cases in the `configs/` directory. You can read more about those in `configs/README.txt`
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
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:
|
||||
|
||||
1. Make sure that [Doxygen](http://www.doxygen.nl/) is installed.
|
||||
1. Run `make apidoc`.
|
||||
1. Browse `apidoc/index.html` or `apidoc/modules.html`.
|
||||
|
||||
For other sources of documentation, see the [SUPPORT](SUPPORT.md) document.
|
||||
|
||||
Compiling
|
||||
---------
|
||||
|
||||
There are currently three active build systems used within Mbed TLS releases:
|
||||
|
||||
- GNU Make
|
||||
- CMake
|
||||
- Microsoft Visual Studio
|
||||
|
||||
The main systems used for development are CMake and GNU Make. Those systems are always complete and up-to-date. The others should reflect all changes present in the CMake and Make build system, although features may not be ported there automatically.
|
||||
|
||||
The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`.
|
||||
|
||||
### Tool versions
|
||||
|
||||
You need the following tools to build the library with the provided makefiles:
|
||||
|
||||
* GNU Make 3.82 or a build tool that CMake supports.
|
||||
* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, Arm Compiler 6, IAR 8 and Visual Studio 2017. More recent versions should work. Slightly older versions may work.
|
||||
* Python 3.8 to generate the test code. Python is also needed to integrate PSA drivers and to build the development branch (see next section).
|
||||
* Perl to run the tests, and to generate some source files in the development branch.
|
||||
* CMake 3.10.2 or later (if using CMake).
|
||||
* Microsoft Visual Studio 2017 or later (if using Visual Studio).
|
||||
* Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work).
|
||||
|
||||
### Git usage
|
||||
|
||||
The `development` branch and the `mbedtls-3.6` long-term support branch of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar).
|
||||
|
||||
### Generated source files in the development branch
|
||||
|
||||
The source code of Mbed TLS includes some files that are automatically generated by scripts and whose content depends only on the Mbed TLS source, not on the platform or on the library configuration. These files are not included in the development branch of Mbed TLS, but the generated files are included in official releases. This section explains how to generate the missing files in the development branch.
|
||||
|
||||
The following tools are required:
|
||||
|
||||
* Perl, for some library source files and for Visual Studio build files.
|
||||
* Python 3.8 and some Python packages, for some library source files, sample programs and test data. To install the necessary packages, run:
|
||||
```
|
||||
python3 -m pip install --user -r scripts/basic.requirements.txt
|
||||
```
|
||||
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.
|
||||
|
||||
Any of the following methods are available to generate the configuration-independent files:
|
||||
|
||||
* If not cross-compiling, running `make` with any target, or just `make`, will automatically generate required files.
|
||||
* On non-Windows systems, when not cross-compiling, CMake will generate the required files automatically.
|
||||
* Run `make generated_files` to generate all the configuration-independent files.
|
||||
* On Unix/POSIX systems, run `tests/scripts/check-generated-files.sh -u` to generate all the configuration-independent files.
|
||||
* On Windows, run `scripts\make_generated_files.bat` to generate all the configuration-independent files.
|
||||
|
||||
### Make
|
||||
|
||||
We require GNU Make. To build the library and the sample programs, GNU Make and a C compiler are sufficient. Some of the more advanced build targets require some Unix/Linux tools.
|
||||
|
||||
We intentionally only use a minimum of functionality in the makefiles in order to keep them as simple and independent of different toolchains as possible, to allow users to more easily move between different platforms. Users who need more features are recommended to use CMake.
|
||||
|
||||
In order to build from the source code using GNU Make, just enter at the command line:
|
||||
|
||||
make
|
||||
|
||||
In order to run the tests, enter:
|
||||
|
||||
make check
|
||||
|
||||
The tests need Python to be built and Perl to be run. If you don't have one of them installed, you can skip building the tests with:
|
||||
|
||||
make no_test
|
||||
|
||||
You'll still be able to run a much smaller set of tests with:
|
||||
|
||||
programs/test/selftest
|
||||
|
||||
In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if the target is Windows but the build environment is Unix-like (for instance when cross-compiling, or compiling from an MSYS shell), and `WINDOWS=1` if the build environment is a Windows shell (for instance using mingw32-make) (in that case some targets will not be available).
|
||||
|
||||
Setting the variable `SHARED` in your environment will build shared libraries in addition to the static libraries. Setting `DEBUG` gives you a debug build. You can override `CFLAGS` and `LDFLAGS` by setting them in your environment or on the make command line; compiler warning options may be overridden separately using `WARNING_CFLAGS`. Some directory-specific options (for example, `-I` directives) are still preserved.
|
||||
|
||||
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://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://mbed-tls.readthedocs.io/en/latest/kb/).
|
||||
|
||||
### CMake
|
||||
|
||||
In order to build the source using CMake in a separate directory (recommended), just enter at the command line:
|
||||
|
||||
mkdir /path/to/build_dir && cd /path/to/build_dir
|
||||
cmake /path/to/mbedtls_source
|
||||
cmake --build .
|
||||
|
||||
In order to run the tests, enter:
|
||||
|
||||
ctest
|
||||
|
||||
The test suites need Python to be built and Perl to be executed. If you don't have one of these installed, you'll want to disable the test suites with:
|
||||
|
||||
cmake -DENABLE_TESTING=Off /path/to/mbedtls_source
|
||||
|
||||
If you disabled the test suites, but kept the programs enabled, you can still run a much smaller set of tests with:
|
||||
|
||||
programs/test/selftest
|
||||
|
||||
To configure CMake for building shared libraries, use:
|
||||
|
||||
cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On /path/to/mbedtls_source
|
||||
|
||||
There are many different build modes available within the CMake buildsystem. Most of them are available for gcc and clang, though some are compiler-specific:
|
||||
|
||||
- `Release`. This generates the default code without any unnecessary information in the binary files.
|
||||
- `Debug`. This generates debug information and disables optimization of the code.
|
||||
- `Coverage`. This generates code coverage information in addition to debug information.
|
||||
- `ASan`. This instruments the code with AddressSanitizer to check for memory errors. (This includes LeakSanitizer, with recent version of gcc and clang.) (With recent version of clang, this mode also instruments the code with UndefinedSanitizer to check for undefined behaviour.)
|
||||
- `ASanDbg`. Same as ASan but slower, with debug information and better stack traces.
|
||||
- `MemSan`. This instruments the code with MemorySanitizer to check for uninitialised memory reads. Experimental, needs recent clang on Linux/x86\_64.
|
||||
- `MemSanDbg`. Same as MemSan but slower, with debug information, better stack traces and origin tracking.
|
||||
- `Check`. This activates the compiler warnings that depend on optimization and treats all warnings as errors.
|
||||
|
||||
Switching build modes in CMake is simple. For debug mode, enter at the command line:
|
||||
|
||||
cmake -D CMAKE_BUILD_TYPE=Debug /path/to/mbedtls_source
|
||||
|
||||
To list other available CMake options, use:
|
||||
|
||||
cmake -LH
|
||||
|
||||
Note that, with CMake, you can't adjust the compiler or its flags after the
|
||||
initial invocation of cmake. This means that `CC=your_cc make` and `make
|
||||
CC=your_cc` will *not* work (similarly with `CFLAGS` and other variables).
|
||||
These variables need to be adjusted when invoking cmake for the first time,
|
||||
for example:
|
||||
|
||||
CC=your_cc cmake /path/to/mbedtls_source
|
||||
|
||||
If you already invoked cmake and want to change those settings, you need to
|
||||
remove the build directory and create it again.
|
||||
|
||||
Note that it is possible to build in-place; this will however overwrite the
|
||||
provided Makefiles (see `scripts/tmp_ignore_makefiles.sh` if you want to
|
||||
prevent `git status` from showing them as modified). In order to do so, from
|
||||
the Mbed TLS source directory, use:
|
||||
|
||||
cmake .
|
||||
make
|
||||
|
||||
If you want to change `CC` or `CFLAGS` afterwards, you will need to remove the
|
||||
CMake cache. This can be done with the following command using GNU find:
|
||||
|
||||
find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
|
||||
|
||||
You can now make the desired change:
|
||||
|
||||
CC=your_cc cmake .
|
||||
make
|
||||
|
||||
Regarding variables, also note that if you set CFLAGS when invoking cmake,
|
||||
your value of CFLAGS doesn't override the content provided by cmake (depending
|
||||
on the build mode as seen above), it's merely prepended to it.
|
||||
|
||||
#### Consuming Mbed TLS
|
||||
|
||||
Mbed TLS provides a package config file for consumption as a dependency in other
|
||||
CMake projects. You can include Mbed TLS's CMake targets yourself with:
|
||||
|
||||
find_package(MbedTLS)
|
||||
|
||||
If prompted, set `MbedTLS_DIR` to `${YOUR_MBEDTLS_INSTALL_DIR}/cmake`. This
|
||||
creates the following targets:
|
||||
|
||||
- `MbedTLS::mbedcrypto` (Crypto library)
|
||||
- `MbedTLS::mbedtls` (TLS library)
|
||||
- `MbedTLS::mbedx509` (X509 library)
|
||||
|
||||
You can then use these directly through `target_link_libraries()`:
|
||||
|
||||
add_executable(xyz)
|
||||
|
||||
target_link_libraries(xyz
|
||||
PUBLIC MbedTLS::mbedtls
|
||||
MbedTLS::mbedcrypto
|
||||
MbedTLS::mbedx509)
|
||||
|
||||
This will link the Mbed TLS libraries to your library or application, and add
|
||||
its include directories to your target (transitively, in the case of `PUBLIC` or
|
||||
`INTERFACE` link libraries).
|
||||
|
||||
#### Mbed TLS as a subproject
|
||||
|
||||
Mbed TLS supports being built as a CMake subproject. One can
|
||||
use `add_subdirectory()` from a parent CMake project to include Mbed TLS as a
|
||||
subproject.
|
||||
|
||||
### Microsoft Visual Studio
|
||||
|
||||
The build files for Microsoft Visual Studio are generated for Visual Studio 2017.
|
||||
|
||||
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need Python and perl environments as well. However, the selftest program in `programs/test/` is still available.
|
||||
|
||||
In the development branch of Mbed TLS, the Visual Studio solution files need to be generated first as described in [“Generated source files in the development branch”](#generated-source-files-in-the-development-branch).
|
||||
|
||||
Example programs
|
||||
----------------
|
||||
|
||||
We've included example programs for a lot of different features and uses in [`programs/`](programs/README.md).
|
||||
Please note that the goal of these sample programs is to demonstrate specific features of the library, and the code may need to be adapted to build a real-world application.
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
Mbed TLS includes an elaborate test suite in `tests/` that initially requires Python to generate the tests 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.
|
||||
|
||||
For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, additional test scripts are available:
|
||||
|
||||
- `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/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/main/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://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:
|
||||
|
||||
- Bytes must be 8 bits.
|
||||
- All-bits-zero must be a valid representation of a null pointer.
|
||||
- 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
|
||||
|
||||
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://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:
|
||||
|
||||
* The API distinguishes caller memory from internal memory, which allows the library to be implemented in an isolated space for additional security. Library calls can be implemented as direct function calls if isolation is not desired, and as remote procedure calls if isolation is desired.
|
||||
* The structure of internal data is hidden to the application, which allows substituting alternative implementations at build time or run time, for example, in order to take advantage of hardware accelerators.
|
||||
* All access to the keys happens through key identifiers, which allows support for external cryptoprocessors that is transparent to applications.
|
||||
* The interface to algorithms is generic, favoring algorithm agility.
|
||||
* The interface is designed to be easy to use and hard to accidentally misuse.
|
||||
|
||||
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 implementation in Mbed TLS
|
||||
|
||||
Mbed TLS includes a reference implementation of the PSA Cryptography API.
|
||||
However, it does not aim to implement the whole specification; in particular it does not implement all the algorithms.
|
||||
|
||||
The X.509 and TLS code can use PSA cryptography for most operations. To enable this support, activate the compilation option `MBEDTLS_USE_PSA_CRYPTO` in `mbedtls_config.h`. Note that TLS 1.3 uses PSA cryptography for most operations regardless of this option. See `docs/use-psa-crypto.md` for details.
|
||||
|
||||
### PSA drivers
|
||||
|
||||
Mbed TLS supports drivers for cryptographic accelerators, secure elements and random generators. This is work in progress. Please note that the driver interfaces are not fully stable yet and may change without notice. We intend to preserve backward compatibility for application code (using the PSA Crypto API), but the code of the drivers may have to change in future minor releases of Mbed TLS.
|
||||
|
||||
Please see the [PSA driver example and guide](docs/psa-driver-example-and-guide.md) for information on writing a driver.
|
||||
|
||||
When using drivers, you will generally want to enable two compilation options (see the reference manual for more information):
|
||||
|
||||
* `MBEDTLS_USE_PSA_CRYPTO` is necessary so that the X.509 and TLS code calls the PSA drivers rather than the built-in software implementation.
|
||||
* `MBEDTLS_PSA_CRYPTO_CONFIG` allows you to enable PSA cryptographic mechanisms without including the code of the corresponding software implementation. This is not yet supported for all mechanisms.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Unless specifically indicated otherwise in a file, Mbed TLS files are provided under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license. See the [LICENSE](LICENSE) file for the full text of these licenses, and [the 'License and Copyright' section in the contributing guidelines](CONTRIBUTING.md#License-and-Copyright) for more information.
|
||||
|
||||
### Third-party code included in Mbed TLS
|
||||
|
||||
This project contains code from other projects. This code is located within the `3rdparty/` directory. The original license text is included within project subdirectories, where it differs from the normal Mbed TLS license, and/or in source files. The projects are listed below:
|
||||
|
||||
* `3rdparty/everest/`: Files stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
|
||||
* `3rdparty/p256-m/p256-m/`: Files have been taken from the [p256-m](https://github.com/mpg/p256-m) repository. The code in the original repository is distributed under the Apache 2.0 license. It is distributed in Mbed TLS under a dual Apache-2.0 OR GPL-2.0-or-later license with permission from the author.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
We gratefully accept bug reports and contributions from the community. Please see the [contributing guidelines](CONTRIBUTING.md) for details on how to do this.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
* To report a security vulnerability in Mbed TLS, please email <mbed-tls-security@lists.trustedfirmware.org>. For more information, see [`SECURITY.md`](SECURITY.md).
|
||||
* To report a bug or request a feature in Mbed TLS, please [file an issue on GitHub](https://github.com/Mbed-TLS/mbedtls/issues/new/choose).
|
||||
* Please see [`SUPPORT.md`](SUPPORT.md) for other channels for discussion and support about Mbed TLS.
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
## Reporting Vulnerabilities
|
||||
|
||||
If you think you have found an Mbed TLS security vulnerability, then please
|
||||
send an email to the security team at
|
||||
<mbed-tls-security@lists.trustedfirmware.org>.
|
||||
|
||||
## Security Incident Handling Process
|
||||
|
||||
Our security process is detailed in our
|
||||
[security
|
||||
center](https://developer.trustedfirmware.org/w/mbed-tls/security-center/).
|
||||
|
||||
Its primary goal is to ensure fixes are ready to be deployed when the issue
|
||||
goes public.
|
||||
|
||||
## Maintained branches
|
||||
|
||||
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.
|
||||
|
||||
#### Everest
|
||||
|
||||
The HACL* implementation of X25519 taken from the Everest project only protects
|
||||
against remote timing attacks. (See their [Security
|
||||
Policy](https://github.com/hacl-star/hacl-star/blob/main/SECURITY.md).)
|
||||
|
||||
The Everest variant is only used when `MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED`
|
||||
configuration option is defined. This option is off by default.
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
## Documentation
|
||||
|
||||
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#documentation);
|
||||
- the `docs` directory in the source tree;
|
||||
- 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/).
|
||||
|
||||
## Asking Questions
|
||||
|
||||
If you can't find your answer in the above sources, please use the [Mbed TLS
|
||||
mailing list](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org).
|
||||
@@ -1,3 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/MbedTLSTargets.cmake")
|
||||
@@ -1,24 +0,0 @@
|
||||
This directory contains example configuration files.
|
||||
|
||||
The examples are generally focused on a particular usage case (eg, support for
|
||||
a restricted number of ciphersuites) and aim at minimizing resource usage for
|
||||
this target. They can be used as a basis for custom configurations.
|
||||
|
||||
These files are complete replacements for the default mbedtls_config.h. To use one of
|
||||
them, you can pick one of the following methods:
|
||||
|
||||
1. Replace the default file include/mbedtls/mbedtls_config.h with the chosen one.
|
||||
|
||||
2. Define MBEDTLS_CONFIG_FILE and adjust the include path accordingly.
|
||||
For example, using make:
|
||||
|
||||
CFLAGS="-I$PWD/configs -DMBEDTLS_CONFIG_FILE='<foo.h>'" make
|
||||
|
||||
Or, using cmake:
|
||||
|
||||
find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
|
||||
CFLAGS="-I$PWD/configs -DMBEDTLS_CONFIG_FILE='<foo.h>'" cmake .
|
||||
make
|
||||
|
||||
Note that the second method also works if you want to keep your custom
|
||||
configuration file outside the Mbed TLS tree.
|
||||
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* \file config-ccm-psk-dtls1_2.h
|
||||
*
|
||||
* \brief Small configuration for DTLS 1.2 with PSK and AES-CCM ciphersuites
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* Minimal configuration for DTLS 1.2 with PSK and AES-CCM ciphersuites
|
||||
*
|
||||
* Distinguishing features:
|
||||
* - Optimized for small code size, low bandwidth (on an unreliable transport),
|
||||
* and low RAM usage.
|
||||
* - No asymmetric cryptography (no certificates, no Diffie-Hellman key
|
||||
* exchange).
|
||||
* - Fully modern and secure (provided the pre-shared keys are generated and
|
||||
* stored securely).
|
||||
* - Very low record overhead with CCM-8.
|
||||
* - Includes several optional DTLS features typically used in IoT.
|
||||
*
|
||||
* See README.txt for usage instructions.
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
//#define MBEDTLS_HAVE_TIME /* Optionally used in Hello messages */
|
||||
/* Other MBEDTLS_HAVE_XXX flags irrelevant for this configuration */
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NET_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_COOKIE_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
#define MBEDTLS_SSL_TLS_C
|
||||
#define MBEDTLS_TIMING_C
|
||||
|
||||
/* TLS protocol feature support */
|
||||
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
#define MBEDTLS_SSL_PROTO_DTLS
|
||||
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
|
||||
#define MBEDTLS_SSL_DTLS_CONNECTION_ID
|
||||
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
|
||||
/*
|
||||
* Use only CCM_8 ciphersuites, and
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Save RAM at the expense of interoperability: do this only if you control
|
||||
* both ends of the connection! (See comments in "mbedtls/ssl.h".)
|
||||
* The optimal size here depends on the typical size of records.
|
||||
*/
|
||||
#define MBEDTLS_SSL_IN_CONTENT_LEN 256
|
||||
#define MBEDTLS_SSL_OUT_CONTENT_LEN 256
|
||||
|
||||
/* Save RAM at the expense of ROM */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/* Save some RAM by adjusting to your exact needs */
|
||||
#define MBEDTLS_PSK_MAX_LEN 16 /* 128-bits keys are generally enough */
|
||||
|
||||
/*
|
||||
* You should adjust this to the exact number of sources you're using: default
|
||||
* is the "platform_entropy_poll" source, but you may want to add other ones
|
||||
* Minimum is 2 for the entropy test suite.
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
|
||||
|
||||
/* These defines are present so that the config modifying scripts can enable
|
||||
* them during tests/scripts/test-ref-configs.pl */
|
||||
//#define MBEDTLS_USE_PSA_CRYPTO
|
||||
//#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/* Error messages and TLS debugging traces
|
||||
* (huge code size increase, needed for tests/ssl-opt.sh) */
|
||||
//#define MBEDTLS_DEBUG_C
|
||||
//#define MBEDTLS_ERROR_C
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* \file config-ccm-psk-tls1_2.h
|
||||
*
|
||||
* \brief Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
|
||||
*
|
||||
* Distinguishing features:
|
||||
* - Optimized for small code size, low bandwidth (on a reliable transport),
|
||||
* and low RAM usage.
|
||||
* - No asymmetric cryptography (no certificates, no Diffie-Hellman key
|
||||
* exchange).
|
||||
* - Fully modern and secure (provided the pre-shared keys are generated and
|
||||
* stored securely).
|
||||
* - Very low record overhead with CCM-8.
|
||||
*
|
||||
* See README.txt for usage instructions.
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
//#define MBEDTLS_HAVE_TIME /* Optionally used in Hello messages */
|
||||
/* Other MBEDTLS_HAVE_XXX flags irrelevant for this configuration */
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NET_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
#define MBEDTLS_SSL_TLS_C
|
||||
|
||||
/* TLS protocol feature support */
|
||||
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
|
||||
/*
|
||||
* Use only CCM_8 ciphersuites, and
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Save RAM at the expense of interoperability: do this only if you control
|
||||
* both ends of the connection! (See comments in "mbedtls/ssl.h".)
|
||||
* The optimal size here depends on the typical size of records.
|
||||
*/
|
||||
#define MBEDTLS_SSL_IN_CONTENT_LEN 1024
|
||||
#define MBEDTLS_SSL_OUT_CONTENT_LEN 1024
|
||||
|
||||
/* Save RAM at the expense of ROM */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/* Save some RAM by adjusting to your exact needs */
|
||||
#define MBEDTLS_PSK_MAX_LEN 16 /* 128-bits keys are generally enough */
|
||||
|
||||
/*
|
||||
* You should adjust this to the exact number of sources you're using: default
|
||||
* is the "platform_entropy_poll" source, but you may want to add other ones
|
||||
* Minimum is 2 for the entropy test suite.
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
|
||||
|
||||
/* These defines are present so that the config modifying scripts can enable
|
||||
* them during tests/scripts/test-ref-configs.pl */
|
||||
//#define MBEDTLS_USE_PSA_CRYPTO
|
||||
//#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/* Error messages and TLS debugging traces
|
||||
* (huge code size increase, needed for tests/ssl-opt.sh) */
|
||||
//#define MBEDTLS_DEBUG_C
|
||||
//#define MBEDTLS_ERROR_C
|
||||
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* \file config-no-entropy.h
|
||||
*
|
||||
* \brief Minimal configuration of features that do not require an entropy source
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* Minimal configuration of features that do not require an entropy source
|
||||
* Distinguishing features:
|
||||
* - no entropy module
|
||||
* - no TLS protocol implementation available due to absence of an entropy
|
||||
* source
|
||||
*
|
||||
* See README.txt for usage instructions.
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
#define MBEDTLS_HAVE_TIME
|
||||
|
||||
/* Mbed TLS feature support */
|
||||
#define MBEDTLS_CIPHER_MODE_CBC
|
||||
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
#define MBEDTLS_ECDSA_DETERMINISTIC
|
||||
#define MBEDTLS_PK_RSA_ALT_SUPPORT
|
||||
#define MBEDTLS_PKCS1_V15
|
||||
#define MBEDTLS_PKCS1_V21
|
||||
#define MBEDTLS_SELF_TEST
|
||||
#define MBEDTLS_VERSION_FEATURES
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ERROR_C
|
||||
#define MBEDTLS_GCM_C
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
#define MBEDTLS_RSA_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
|
||||
#define MBEDTLS_VERSION_C
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#define MBEDTLS_X509_CRL_PARSE_C
|
||||
//#define MBEDTLS_CMAC_C
|
||||
|
||||
/* Miscellaneous options */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* \file config-suite-b.h
|
||||
*
|
||||
* \brief Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
/*
|
||||
* Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
|
||||
*
|
||||
* Distinguishing features:
|
||||
* - no RSA or classic DH, fully based on ECC
|
||||
* - optimized for low RAM usage
|
||||
*
|
||||
* Possible improvements:
|
||||
* - if 128-bit security is enough, disable secp384r1 and SHA-512
|
||||
* - use embedded certs in DER format and disable PEM_PARSE_C and BASE64_C
|
||||
*
|
||||
* See README.txt for usage instructions.
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
#define MBEDTLS_HAVE_TIME
|
||||
|
||||
/* Mbed TLS feature support */
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_GCM_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NET_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SHA384_C
|
||||
#define MBEDTLS_SHA512_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
#define MBEDTLS_SSL_TLS_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#define MBEDTLS_X509_USE_C
|
||||
|
||||
/* For test certificates */
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
|
||||
/* Save RAM at the expense of ROM */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/* Save RAM by adjusting to our exact needs */
|
||||
#define MBEDTLS_MPI_MAX_SIZE 48 // 384-bit EC curve = 48 bytes
|
||||
|
||||
/* Save RAM at the expense of speed, see ecp.h */
|
||||
#define MBEDTLS_ECP_WINDOW_SIZE 2
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
|
||||
|
||||
/* Significant speed benefit at the expense of some ROM */
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/*
|
||||
* You should adjust this to the exact number of sources you're using: default
|
||||
* is the "mbedtls_platform_entropy_poll" source, but you may want to add other ones.
|
||||
* Minimum is 2 for the entropy test suite.
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
|
||||
|
||||
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
|
||||
#define MBEDTLS_SSL_CIPHERSUITES \
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \
|
||||
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
|
||||
/*
|
||||
* Save RAM at the expense of interoperability: do this only if you control
|
||||
* both ends of the connection! (See comments in "mbedtls/ssl.h".)
|
||||
* The minimum size here depends on the certificate chain used as well as the
|
||||
* typical size of records.
|
||||
*/
|
||||
#define MBEDTLS_SSL_IN_CONTENT_LEN 1024
|
||||
#define MBEDTLS_SSL_OUT_CONTENT_LEN 1024
|
||||
|
||||
/* These defines are present so that the config modifying scripts can enable
|
||||
* them during tests/scripts/test-ref-configs.pl */
|
||||
//#define MBEDTLS_USE_PSA_CRYPTO
|
||||
//#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/* Error messages and TLS debugging traces
|
||||
* (huge code size increase, needed for tests/ssl-opt.sh) */
|
||||
//#define MBEDTLS_DEBUG_C
|
||||
//#define MBEDTLS_ERROR_C
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* \file config-symmetric-only.h
|
||||
*
|
||||
* \brief Configuration without any asymmetric cryptography.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
//#define MBEDTLS_HAVE_ASM
|
||||
#define MBEDTLS_HAVE_TIME
|
||||
#define MBEDTLS_HAVE_TIME_DATE
|
||||
|
||||
/* Mbed TLS feature support */
|
||||
#define MBEDTLS_CIPHER_MODE_CBC
|
||||
#define MBEDTLS_CIPHER_MODE_CFB
|
||||
#define MBEDTLS_CIPHER_MODE_CTR
|
||||
#define MBEDTLS_CIPHER_MODE_OFB
|
||||
#define MBEDTLS_CIPHER_MODE_XTS
|
||||
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||
#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
|
||||
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
|
||||
#define MBEDTLS_CIPHER_PADDING_ZEROS
|
||||
#define MBEDTLS_ERROR_STRERROR_DUMMY
|
||||
#define MBEDTLS_FS_IO
|
||||
#define MBEDTLS_ENTROPY_NV_SEED
|
||||
#define MBEDTLS_SELF_TEST
|
||||
#define MBEDTLS_USE_PSA_CRYPTO
|
||||
#define MBEDTLS_VERSION_FEATURES
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_CAMELLIA_C
|
||||
#define MBEDTLS_ARIA_C
|
||||
#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CHACHA20_C
|
||||
#define MBEDTLS_CHACHAPOLY_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_CMAC_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_DES_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_ERROR_C
|
||||
#define MBEDTLS_GCM_C
|
||||
#define MBEDTLS_HKDF_C
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_NIST_KW_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_MD5_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_PEM_WRITE_C
|
||||
#define MBEDTLS_PKCS5_C
|
||||
#define MBEDTLS_PKCS12_C
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
#define MBEDTLS_POLY1305_C
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
#define MBEDTLS_PSA_CRYPTO_SE_C
|
||||
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
#define MBEDTLS_PSA_ITS_FILE_C
|
||||
#define MBEDTLS_RIPEMD160_C
|
||||
#define MBEDTLS_SHA1_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
|
||||
//#define MBEDTLS_THREADING_C
|
||||
#define MBEDTLS_TIMING_C
|
||||
#define MBEDTLS_VERSION_C
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* \file config-tfm.h
|
||||
*
|
||||
* \brief TF-M medium profile, adapted to work on other platforms.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* TF-M medium profile: mbedtls legacy configuration */
|
||||
#include "../configs/ext/tfm_mbedcrypto_config_profile_medium.h"
|
||||
|
||||
/* TF-M medium profile: PSA crypto configuration */
|
||||
#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "../configs/ext/crypto_config_profile_medium.h"
|
||||
|
||||
/***********************************************************/
|
||||
/* Tweak the configuration to remove dependencies on TF-M. */
|
||||
/***********************************************************/
|
||||
|
||||
/* MBEDTLS_PSA_CRYPTO_SPM needs third-party files, so disable it. */
|
||||
#undef MBEDTLS_PSA_CRYPTO_SPM
|
||||
|
||||
/* Disable buffer-based memory allocator. This isn't strictly required,
|
||||
* but using the native allocator is faster and works better with
|
||||
* memory management analysis frameworks such as ASan. */
|
||||
#undef MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
||||
// This macro is enabled in TFM Medium but is disabled here because it is
|
||||
// incompatible with baremetal builds in Mbed TLS.
|
||||
#undef MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
// These platform-related TF-M settings are not useful here.
|
||||
#undef MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#undef MBEDTLS_PLATFORM_STD_MEM_HDR
|
||||
#undef MBEDTLS_PLATFORM_SNPRINTF_MACRO
|
||||
#undef MBEDTLS_PLATFORM_PRINTF_ALT
|
||||
#undef MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
|
||||
#undef MBEDTLS_PLATFORM_STD_EXIT_FAILURE
|
||||
|
||||
/*
|
||||
* In order to get an example config that works cleanly out-of-the-box
|
||||
* for both baremetal and non-baremetal builds, we detect baremetal builds
|
||||
* (either IAR, Arm compiler or __ARM_EABI__ defined), and adjust some
|
||||
* variables accordingly.
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__) || defined(__ARMCC_VERSION) || defined(__ARM_EABI__)
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#else
|
||||
/* Use built-in platform entropy functions (TF-M provides its own). */
|
||||
#undef MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Local changes to crypto config below this delimiter
|
||||
**********************************************************************/
|
||||
|
||||
// We expect TF-M to pick this up soon
|
||||
#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
|
||||
|
||||
/* CCM is the only cipher/AEAD enabled in TF-M configuration files, but it
|
||||
* does not need CIPHER_C to be enabled, so we can disable it in order
|
||||
* to reduce code size further. */
|
||||
#undef MBEDTLS_CIPHER_C
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* \file config-thread.h
|
||||
*
|
||||
* \brief Minimal configuration for using TLS as part of Thread
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* Minimal configuration for using TLS a part of Thread
|
||||
* http://threadgroup.org/
|
||||
*
|
||||
* Distinguishing features:
|
||||
* - no RSA or classic DH, fully based on ECC
|
||||
* - no X.509
|
||||
* - support for experimental EC J-PAKE key exchange
|
||||
*
|
||||
* See README.txt for usage instructions.
|
||||
*/
|
||||
|
||||
/* System support */
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
|
||||
/* Mbed TLS feature support */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
#define MBEDTLS_SSL_PROTO_DTLS
|
||||
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
|
||||
/* Mbed TLS modules */
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_CMAC_C
|
||||
#define MBEDTLS_ECJPAKE_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SSL_COOKIE_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
#define MBEDTLS_SSL_TLS_C
|
||||
|
||||
/* For tests using ssl-opt.sh */
|
||||
#define MBEDTLS_NET_C
|
||||
#define MBEDTLS_TIMING_C
|
||||
|
||||
/* Save RAM at the expense of ROM */
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/* Save RAM by adjusting to our exact needs */
|
||||
#define MBEDTLS_MPI_MAX_SIZE 32 // 256-bit EC curve = 32 bytes
|
||||
|
||||
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
|
||||
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
|
||||
|
||||
/* These defines are present so that the config modifying scripts can enable
|
||||
* them during tests/scripts/test-ref-configs.pl */
|
||||
//#define MBEDTLS_USE_PSA_CRYPTO
|
||||
//#define MBEDTLS_PSA_CRYPTO_C
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* \file configs/crypto-config-ccm-aes-sha256.h
|
||||
*
|
||||
* \brief PSA crypto configuration with only symmetric cryptography: CCM-AES,
|
||||
* SHA-256, HMAC and key derivation
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_CONFIG_H
|
||||
#define PSA_CRYPTO_CONFIG_H
|
||||
|
||||
#define PSA_WANT_ALG_CCM 1
|
||||
#define PSA_WANT_ALG_HMAC 1
|
||||
#define PSA_WANT_ALG_SHA_256 1
|
||||
#define PSA_WANT_ALG_TLS12_PRF 1
|
||||
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_HMAC 1
|
||||
#define PSA_WANT_KEY_TYPE_AES 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
|
||||
#endif /* PSA_CRYPTO_CONFIG_H */
|
||||
@@ -1,25 +0,0 @@
|
||||
Summary
|
||||
-------
|
||||
|
||||
The two files:
|
||||
|
||||
* crypto_config_profile_medium.h
|
||||
* tfm_mbedcrypto_config_profile_medium.h
|
||||
|
||||
are copyright The Mbed TLS Contributors, and are distributed under the license normally
|
||||
used by Mbed TLS: a dual Apache 2.0 or GPLv2-or-later license.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
The two files crypto_config_profile_medium.h and tfm_mbedcrypto_config_profile_medium.h
|
||||
are taken verbatim from the TF-M source code here:
|
||||
|
||||
https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/lib/ext/mbedcrypto/mbedcrypto_config
|
||||
|
||||
In TF-M, they are distributed under a 3-Clause BSD license, as noted at the top of the files.
|
||||
|
||||
In Mbed TLS, with permission from the TF-M project, they are distributed under a dual [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) OR [GPL-2.0-or-later](https://spdx.org/licenses/GPL-2.0-or-later.html) license, with copyright assigned to The Mbed TLS Contributors.
|
||||
|
||||
We only retain the note at the top of the files because we are taking the files verbatim, for ease of
|
||||
maintenance.
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Empty placeholder
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is intentionally empty.
|
||||
*
|
||||
* Having an empty file here allows us to build the TF-M config, which references this file,
|
||||
* without making any changes to the TF-M config.
|
||||
*/
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2023, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file psa/crypto_config.h
|
||||
* \brief PSA crypto configuration options (set of defines)
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||
/**
|
||||
* When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in mbedtls_config.h,
|
||||
* this file determines which cryptographic mechanisms are enabled
|
||||
* through the PSA Cryptography API (\c psa_xxx() functions).
|
||||
*
|
||||
* To enable a cryptographic mechanism, uncomment the definition of
|
||||
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
|
||||
* To disable a cryptographic mechanism, comment out the definition of
|
||||
* the corresponding \c PSA_WANT_xxx preprocessor symbol.
|
||||
* The names of cryptographic mechanisms correspond to values
|
||||
* defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead
|
||||
* of \c PSA_.
|
||||
*
|
||||
* Note that many cryptographic mechanisms involve two symbols: one for
|
||||
* the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm
|
||||
* (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve
|
||||
* additional symbols.
|
||||
*/
|
||||
#else
|
||||
/**
|
||||
* When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in mbedtls_config.h,
|
||||
* this file is not used, and cryptographic mechanisms are supported
|
||||
* through the PSA API if and only if they are supported through the
|
||||
* mbedtls_xxx API.
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef PROFILE_M_PSA_CRYPTO_CONFIG_H
|
||||
#define PROFILE_M_PSA_CRYPTO_CONFIG_H
|
||||
|
||||
/*
|
||||
* CBC-MAC is not yet supported via the PSA API in Mbed TLS.
|
||||
*/
|
||||
//#define PSA_WANT_ALG_CBC_MAC 1
|
||||
//#define PSA_WANT_ALG_CBC_NO_PADDING 1
|
||||
//#define PSA_WANT_ALG_CBC_PKCS7 1
|
||||
#define PSA_WANT_ALG_CCM 1
|
||||
//#define PSA_WANT_ALG_CMAC 1
|
||||
//#define PSA_WANT_ALG_CFB 1
|
||||
//#define PSA_WANT_ALG_CHACHA20_POLY1305 1
|
||||
//#define PSA_WANT_ALG_CTR 1
|
||||
//#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
//#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECDH 1
|
||||
#define PSA_WANT_ALG_ECDSA 1
|
||||
//#define PSA_WANT_ALG_GCM 1
|
||||
#define PSA_WANT_ALG_HKDF 1
|
||||
#define PSA_WANT_ALG_HMAC 1
|
||||
//#define PSA_WANT_ALG_MD5 1
|
||||
//#define PSA_WANT_ALG_OFB 1
|
||||
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
|
||||
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
|
||||
//#define PSA_WANT_ALG_PBKDF2_HMAC 1
|
||||
//#define PSA_WANT_ALG_RIPEMD160 1
|
||||
//#define PSA_WANT_ALG_RSA_OAEP 1
|
||||
//#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1
|
||||
//#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1
|
||||
//#define PSA_WANT_ALG_RSA_PSS 1
|
||||
//#define PSA_WANT_ALG_SHA_1 1
|
||||
#define PSA_WANT_ALG_SHA_224 1
|
||||
#define PSA_WANT_ALG_SHA_256 1
|
||||
//#define PSA_WANT_ALG_SHA_384 1
|
||||
//#define PSA_WANT_ALG_SHA_512 1
|
||||
//#define PSA_WANT_ALG_STREAM_CIPHER 1
|
||||
#define PSA_WANT_ALG_TLS12_PRF 1
|
||||
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
|
||||
/* PBKDF2-HMAC is not yet supported via the PSA API in Mbed TLS.
|
||||
* Note: when adding support, also adjust include/mbedtls/config_psa.h */
|
||||
//#define PSA_WANT_ALG_XTS 1
|
||||
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
|
||||
//#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
|
||||
//#define PSA_WANT_ECC_MONTGOMERY_255 1
|
||||
//#define PSA_WANT_ECC_MONTGOMERY_448 1
|
||||
//#define PSA_WANT_ECC_SECP_K1_192 1
|
||||
/*
|
||||
* SECP224K1 is buggy via the PSA API in Mbed TLS
|
||||
* (https://github.com/Mbed-TLS/mbedtls/issues/3541). Thus, do not enable it by
|
||||
* default.
|
||||
*/
|
||||
//#define PSA_WANT_ECC_SECP_K1_224 1
|
||||
//#define PSA_WANT_ECC_SECP_K1_256 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_192 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_224 1
|
||||
#define PSA_WANT_ECC_SECP_R1_256 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_384 1
|
||||
//#define PSA_WANT_ECC_SECP_R1_521 1
|
||||
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_HMAC 1
|
||||
#define PSA_WANT_KEY_TYPE_AES 1
|
||||
//#define PSA_WANT_KEY_TYPE_ARIA 1
|
||||
//#define PSA_WANT_KEY_TYPE_CAMELLIA 1
|
||||
//#define PSA_WANT_KEY_TYPE_CHACHA20 1
|
||||
//#define PSA_WANT_KEY_TYPE_DES 1
|
||||
//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 /* Deprecated */
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 /* Deprecated */
|
||||
//#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
|
||||
/*
|
||||
* The following symbols extend and deprecate the legacy
|
||||
* PSA_WANT_KEY_TYPE_xxx_KEY_PAIR ones. They include the usage of that key in
|
||||
* the name's suffix. "_USE" is the most generic and it can be used to describe
|
||||
* a generic suport, whereas other ones add more features on top of that and
|
||||
* they are more specific.
|
||||
*/
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
|
||||
//#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
|
||||
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
#include "crypto_accelerator_config.h"
|
||||
#endif
|
||||
|
||||
#endif /* PROFILE_M_PSA_CRYPTO_CONFIG_H */
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Empty placeholder
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is intentionally empty.
|
||||
*
|
||||
* Having an empty file here allows us to build the TF-M config, which references this file,
|
||||
* without making any changes to the TF-M config.
|
||||
*/
|
||||
@@ -1,573 +0,0 @@
|
||||
/**
|
||||
* \file config.h
|
||||
*
|
||||
* \brief Configuration options (set of defines)
|
||||
*
|
||||
* This set of compile-time options may be used to enable
|
||||
* or disable features selectively, and reduce the global
|
||||
* memory footprint.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2006-2023, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#ifndef PROFILE_M_MBEDTLS_CONFIG_H
|
||||
#define PROFILE_M_MBEDTLS_CONFIG_H
|
||||
|
||||
#include "config_tfm.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: System support
|
||||
*
|
||||
* This section sets system specific settings.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HAVE_ASM
|
||||
*
|
||||
* The compiler has support for asm().
|
||||
*
|
||||
* Requires support for asm() in compiler.
|
||||
*
|
||||
* Used in:
|
||||
* library/aria.c
|
||||
* library/timing.c
|
||||
* include/mbedtls/bn_mul.h
|
||||
*
|
||||
* Required by:
|
||||
* MBEDTLS_AESNI_C
|
||||
* MBEDTLS_PADLOCK_C
|
||||
*
|
||||
* Comment to disable the use of assembly code.
|
||||
*/
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PLATFORM_MEMORY
|
||||
*
|
||||
* Enable the memory allocation layer.
|
||||
*
|
||||
* By default mbed TLS uses the system-provided calloc() and free().
|
||||
* This allows different allocators (self-implemented or provided) to be
|
||||
* provided to the platform abstraction layer.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY without the
|
||||
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
|
||||
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
|
||||
* free() function pointer at runtime.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
|
||||
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
|
||||
* alternate function at compile time.
|
||||
*
|
||||
* Requires: MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* Enable this layer to allow use of alternative memory allocators.
|
||||
*/
|
||||
#define MBEDTLS_PLATFORM_MEMORY
|
||||
|
||||
/* \} name SECTION: System support */
|
||||
|
||||
/**
|
||||
* \name SECTION: mbed TLS feature support
|
||||
*
|
||||
* This section sets support for features that are or are not needed
|
||||
* within the modules that are enabled.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ROM_TABLES
|
||||
*
|
||||
* Use precomputed AES tables stored in ROM.
|
||||
*
|
||||
* Uncomment this macro to use precomputed AES tables stored in ROM.
|
||||
* Comment this macro to generate AES tables in RAM at runtime.
|
||||
*
|
||||
* Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
|
||||
* (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
|
||||
* initialization time before the first AES operation can be performed.
|
||||
* It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
|
||||
* MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
|
||||
* performance if ROM access is slower than RAM access.
|
||||
*
|
||||
* This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_ROM_TABLES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_FEWER_TABLES
|
||||
*
|
||||
* Use less ROM/RAM for AES tables.
|
||||
*
|
||||
* Uncommenting this macro omits 75% of the AES tables from
|
||||
* ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
|
||||
* by computing their values on the fly during operations
|
||||
* (the tables are entry-wise rotations of one another).
|
||||
*
|
||||
* Tradeoff: Uncommenting this reduces the RAM / ROM footprint
|
||||
* by ~6kb but at the cost of more arithmetic operations during
|
||||
* runtime. Specifically, one has to compare 4 accesses within
|
||||
* different tables to 4 accesses with additional arithmetic
|
||||
* operations within the same table. The performance gain/loss
|
||||
* depends on the system and memory details.
|
||||
*
|
||||
* This option is independent of \c MBEDTLS_AES_ROM_TABLES.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_AES_FEWER_TABLES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECP_NIST_OPTIM
|
||||
*
|
||||
* Enable specific 'modulo p' routines for each NIST prime.
|
||||
* Depending on the prime and architecture, makes operations 4 to 8 times
|
||||
* faster on the corresponding curve.
|
||||
*
|
||||
* Comment this macro to disable NIST curves optimisation.
|
||||
*/
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
*
|
||||
* Do not use built-in platform entropy functions.
|
||||
* This is useful if your platform does not support
|
||||
* standards like the /dev/urandom or Windows CryptoAPI.
|
||||
*
|
||||
* Uncomment this macro to disable the built-in platform entropy functions.
|
||||
*/
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_NV_SEED
|
||||
*
|
||||
* Enable the non-volatile (NV) seed file-based entropy source.
|
||||
* (Also enables the NV seed read/write functions in the platform layer)
|
||||
*
|
||||
* This is crucial (if not required) on systems that do not have a
|
||||
* cryptographic entropy source (in hardware or kernel) available.
|
||||
*
|
||||
* Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* \note The read/write functions that are used by the entropy source are
|
||||
* determined in the platform layer, and can be modified at runtime and/or
|
||||
* compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
|
||||
*
|
||||
* \note If you use the default implementation functions that read a seedfile
|
||||
* with regular fopen(), please make sure you make a seedfile with the
|
||||
* proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
|
||||
* least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
|
||||
* and written to or you will get an entropy source error! The default
|
||||
* implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
|
||||
* bytes from the file.
|
||||
*
|
||||
* \note The entropy collector will write to the seed file before entropy is
|
||||
* given to an external source, to update it.
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_NV_SEED
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_SPM
|
||||
*
|
||||
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
|
||||
* Partition Manager) integration which separates the code into two parts: a
|
||||
* NSPE (Non-Secure Process Environment) and an SPE (Secure Process
|
||||
* Environment).
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_SPM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_SMALLER
|
||||
*
|
||||
* Enable an implementation of SHA-256 that has lower ROM footprint but also
|
||||
* lower performance.
|
||||
*
|
||||
* The default implementation is meant to be a reasonnable compromise between
|
||||
* performance and size. This version optimizes more aggressively for size at
|
||||
* the expense of performance. Eg on Cortex-M4 it reduces the size of
|
||||
* mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
|
||||
* 30%.
|
||||
*
|
||||
* Uncomment to enable the smaller implementation of SHA256.
|
||||
*/
|
||||
#define MBEDTLS_SHA256_SMALLER
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
*
|
||||
* This setting allows support for cryptographic mechanisms through the PSA
|
||||
* API to be configured separately from support through the mbedtls API.
|
||||
*
|
||||
* When this option is disabled, the PSA API exposes the cryptographic
|
||||
* mechanisms that can be implemented on top of the `mbedtls_xxx` API
|
||||
* configured with `MBEDTLS_XXX` symbols.
|
||||
*
|
||||
* When this option is enabled, the PSA API exposes the cryptographic
|
||||
* mechanisms requested by the `PSA_WANT_XXX` symbols defined in
|
||||
* include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are
|
||||
* automatically enabled if required (i.e. if no PSA driver provides the
|
||||
* mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols
|
||||
* in mbedtls_config.h.
|
||||
*
|
||||
* If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies
|
||||
* an alternative header to include instead of include/psa/crypto_config.h.
|
||||
*
|
||||
* This feature is still experimental and is not ready for production since
|
||||
* it is not completed.
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
|
||||
/* \} name SECTION: mbed TLS feature support */
|
||||
|
||||
/**
|
||||
* \name SECTION: mbed TLS modules
|
||||
*
|
||||
* This section enables or disables entire modules in mbed TLS
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_C
|
||||
*
|
||||
* Enable the AES block cipher.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
* Caller: library/cipher.c
|
||||
* library/pem.c
|
||||
* library/ctr_drbg.c
|
||||
*
|
||||
* This module is required to support the TLS ciphersuites that use the AES
|
||||
* cipher.
|
||||
*
|
||||
* PEM_PARSE uses AES for decrypting encrypted keys.
|
||||
*/
|
||||
#define MBEDTLS_AES_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
|
||||
*
|
||||
* Use only 128-bit keys in AES operations to save ROM.
|
||||
*
|
||||
* Uncomment this macro to remove support for AES operations that use 192-
|
||||
* or 256-bit keys.
|
||||
*
|
||||
* Uncommenting this macro reduces the size of AES code by ~300 bytes
|
||||
* on v8-M/Thumb2.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
*
|
||||
* Requires: MBEDTLS_AES_C
|
||||
*/
|
||||
#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CIPHER_C
|
||||
*
|
||||
* Enable the generic cipher layer.
|
||||
*
|
||||
* Module: library/cipher.c
|
||||
*
|
||||
* Uncomment to enable generic cipher wrappers.
|
||||
*/
|
||||
#define MBEDTLS_CIPHER_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CTR_DRBG_C
|
||||
*
|
||||
* Enable the CTR_DRBG AES-based random generator.
|
||||
* The CTR_DRBG generator uses AES-256 by default.
|
||||
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
|
||||
*
|
||||
* Module: library/ctr_drbg.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_AES_C
|
||||
*
|
||||
* This module provides the CTR_DRBG AES random number generator.
|
||||
*/
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_C
|
||||
*
|
||||
* Enable the platform-specific entropy code.
|
||||
*
|
||||
* Module: library/entropy.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
|
||||
*
|
||||
* This module provides a generic entropy pool
|
||||
*/
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_HKDF_C
|
||||
*
|
||||
* Enable the HKDF algorithm (RFC 5869).
|
||||
*
|
||||
* Module: library/hkdf.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: MBEDTLS_MD_C
|
||||
*
|
||||
* This module adds support for the Hashed Message Authentication Code
|
||||
* (HMAC)-based key derivation function (HKDF).
|
||||
*/
|
||||
//#define MBEDTLS_HKDF_C /* Used for HUK deriviation */
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
*
|
||||
* Enable the buffer allocator implementation that makes use of a (stack)
|
||||
* based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
|
||||
* calls)
|
||||
*
|
||||
* Module: library/memory_buffer_alloc.c
|
||||
*
|
||||
* Requires: MBEDTLS_PLATFORM_C
|
||||
* MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
|
||||
*
|
||||
* Enable this module to enable the buffer memory allocator.
|
||||
*/
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* Enable the platform abstraction layer that allows you to re-assign
|
||||
* functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
|
||||
* or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
|
||||
* above to be specified at runtime or compile time respectively.
|
||||
*
|
||||
* \note This abstraction layer must be enabled on Windows (including MSYS2)
|
||||
* as other module rely on it for a fixed snprintf implementation.
|
||||
*
|
||||
* Module: library/platform.c
|
||||
* Caller: Most other .c files
|
||||
*
|
||||
* This module enables abstraction of common (libc) functions.
|
||||
*/
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
|
||||
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#define MBEDTLS_PLATFORM_STD_MEM_HDR <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
|
||||
#define MBEDTLS_PLATFORM_PRINTF_ALT
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
* Enable the Platform Security Architecture cryptography API.
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
*
|
||||
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
*
|
||||
* Enable the Platform Security Architecture persistent key storage.
|
||||
*
|
||||
* Module: library/psa_crypto_storage.c
|
||||
*
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C,
|
||||
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
|
||||
* the PSA ITS interface
|
||||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
|
||||
/* \} name SECTION: mbed TLS modules */
|
||||
|
||||
/**
|
||||
* \name SECTION: General configuration options
|
||||
*
|
||||
* This section contains Mbed TLS build settings that are not associated
|
||||
* with a particular module.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included instead of
|
||||
* `"mbedtls/mbedtls_config.h"`.
|
||||
* This header file specifies the compile-time configuration of Mbed TLS.
|
||||
* Unlike other configuration options, this one must be defined on the
|
||||
* compiler command line: a definition in `mbedtls_config.h` would have
|
||||
* no effect.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_USER_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included after
|
||||
* `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE.
|
||||
* This allows you to modify the default configuration, including the ability
|
||||
* to undefine options that are enabled by default.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_USER_CONFIG_FILE "/dev/null"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included instead of
|
||||
* `"psa/crypto_config.h"`.
|
||||
* This header file specifies which cryptographic mechanisms are available
|
||||
* through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and
|
||||
* is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h"
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE
|
||||
*
|
||||
* If defined, this is a header which will be included after
|
||||
* `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE.
|
||||
* This allows you to modify the default configuration, including the ability
|
||||
* to undefine options that are enabled by default.
|
||||
*
|
||||
* This macro is expanded after an <tt>\#include</tt> directive. This is a popular but
|
||||
* non-standard feature of the C language, so this feature is only available
|
||||
* with compilers that perform macro expansion on an <tt>\#include</tt> line.
|
||||
*
|
||||
* The value of this symbol is typically a path in double quotes, either
|
||||
* absolute or relative to a directory on the include search path.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null"
|
||||
|
||||
/** \} name SECTION: General configuration options */
|
||||
|
||||
/**
|
||||
* \name SECTION: Module configuration options
|
||||
*
|
||||
* This section allows for the setting of module specific sizes and
|
||||
* configuration options. The default values are already present in the
|
||||
* relevant header files and should suffice for the regular use cases.
|
||||
*
|
||||
* Our advice is to enable options and change their values here
|
||||
* only if you have a good reason and know the consequences.
|
||||
*
|
||||
* Please check the respective header file for documentation on these
|
||||
* parameters (to prevent duplicate documentation).
|
||||
* \{
|
||||
*/
|
||||
|
||||
/* ECP options */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Disable fixed-point speed-up */
|
||||
|
||||
/**
|
||||
* Uncomment to enable p256-m. This is an alternative implementation of
|
||||
* key generation, ECDH and (randomized) ECDSA on the curve SECP256R1.
|
||||
* Compared to the default implementation:
|
||||
*
|
||||
* - p256-m has a much smaller code size and RAM footprint.
|
||||
* - p256-m is only available via the PSA API. This includes the pk module
|
||||
* when #MBEDTLS_USE_PSA_CRYPTO is enabled.
|
||||
* - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols
|
||||
* over the core arithmetic, or deterministic derivation of keys.
|
||||
*
|
||||
* We recommend enabling this option if your application uses the PSA API
|
||||
* and the only elliptic curve support it needs is ECDH and ECDSA over
|
||||
* SECP256R1.
|
||||
*
|
||||
* If you enable this option, you do not need to enable any ECC-related
|
||||
* MBEDTLS_xxx option. You do need to separately request support for the
|
||||
* cryptographic mechanisms through the PSA API:
|
||||
* - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based
|
||||
* configuration;
|
||||
* - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS;
|
||||
* - #PSA_WANT_ECC_SECP_R1_256;
|
||||
* - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed;
|
||||
* - #PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY, #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC,
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT,
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed.
|
||||
*
|
||||
* \note To benefit from the smaller code size of p256-m, make sure that you
|
||||
* do not enable any ECC-related option not supported by p256-m: this
|
||||
* would cause the built-in ECC implementation to be built as well, in
|
||||
* order to provide the required option.
|
||||
* Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and
|
||||
* #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than
|
||||
* SECP256R1 are disabled as they are not supported by this driver.
|
||||
* Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or
|
||||
* #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of
|
||||
* the built-in ECC implementation, see docs/driver-only-builds.md.
|
||||
*/
|
||||
#define MBEDTLS_PSA_P256M_DRIVER_ENABLED
|
||||
|
||||
/* \} name SECTION: Customisation configuration options */
|
||||
|
||||
#if CRYPTO_NV_SEED
|
||||
#include "tfm_mbedcrypto_config_extra_nv_seed.h"
|
||||
#endif /* CRYPTO_NV_SEED */
|
||||
|
||||
#if !defined(CRYPTO_HW_ACCELERATOR) && defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#include "mbedtls_entropy_nv_seed_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTO_HW_ACCELERATOR
|
||||
#include "mbedtls_accelerator_config.h"
|
||||
#endif
|
||||
|
||||
#endif /* PROFILE_M_MBEDTLS_CONFIG_H */
|
||||
@@ -1,37 +0,0 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
1 Letterman Drive
|
||||
Suite D4700
|
||||
San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
@@ -1,4 +0,0 @@
|
||||
*.html
|
||||
*.pdf
|
||||
_build/
|
||||
api/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,21 +0,0 @@
|
||||
PANDOC = pandoc
|
||||
|
||||
default: all
|
||||
|
||||
all_markdown = $(wildcard *.md */*.md)
|
||||
|
||||
html: $(all_markdown:.md=.html)
|
||||
pdf: $(all_markdown:.md=.pdf)
|
||||
all: html pdf
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .md .html .pdf
|
||||
|
||||
.md.html:
|
||||
$(PANDOC) -o $@ $<
|
||||
.md.pdf:
|
||||
$(PANDOC) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.html *.pdf
|
||||
rm -f testing/*.html testing/*.pdf
|
||||
@@ -1,91 +0,0 @@
|
||||
Alternative implementations of Mbed TLS functionality
|
||||
=====================================================
|
||||
|
||||
This document describes how parts of the Mbed TLS functionality can be replaced at compile time to integrate the library on a platform.
|
||||
|
||||
This document is an overview. It is not exhaustive. Please consult the documentation of individual modules and read the library header files for more details.
|
||||
|
||||
## Platform integration
|
||||
|
||||
Mbed TLS works out of the box on Unix/Linux/POSIX-like systems and on Windows. On embedded platforms, you may need to customize some aspects of how Mbed TLS interacts with the underlying platform. This section discusses the main areas that can be configured.
|
||||
|
||||
The platform module (`include/mbedtls/platform.h`) controls how Mbed TLS accesses standard library features such as memory management (`calloc`, `free`), `printf`, `exit`. You can define custom functions instead of the ones from the C standard library through `MBEDTLS_PLATFORM_XXX` options in the configuration file. Many options have two mechanisms: either define `MBEDTLS_PLATFORM_XXX_MACRO` to the name of a function to call instead of the standard function `xxx`, or define `MBEDTLS_PLATFORM_XXX_ALT` and [register an alternative implementation during the platform setup](#alternative-implementations-of-platform-functions).
|
||||
|
||||
The storage of the non-volatile seed for random generation, enabled with `MBEDTLS_ENTROPY_NV_SEED`, is also controlled via the platform module.
|
||||
|
||||
For timing functions, you can [declare an alternative implementation of the timing module](#module-alternative-implementations).
|
||||
|
||||
On multithreaded platforms, [declare an alternative implementation of the threading module](#module-alternative-implementations).
|
||||
|
||||
To configure entropy sources (hardware random generators), see the `MBEDTLS_ENTROPY_XXX` options in the configuration file.
|
||||
|
||||
For networking, the `net_sockets` module does not currently support alternative implementations. If this module does not work on your platform, disable `MBEDTLS_NET_C` and use custom functions for TLS.
|
||||
|
||||
If your platform has a cryptographic accelerator, you can use it via a [PSA driver](#psa-cryptography-drivers) or declare an [alternative implementation of the corresponding module(s)](#module-alternative-implementations) or [of specific functions](#function-alternative-implementations). PSA drivers will ultimately replace the alternative implementation mechanism, but alternative implementation will remain supported in at least all Mbed TLS versions of the form 3.x. The interface of PSA drivers is currently still experimental and subject to change.
|
||||
|
||||
## PSA cryptography drivers
|
||||
|
||||
On platforms where a hardware cryptographic engine is present, you can implement a driver for this engine in the PSA interface. Drivers are supported for cryptographic operations with transparent keys (keys available in cleartext), for cryptographic operations with opaque keys (keys that are only available inside the cryptographic engine), and for random generation. Calls to `psa_xxx` functions that perform cryptographic operations are directed to drivers instead of the built-in code as applicable. See the [PSA cryptography driver interface specification](docs/proposed/psa-driver-interface.md), the [Mbed TLS PSA driver developer guide](docs/proposed/psa-driver-developer-guide.md) and the [Mbed TLS PSA driver integration guide](docs/proposed/psa-driver-integration-guide.md) for more information.
|
||||
|
||||
As of Mbed TLS 3.0, this interface is still experimental and subject to change, and not all operations support drivers yet. The configuration option `MBEDTLS_USE_PSA_CRYPTO` causes parts of the `mbedtls_xxx` API to use PSA crypto and therefore to support drivers, however it is not yet compatible with all drivers.
|
||||
|
||||
## Module alternative implementations
|
||||
|
||||
You can replace the code of some modules of Mbed TLS at compile time by a custom implementation. This is possible for low-level cryptography modules (symmetric algorithms, DHM, RSA, ECP, ECJPAKE) and for some platform-related modules (threading, timing). Such custom implementations are called “alternative implementations”, or “ALT implementations” for short.
|
||||
|
||||
The general principle of an alternative implementation is:
|
||||
* Enable `MBEDTLS_XXX_ALT` in the compile-time configuration where XXX is the module name. For example, `MBEDTLS_AES_ALT` for an implementation of the AES module. This is in addition to enabling `MBEDTLS_XXX_C`.
|
||||
* 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://mbed-tls.readthedocs.io/en/latest/kb/development/hw_acc_guidelines for a more detailed guide.
|
||||
|
||||
### Constraints on context types
|
||||
|
||||
Generally, alternative implementations can define their context types to any C type except incomplete and array types (although they would normally be `struct` types). This section lists some known limitations where the context type needs to be a structure with certain fields.
|
||||
|
||||
Where a context type needs to have a certain field, the field must have the same type and semantics as in the built-in implementation, but does not need to be at the same position in the structure. Furthermore, unless otherwise indicated, only read access is necessary: the field can be `const`, and modifications to it do not need to be supported. For example, if an alternative implementation of asymmetric cryptography uses a different representation of large integers, it is sufficient to provide a read-only copy of the fields listed here of type `mbedtls_mpi`.
|
||||
|
||||
* AES: if `MBEDTLS_AESNI_C` or `MBEDTLS_PADLOCK_C` is enabled, `mbedtls_aes_context` must have the fields `nr` and `rk`.
|
||||
* DHM: if `MBEDTLS_DEBUG_C` is enabled, `mbedtls_dhm_context` must have the fields `P`, `Q`, `G`, `GX`, `GY` and `K`.
|
||||
* ECP: `mbedtls_ecp_group` must have the fields `id`, `P`, `A`, `B`, `G`, `N`, `pbits` and `nbits`.
|
||||
* If `MBEDTLS_PK_PARSE_EC_EXTENDED` is enabled, those fields must be writable, and `mbedtls_ecp_point_read_binary()` must support a group structure where only `P`, `pbits`, `A` and `B` are set.
|
||||
|
||||
It must be possible to move a context object in memory (except during the execution of a library function that takes this context as an argument). (This is necessary, for example, to support applications that populate a context on the stack of an inner function and then copy the context upwards through the call chain, or applications written in a language with automatic memory management that can move objects on the heap.) That is, call sequences like the following must work:
|
||||
```
|
||||
mbedtls_xxx_context ctx1, ctx2;
|
||||
mbedtls_xxx_init(&ctx1);
|
||||
mbedtls_xxx_setup(&ctx1, …);
|
||||
ctx2 = ctx1;
|
||||
memset(&ctx1, 0, sizeof(ctx1));
|
||||
mbedtls_xxx_do_stuff(&ctx2, …);
|
||||
mbedtls_xxx_free(&ctx2);
|
||||
```
|
||||
In practice, this means that a pointer to a context or to a part of a context does not remain valid across function calls. Alternative implementations do not need to support copying of contexts: contexts can only be cloned through explicit `clone()` functions.
|
||||
|
||||
## Function alternative implementations
|
||||
|
||||
In some cases, it is possible to replace a single function or a small set of functions instead of [providing an alternative implementation of the whole module](#module-alternative-implementations).
|
||||
|
||||
### Alternative implementations of cryptographic functions
|
||||
|
||||
Options to replace individual functions of cryptographic modules generally have a name obtained by upper-casing the function name and appending `_ALT`. If the function name contains `_internal`, `_ext` or `_ret`, this is removed in the `_ALT` symbol. When the corresponding option is enabled, the built-in implementation of the function will not be compiled, and you must provide an alternative implementation at link time.
|
||||
|
||||
For example, enable `MBEDTLS_AES_ENCRYPT_ALT` at compile time and provide your own implementation of `mbedtls_aes_encrypt()` to provide an accelerated implementation of AES encryption that is compatible with the built-in key schedule. If you wish to implement key schedule differently, you can also enable `MBEDTLS_AES_SETKEY_ENC_ALT` and implement `mbedtls_aes_setkey_enc()`.
|
||||
|
||||
Another example: enable `MBEDTLS_SHA256_PROCESS_ALT` and implement `mbedtls_internal_sha256_process()` to provide an accelerated implementation of SHA-256 and SHA-224.
|
||||
|
||||
Note that since alternative implementations of individual functions cooperate with the built-in implementation of other functions, you must use the same layout for context objects as the built-in implementation. If you want to use different context types, you need to [provide an alternative implementation of the whole module](#module-alternative-implementations).
|
||||
|
||||
### Alternative implementations of platform functions
|
||||
|
||||
Several platform functions can be reconfigured dynamically by following the process described here. To reconfigure how Mbed TLS calls the standard library function `xxx()`:
|
||||
|
||||
* Define the symbol `MBEDTLS_PLATFORM_XXX_ALT` at compile time.
|
||||
* During the initialization of your application, set the global variable `mbedtls_xxx` to an alternative implementation of `xxx()`.
|
||||
|
||||
For example, to provide a custom `printf` function at run time, enable `MBEDTLS_PLATFORM_PRINTF_ALT` at compile time and assign to `mbedtls_printf` during the initialization of your application.
|
||||
|
||||
Merely enabling `MBEDTLS_PLATFORM_XXX_ALT` does not change the behavior: by default, `mbedtls_xxx` points to the standard function `xxx`.
|
||||
|
||||
Note that there are variations on the naming pattern. For example, some configurable functions are activated in pairs, such as `mbedtls_calloc` and `mbedtls_free` via `MBEDTLS_PLATFORM_MEMORY`. Consult the documentation of individual configuration options and of the platform module for details.
|
||||
@@ -1,467 +0,0 @@
|
||||
Mbed TLS storage specification
|
||||
=================================
|
||||
|
||||
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:
|
||||
|
||||
1. Any change may break existing installations and may require an upgrade path.
|
||||
1. This document retains historical information about all past released versions. Do not remove information from this document unless it has always been incorrect or it is about a version that you are sure was never released.
|
||||
|
||||
Mbed Crypto 0.1.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-0.1.0b, mbedcrypto-0.1.0b2
|
||||
|
||||
Released in November 2018. <br>
|
||||
Integrated in Mbed OS 5.11.
|
||||
|
||||
Supported backends:
|
||||
|
||||
* [PSA ITS](#file-namespace-on-its-for-0.1.0)
|
||||
* [C stdio](#file-namespace-on-stdio-for-0.1.0)
|
||||
|
||||
Supported features:
|
||||
|
||||
* [Persistent transparent keys](#key-file-format-for-0.1.0) designated by a [slot number](#key-names-for-0.1.0).
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0) on ITS only.
|
||||
|
||||
This is a beta release, and we do not promise backward compatibility, with one exception:
|
||||
|
||||
> On Mbed OS, if a device has a nonvolatile random seed file produced with Mbed OS 5.11.x and is upgraded to a later version of Mbed OS, the nonvolatile random seed file is preserved or upgraded.
|
||||
|
||||
We do not make any promises regarding key storage, or regarding the nonvolatile random seed file on other platforms.
|
||||
|
||||
### Key names for 0.1.0
|
||||
|
||||
Information about each key is stored in a dedicated file whose name is constructed from the key identifier. The way in which the file name is constructed depends on the storage backend. The content of the file is described [below](#key-file-format-for-0.1.0).
|
||||
|
||||
The valid values for a key identifier are the range from 1 to 0xfffeffff. This limitation on the range is not documented in user-facing documentation: according to the user-facing documentation, arbitrary 32-bit values are valid.
|
||||
|
||||
The code uses the following constant in an internal header (note that despite the name, this value is actually one plus the maximum permitted value):
|
||||
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
|
||||
|
||||
There is a shared namespace for all callers.
|
||||
|
||||
### Key file format for 0.1.0
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`
|
||||
* version (4 bytes): 0
|
||||
* type (4 bytes): `psa_key_type_t` value
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
|
||||
* key material length (4 bytes)
|
||||
* key material: output of `psa_export_key`
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Nonvolatile random seed file format for 0.1.0
|
||||
|
||||
The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
|
||||
|
||||
The file format is just the seed as a byte string with no metadata or encoding of any kind.
|
||||
|
||||
### File namespace on ITS for 0.1.0
|
||||
|
||||
Assumption: ITS provides a 32-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-0.1.0) of the [key whose identifier is the file identifier](#key-names-for-0.1.0).
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff: unused.
|
||||
|
||||
### File namespace on stdio for 0.1.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `CRYPTO_STORAGE_FILE_LOCATION` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu", key_id)` [content](#key-file-format-for-0.1.0) of the [key whose identifier](#key-names-for-0.1.0) is `key_id`.
|
||||
* Other files: unused.
|
||||
|
||||
Mbed Crypto 1.0.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-1.0.0d4, mbedcrypto-1.0.0
|
||||
|
||||
Released in February 2019. <br>
|
||||
Integrated in Mbed OS 5.12.
|
||||
|
||||
Supported integrations:
|
||||
|
||||
* [PSA platform](#file-namespace-on-a-psa-platform-for-1.0.0)
|
||||
* [library using PSA ITS](#file-namespace-on-its-as-a-library-for-1.0.0)
|
||||
* [library using C stdio](#file-namespace-on-stdio-for-1.0.0)
|
||||
|
||||
Supported features:
|
||||
|
||||
* [Persistent transparent keys](#key-file-format-for-1.0.0) designated by a [key identifier and owner](#key-names-for-1.0.0).
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0) on ITS only.
|
||||
|
||||
Backward compatibility commitments: TBD
|
||||
|
||||
### Key names for 1.0.0
|
||||
|
||||
Information about each key is stored in a dedicated file designated by the key identifier. In integrations where there is no concept of key owner (in particular, in library integrations), the key identifier is exactly the key identifier as defined in the PSA Cryptography API specification (`psa_key_id_t`). In integrations where there is a concept of key owner (integration into a service for example), the key identifier is made of an owner identifier (its semantics and type are integration specific) and of the key identifier (`psa_key_id_t`) from the key owner point of view.
|
||||
|
||||
The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-1.0.0).
|
||||
|
||||
* Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value.
|
||||
* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
|
||||
|
||||
### Key file format for 1.0.0
|
||||
|
||||
The layout is identical to [0.1.0](#key-file-format-for-0.1.0) so far. However note that the encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
|
||||
|
||||
### Nonvolatile random seed file format for 1.0.0
|
||||
|
||||
The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
|
||||
|
||||
The file format is just the seed as a byte string with no metadata or encoding of any kind.
|
||||
|
||||
This is unchanged since [the feature was introduced in Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
|
||||
### File namespace on a PSA platform for 1.0.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xffffff51, 0xffffff53 through 0xffffffff: unused, reserved for internal use of the crypto library or crypto service.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library for 1.0.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
|
||||
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff, 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### File namespace on stdio for 1.0.0
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
[Identical to 0.1.0](#file-namespace-on-stdio-for-0.1.0).
|
||||
|
||||
### Upgrade from 0.1.0 to 1.0.0.
|
||||
|
||||
* Delete files 1 through 0xfffeffff, which contain keys in a format that is no longer supported.
|
||||
|
||||
### Suggested changes to make before 1.0.0
|
||||
|
||||
The library integration and the PSA platform integration use different sets of file names. This is annoyingly non-uniform. For example, if we want to store non-key files, we have room in different ranges (0 through 0xffffffff on a PSA platform, 0xffff0000 through 0xffffffffffffffff in a library integration).
|
||||
|
||||
It would simplify things to always have a 32-bit owner, with a nonzero value, and thus reserve the range 0–0xffffffff for internal library use.
|
||||
|
||||
Mbed Crypto 1.1.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-1.1.0
|
||||
|
||||
Released in early June 2019. <br>
|
||||
Integrated in Mbed OS 5.13.
|
||||
|
||||
Changes since [1.0.0](#mbed-crypto-1.0.0):
|
||||
|
||||
* The stdio backend for storage has been replaced by an implementation of [PSA ITS over stdio](#file-namespace-on-stdio-for-1.1.0).
|
||||
* [Some changes in the key file format](#key-file-format-for-1.1.0).
|
||||
|
||||
### File namespace on stdio for 1.1.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a non-key file (currently: only the [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0)). The contents of the file are:
|
||||
* Magic header (8 bytes): `"PSA\0ITS\0"`
|
||||
* File contents.
|
||||
|
||||
### Key file format for 1.1.0
|
||||
|
||||
The key file format is identical to [1.0.0](#key-file-format-for-1.0.0), except for the following changes:
|
||||
|
||||
* A new policy field, marked as [NEW:1.1.0] below.
|
||||
* The encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
|
||||
|
||||
A self-contained description of the file layout follows.
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`
|
||||
* version (4 bytes): 0
|
||||
* type (4 bytes): `psa_key_type_t` value
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value [NEW:1.1.0]
|
||||
* key material length (4 bytes)
|
||||
* key material: output of `psa_export_key`
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
Mbed Crypto TBD
|
||||
---------------
|
||||
|
||||
Tags: TBD
|
||||
|
||||
Released in TBD 2019. <br>
|
||||
Integrated in Mbed OS TBD.
|
||||
|
||||
### Changes introduced in TBD
|
||||
|
||||
* The layout of a key file now has a lifetime field before the type field.
|
||||
* Key files can store references to keys in a secure element. In such key files, the key material contains the slot number.
|
||||
|
||||
### File namespace on a PSA platform on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xfffeffff: unused.
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### Non-key files on TBD
|
||||
|
||||
File identifiers in the range 0xffff0000 through 0xffffffff are reserved for internal use in Mbed Crypto.
|
||||
|
||||
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): secure element driver storage. The content of the file is the secure element driver's persistent data.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
|
||||
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-tbd).
|
||||
* Other files are unused and reserved for future use.
|
||||
|
||||
### Key file format for TBD
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (4 bytes): `psa_key_type_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Transaction file format for TBD
|
||||
|
||||
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
|
||||
|
||||
All integers are encoded in platform endianness.
|
||||
|
||||
All currently existing transactions concern a key in a secure element.
|
||||
|
||||
The layout of a transaction file is:
|
||||
|
||||
* type (2 bytes): the [transaction type](#transaction-types-on-tbd).
|
||||
* unused (2 bytes)
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
|
||||
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
|
||||
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-tbd)).
|
||||
|
||||
#### Transaction types on TBD
|
||||
|
||||
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
|
||||
Mbed Crypto TBD
|
||||
---------------
|
||||
|
||||
Tags: TBD
|
||||
|
||||
Released in TBD 2020. <br>
|
||||
Integrated in Mbed OS TBD.
|
||||
|
||||
### Changes introduced in TBD
|
||||
|
||||
* The type field has been split into a type and a bits field of 2 bytes each.
|
||||
|
||||
### Key file format for TBD
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (2 bytes): `psa_key_type_t` value.
|
||||
* bits (2 bytes): `psa_key_bits_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
Mbed TLS 2.25.0
|
||||
---------------
|
||||
|
||||
Tags: `mbedtls-2.25.0`, `mbedtls-2.26.0`, `mbedtls-2.27.0`, `mbedtls-2.28.0`, `mbedtls-3.0.0`, `mbedtls-3.1.0`
|
||||
|
||||
First released in December 2020.
|
||||
|
||||
Note: this is the first version that is officially supported. The version number is still 0.
|
||||
|
||||
Backward compatibility commitments: we promise backward compatibility for stored keys when Mbed TLS is upgraded from x to y if x >= 2.25 and y < 4. See [`BRANCHES.md`](../../BRANCHES.md) for more details.
|
||||
|
||||
Supported integrations:
|
||||
|
||||
* [PSA platform](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)
|
||||
* [library using PSA ITS](#file-namespace-on-its-as-a-library-on-mbed-tls-2.25.0)
|
||||
* [library using C stdio](#file-namespace-on-stdio-for-mbed-tls-2.25.0)
|
||||
|
||||
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 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.
|
||||
|
||||
### Changes introduced in Mbed TLS 2.25.0
|
||||
|
||||
* The numerical encodings of `psa_key_type_t`, `psa_key_usage_t` and `psa_algorithm_t` have changed.
|
||||
|
||||
### File namespace on a PSA platform on Mbed TLS 2.25.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xfffeffff: unused.
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library on Mbed TLS 2.25.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0).
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
|
||||
* Files 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### File namespace on stdio for Mbed TLS 2.25.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a [non-key file](#non-key-files-on-mbed-tls-2.25.0). The contents of the file are:
|
||||
* Magic header (8 bytes): `"PSA\0ITS\0"`
|
||||
* File contents.
|
||||
|
||||
### Key names for Mbed TLS 2.25.0
|
||||
|
||||
Information about each key is stored in a dedicated file designated by the key identifier. In integrations where there is no concept of key owner (in particular, in library integrations), the key identifier is exactly the key identifier as defined in the PSA Cryptography API specification (`psa_key_id_t`). In integrations where there is a concept of key owner (integration into a service for example), the key identifier is made of an owner identifier (its semantics and type are integration specific) and of the key identifier (`psa_key_id_t`) from the key owner point of view.
|
||||
|
||||
The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-mbed-tls-2.25.0).
|
||||
|
||||
* Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value which must be in the range 0x00000001..0x3fffffff (`PSA_KEY_ID_USER_MIN`..`PSA_KEY_ID_USER_MAX`).
|
||||
* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
|
||||
|
||||
### Key file format for Mbed TLS 2.25.0
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (2 bytes): `psa_key_type_t` value.
|
||||
* bits (2 bytes): `psa_key_bits_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a dynamic secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Non-key files on Mbed TLS 2.25.0
|
||||
|
||||
File identifiers that are outside the range of persistent key identifiers are reserved for internal use by the library. The only identifiers currently in use have the owner id (top 32 bits) set to 0.
|
||||
|
||||
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): dynamic secure element driver storage. The content of the file is the secure element driver's persistent data.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0).
|
||||
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-mbed-tls-2.25.0).
|
||||
* Other files are unused and reserved for future use.
|
||||
|
||||
### Nonvolatile random seed file format for Mbed TLS 2.25.0
|
||||
|
||||
[Identical to Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
|
||||
### Transaction file format for Mbed TLS 2.25.0
|
||||
|
||||
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
|
||||
|
||||
All integers are encoded in platform endianness.
|
||||
|
||||
All currently existing transactions concern a key in a dynamic secure element.
|
||||
|
||||
The layout of a transaction file is:
|
||||
|
||||
* type (2 bytes): the [transaction type](#transaction-types-on-mbed-tls-2.25.0).
|
||||
* unused (2 bytes)
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
|
||||
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
|
||||
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)).
|
||||
|
||||
#### Transaction types on Mbed TLS 2.25.0
|
||||
|
||||
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
@@ -1,175 +0,0 @@
|
||||
PSA Cryptography API implementation and PSA driver interface
|
||||
===========================================================
|
||||
|
||||
## Introduction
|
||||
|
||||
The [PSA Cryptography API specification](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) defines an interface to cryptographic operations for which the Mbed TLS library provides a reference implementation. The PSA Cryptography API specification is complemented by the PSA driver interface specification which defines an interface for cryptoprocessor drivers.
|
||||
|
||||
This document describes the high level organization of the Mbed TLS PSA Cryptography API implementation which is tightly related to the PSA driver interface.
|
||||
|
||||
## High level organization of the Mbed TLS PSA Cryptography API implementation
|
||||
In one sentence, the Mbed TLS PSA Cryptography API implementation is made of a core and PSA drivers as defined in the PSA driver interface. The key point is that software cryptographic operations are organized as PSA drivers: they interact with the core through the PSA driver interface.
|
||||
|
||||
### Rationale
|
||||
|
||||
* Addressing software and hardware cryptographic implementations through the same C interface reduces the core code size and its call graph complexity. The core and its dispatching to software and hardware implementations are consequently easier to test and validate.
|
||||
* The organization of the software cryptographic implementations in drivers promotes modularization of those implementations.
|
||||
* As hardware capabilities, software cryptographic functionalities can be described by a JSON driver description file as defined in the PSA driver interface.
|
||||
* Along with JSON driver description files, the PSA driver specification defines the deliverables for a driver to be included into the Mbed TLS PSA Cryptography implementation. This provides a natural framework to integrate third party or alternative software implementations of cryptographic operations.
|
||||
|
||||
## The Mbed TLS PSA Cryptography API implementation core
|
||||
|
||||
The core implements all the APIs as defined in the PSA Cryptography API specification but does not perform on its own any cryptographic operation. The core relies on PSA drivers to actually
|
||||
perform the cryptographic operations. The core is responsible for:
|
||||
|
||||
* the key store.
|
||||
* checking PSA API arguments and translating them into valid arguments for the necessary calls to the PSA driver interface.
|
||||
* dispatching the cryptographic operations to the appropriate PSA drivers.
|
||||
|
||||
The sketch of an Mbed TLS PSA cryptographic API implementation is thus:
|
||||
```C
|
||||
psa_status_t psa_api( ... )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* Pre driver interface call processing: validation of arguments, building
|
||||
* of arguments for the call to the driver interface, ... */
|
||||
|
||||
...
|
||||
|
||||
/* Call to the driver interface */
|
||||
status = psa_driver_wrapper_<entry_point>( ... );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* Post driver interface call processing: validation of the values returned
|
||||
* by the driver, finalization of the values to return to the caller,
|
||||
* clean-up in case of error ... */
|
||||
}
|
||||
```
|
||||
The code of most PSA APIs is expected to match precisely the above layout. However, it is likely that the code structure of some APIs will be more complicated with several calls to the driver interface, mainly to encompass a larger variety of hardware designs. For example, to encompass hardware accelerators that are capable of verifying a MAC and those that are only capable of computing a MAC, the psa_mac_verify() API could call first psa_driver_wrapper_mac_verify() and then fallback to psa_driver_wrapper_mac_compute().
|
||||
|
||||
The implementations of `psa_driver_wrapper_<entry_point>` functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are splited into two parts. The static ones are generated in a psa_crypto_driver_wrappers.h header file, the non-static ones are generated in a psa_crypto_driver_wrappers_no_static.c C file and the function prototypes declared in a psa_crypto_driver_wrappers_no_static.h header file.
|
||||
|
||||
The psa_driver_wrapper_<entry_point>() functions dispatch cryptographic operations to accelerator drivers, secure element drivers as well as to the software implementations of cryptographic operations.
|
||||
|
||||
Note that the implementation allows to build the library with only a C compiler by shipping a generated file corresponding to a pure software implementation. The driver entry points and their code in this generated file are guarded by pre-processor directives based on PSA_WANT_xyz macros (see [Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](psa-conditional-inclusion-c.html). That way, it is possible to compile and include in the library only the desired cryptographic operations.
|
||||
|
||||
### Key creation
|
||||
|
||||
Key creation implementation in Mbed TLS PSA core is articulated around three internal functions: psa_start_key_creation(), psa_finish_key_creation() and psa_fail_key_creation(). Implementations of key creation PSA APIs, namely psa_import_key(), psa_generate_key(), psa_key_derivation_output_key() and psa_copy_key() go by the following sequence:
|
||||
1. Check the input parameters.
|
||||
2. Call psa_start_key_creation() that allocates a key slot, prepares it with the specified key attributes, and in case of a volatile key assign it a volatile key identifier.
|
||||
3. Generate or copy the key material into the key slot. This entails the allocation of the buffer to store the key material.
|
||||
4. Call psa_finish_key_creation() that mostly saves persistent keys into persistent storage.
|
||||
|
||||
In case of any error occurring at step 3 or 4, psa_fail_key_creation() is called. It wipes and cleans the slot especially the key material: reset to zero of the RAM memory that contained the key material, free the allocated buffer.
|
||||
|
||||
|
||||
## Mbed TLS PSA Cryptography API implementation drivers
|
||||
|
||||
A driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software.
|
||||
|
||||
An Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa_<driver name>_<entry point>(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the "import_key" entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key().
|
||||
|
||||
## How to implement a new cryptographic mechanism
|
||||
|
||||
Summary of files to modify when adding a new algorithm or key type:
|
||||
|
||||
* [ ] PSA Crypto API draft, if not already done — [PSA standardization](#psa-standardization)
|
||||
* [ ] `include/psa/crypto_values.h` or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `include/psa/crypto_config.h`, `tests/include/test/drivers/crypto_config_test_driver_extension.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* Occasionally `library/check_crypto_config.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `include/mbedtls/config_psa.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `library/psa_crypto.c`, `library/psa_crypto_*.[hc]` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] `include/psa/crypto_builtin_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto_metadata.data` — [New functions and macros](#new-functions-and-macros)
|
||||
* (If adding `PSA_IS_xxx`) `tests/suites/test_suite_psa_crypto_metadata.function` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto*.data`, `tests/suites/test_suite_psa_crypto*.function` — [Unit tests](#unit-tests)
|
||||
* [ ] `scripts/mbedtls_dev/crypto_knowledge.py`, `scripts/mbedtls_dev/asymmetric_key_data.py` — [Unit tests](#unit-tests)
|
||||
* [ ] `ChangeLog.d/*.txt` — changelog entry
|
||||
|
||||
Summary of files to modify when adding new API functions:
|
||||
|
||||
* [ ] `include/psa/crypto.h` and `include/psa/crypto_sizes.h`, or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `library/psa_crypto.c`, `scripts/data_files/driver_templates/*.jinja` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] If adding stateful functions: `include/psa/crypto_struct.h`, `include/psa/crypto_builtin_*.h`, `include/psa/crypto_driver_contexts_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto.data`, `tests/suites/test_suite_psa_crypto.function`, `tests/suites/test_suite_psa_crypto_driver_wrappers.*` — [Unit tests](#unit-tests)
|
||||
|
||||
Note that this is just a basic guide. In some cases, you won't need to change all the files listed here. In some cases, you may need to change other files.
|
||||
|
||||
### PSA standardization
|
||||
|
||||
Typically, if there's enough demand for a cryptographic mechanism in Mbed TLS, there's enough demand for it to be part of the official PSA Cryptography specification. Therefore the first step before implementing a new mechanism should be to approach the PSA Cryptography working group in Arm for standardization.
|
||||
|
||||
At the time of writing, all cryptographic mechanisms that are accessible through `psa_xxx` APIs in in Mbed TLS are current or upcoming PSA standards. Mbed TLS implements some extensions to the PSA API that offer extra integration customization or extra key policies.
|
||||
|
||||
Mbed TLS routinely implements cryptographic mechanisms that are not yet part of a published PSA standard, but that are scheduled to be part of a future version of the standard. The Mbed TLS implementation validates the feasibility of the upcoming PSA standard. The PSA Cryptography working group and the Mbed TLS development team communicate during the elaboration of the new interfaces.
|
||||
|
||||
### New functions and macros
|
||||
|
||||
If a mechanism requires new functions, they should follow the design guidelines in the PSA Cryptography API specification.
|
||||
|
||||
Functions that are part of the current or upcoming API are declared in `include/psa/crypto.h`, apart from structure accessors defined in `include/psa/crypto_struct.h`. Functions that have output buffers have associated sufficient-output-size macros in `include/psa/crypto_sizes.h`.
|
||||
|
||||
Constants (algorithm identifiers, key type identifiers, etc.) and associated destructor macros (e.g. `PSA_IS_xxx()`) are defined in `include/psa/crypto_values.h`.
|
||||
|
||||
Functions and macros that are not intended for standardization, or that are at a stage where the draft standard might still evolve significantly, are declared in `include/psa/crypto_extra.h`.
|
||||
|
||||
The PSA Cryptography API specification defines both names and values for certain kinds of constants: algorithms (`PSA_ALG_xxx`), key types (`PSA_KEY_TYPE_xxx`), ECC curve families (`PSA_ECC_FAMILY_xxx`), DH group families (`PSA_DH_FAMILY_xxx`). If Mbed TLS defines an algorithm or a key type that is not part of a current or upcoming PSA standard, pick a value with the `VENDOR` flag set. If Mbed TLS defines an ECC curve or DH group family that is not part of a current or upcoming PSA standard, define a vendor key type and use the family identifier only with this vendor key type.
|
||||
|
||||
New constants must have a test case in `tests/suites/test_suite_psa_crypto_metadata.data` that verifies that `PSA_IS_xxx` macros behave properly with the new constant. New `PSA_IS_xxx` macros must be declared in `tests/suites/test_suite_psa_crypto_metadata.function`.
|
||||
|
||||
### Preprocessor symbols
|
||||
|
||||
Each cryptographic mechanism is optional and can be selected by the application at build time. For each feature `PSA_ttt_xxx`:
|
||||
|
||||
* The feature is available to applications when the preprocessor symbol `PSA_WANT_ttt_xxx` is defined. These symbols are set:
|
||||
* If `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled: based on the available mechanisms in Mbed TLS, deduced from `mbedtls/mbedtls_config.h` by code in `include/mbedtls/config_psa.h`.
|
||||
* if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled: in the application configuration file `include/psa/crypto_config.h` (or `MBEDTLS_PSA_CRYPTO_CONFIG_FILE`, plus `MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`), with code in `include/mbedtls/config_psa.h` deducing the necessary underlying `MBEDTLS_xxx` symbols.
|
||||
* For transparent keys (keys that are not in a secure element), the feature is implemented by Mbed TLS if `MBEDTLS_PSA_BUILTIN_ttt_xxx` is defined, and by an accelerator driver if `MBEDTLS_PSA_ACCEL_ttt_xxx` is defined. `MBEDTLS_PSA_BUILTIN_ttt_xxx` constants are set in `include/mbedtls/config_psa.h` based on the application requests `PSA_WANT_ttt_xxx` and the accelerator driver declarations `MBEDTLS_PSA_ACCEL_ttt_xxx`.
|
||||
* For the testing of the driver dispatch code, `tests/include/test/drivers/crypto_config_test_driver_extension.h` sets additional `MBEDTLS_PSA_ACCEL_xxx` symbols.
|
||||
|
||||
For more details, see *[Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](../proposed/psa-conditional-inclusion-c.html)*.
|
||||
|
||||
Some mechanisms require other mechanisms. For example, you can't do GCM without a block cipher, or RSA-PSS without RSA keys. When mechanism A requires mechanism B, `include/mbedtls/config_psa.h` ensures that B is enabled whenever A is enabled. When mechanism A requires at least one of a set {B1, B2, B3, ...} but there is no particular reason why enabling A would enable any of the specific Bi's, it's up to the application to choose Bi's and the file `library/check_crypto_config.h` contains compile-time constraints to ensure that at least one Bi is enabled.
|
||||
|
||||
### Implementation of the mechanisms
|
||||
|
||||
The general structure of a cryptographic operation function is:
|
||||
|
||||
1. API function defined in `library/psa_crypto.c`. The entry point performs generic checks that don't depend on whether the mechanism is implemented in software or in a driver and looks up keys in the key store.
|
||||
2. Driver dispatch code in `scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja`, `scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja` or files included from there.
|
||||
3. Built-in implementation in `library/psa_crypto_*.c` (with function declarations in the corresponding `.h` file). These files typically contain the implementation of modes of operation over basic building blocks that are defined elsewhere. For example, HMAC is implemented in `library/psa_crypto_mac.c` but the underlying hash functions are implemented in `library/sha*.c` and `library/md*.c`.
|
||||
4. Basic cryptographic building blocks in `library/*.c`.
|
||||
|
||||
When implementing a new algorithm or key type, there are typically things to change in `library/crypto.c` (e.g. buffer size calculations, algorithm/key-type compatibility) and in the built-in implementation, but not in the driver dispatch code.
|
||||
|
||||
### Translucent data structures
|
||||
|
||||
Some mechanisms require state to be kept between function calls. Keys and key-like data is kept in the key store, which PSA manages internally. Other state, for example the state of multipart operations, is kept in structures allocated by the caller.
|
||||
|
||||
The size of operation structures needs to be known at compile time, since callers may allocate them on the stack. Therefore these structures are defined in a public header: `include/psa/crypto_struct.h` for the parts that are independent of the underlying implementation, `include/psa/crypto_builtin_*` for parts that are specific to the Mbed TLS built-in implementation, `include/psa/crypto_driver_*.h` for structures implemented by drivers.
|
||||
|
||||
### Unit tests
|
||||
|
||||
A number of unit tests are automatically generated by `tests/scripts/generate_psa_tests.py` based on the algorithms and key types declared in `include/psa/crypto_values.h` and `include/psa/crypto_extra.h`:
|
||||
|
||||
* Attempt to create a key with a key type that is not supported.
|
||||
* Attempt to perform an operation with a combination of key type and algorithm that is not valid or not supported.
|
||||
* Storage and retrieval of a persistent key.
|
||||
|
||||
When adding a new key type or algorithm:
|
||||
|
||||
* `scripts/mbedtls_dev/crypto_knowledge.py` contains knowledge about the compatibility of key types, key sizes and algorithms.
|
||||
* `scripts/mbedtls_dev/asymmetric_key_data.py` contains valid key data for asymmetric key types.
|
||||
|
||||
Other things need to be tested manually, either in `tests/suites/test_sutie_psa_crypto.data` or in another file. For example (this is not an exhaustive list):
|
||||
|
||||
* Known answer tests.
|
||||
* Potential edge cases (e.g. data less/equal/more than the block size, number equal to zero in asymmetric cryptography).
|
||||
* Tests with invalid keys (e.g. wrong size or format).
|
||||
* Tests with invalid data (e.g. wrong size or format, output buffer too small, invalid padding).
|
||||
* For new functions: incorrect function call sequence, driver dispatch (in `tests/suites/test_suite_psa_crypto_driver_wrappers.*`).
|
||||
* For key derivation algorithms: variation on the sequence of input steps, variation on the output size.
|
||||
|
||||
@@ -1,616 +0,0 @@
|
||||
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 parts specific TLS 1.3).
|
||||
* Code that always uses PSA for crypto: TLS 1.3 (except things common with 1.2), LMS.
|
||||
|
||||
For the purposes of this work, three domains emerge:
|
||||
|
||||
* **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.
|
||||
|
||||
Hashes and HMAC (after the work on driver-only hashes):
|
||||
|
||||
* entropy (hashes via MD-light)
|
||||
* ECDSA (HMAC\_DRBG; `md.h` exposed through API)
|
||||
* ECJPAKE (hashes via MD-light; `md.h` exposed through API)
|
||||
* MD (hashes and HMAC)
|
||||
* HKDF (HMAC via `md.h`; `md.h` exposed through API)
|
||||
* HMAC\_DRBG (hashes and HMAC via `md.h`; `md.h` exposed through API)
|
||||
* PKCS12 (hashes via MD-light)
|
||||
* PKCS5 (HMAC via `md.h`; `md.h` exposed through API)
|
||||
* PKCS7 (hashes via MD)
|
||||
* RSA (hash via MD-light for PSS and OAEP; `md.h` exposed through API)
|
||||
* PEM (MD5 hash via MD-light)
|
||||
|
||||
Symmetric ciphers and AEADs (before work on driver-only cipher):
|
||||
|
||||
* PEM:
|
||||
* AES, DES or 3DES in CBC mode without padding, decrypt only (!).
|
||||
* Currently using low-level non-generic APIs.
|
||||
* No hard dependency, features guarded by `AES_C` resp. `DES_C`.
|
||||
* Functions called: `setkey_dec()` + `crypt_cbc()`.
|
||||
* PKCS12:
|
||||
* In practice: 2DES or 3DES in CBC mode with PKCS7 padding, decrypt only
|
||||
(when called from pkparse).
|
||||
* In principle: any cipher-mode (default padding), passed an
|
||||
`mbedtls_cipher_type_t` as an argument, no documented restriction.
|
||||
* Cipher, generically, selected from ASN.1 or function parameters;
|
||||
no documented restriction but in practice TODO (inc. padding and
|
||||
en/decrypt, look at standards and tests)
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: `cipher.h` exposed through API.
|
||||
* Functions called: `setup`, `setkey`, `set_iv`, `reset`, `update`, `finish` (in sequence, once).
|
||||
* PKCS5 (PBES2, `mbedtls_pkcs5_pbes2()`):
|
||||
* 3DES or DES in CBC mode with PKCS7 padding, both encrypt and decrypt.
|
||||
* Note: could also be AES in the future, see #7038.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Functions called: `setup`, `setkey`, `crypt`.
|
||||
* CTR\_DRBG:
|
||||
* AES in ECB mode, encrypt only.
|
||||
* Currently using low-level non-generic API (`aes.h`).
|
||||
* Unconditional dependency on `AES_C` in `check_config.h`.
|
||||
* Functions called: `setkey_enc`, `crypt_ecb`.
|
||||
* CCM:
|
||||
* AES, Camellia or Aria in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || CAMELLIA_C || ARIA_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* CMAC:
|
||||
* AES or DES in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || DES_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* GCM:
|
||||
* AES, Camellia or Aria in ECB mode, encrypt only.
|
||||
* Unconditional dependency on `AES_C || CAMELLIA_C || ARIA_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* NIST\_KW:
|
||||
* AES in ECB mode, both encryt and decrypt.
|
||||
* Unconditional dependency on `AES_C || DES_C` in `check_config.h`.
|
||||
* Unconditional dependency on `CIPHER_C` in `check_config.h`.
|
||||
* Note: also called by `cipher.c` if enabled.
|
||||
* Note: `cipher.h` exposed through API.
|
||||
* Functions called: `info`, `setup`, `setkey`, `update` (several times) - (never finish)
|
||||
* Cipher:
|
||||
* potentially any cipher/AEAD in any mode and any direction
|
||||
|
||||
Note: PSA cipher is built on Cipher, but PSA AEAD directly calls the underlying AEAD modules (GCM, CCM, ChachaPoly).
|
||||
|
||||
### Difficulties
|
||||
|
||||
#### 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`.
|
||||
|
||||
### Scope reductions and priorities for 3.x
|
||||
|
||||
This section documents things that we chose to temporarily exclude from the scope in the 3.x branch (which will eventually be in scope again after 4.0) as well as things we chose to prioritize if we don't have time to support everything.
|
||||
|
||||
#### Don't support PK, X.509 and TLS without `MBEDTLS_USE_PSA_CRYPTO`
|
||||
|
||||
We do not need to support driver-only hashes and ciphers in PK. X.509 and TLS without `MBEDTLS_USE_PSA_CRYPTO`. Users who want to take full advantage of drivers will need to enabled this macro.
|
||||
|
||||
Note that this applies to TLS 1.3 as well, as some uses of hashes and all uses of ciphers there are common with TLS 1.2, hence governed by `MBEDTLS_USE_PSA_CRYPTO`, see [this macro's extended documentation](../../docs/use-psa-crypto.html).
|
||||
|
||||
This will go away naturally in 4.0 when this macros is not longer an option (because it's always on).
|
||||
|
||||
#### Don't support for `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`
|
||||
|
||||
We generally don't really support builds with `MBEDTLS_PSA_CRYPTO_CLIENT` without `MBEDTLS_PSA_CRYPTO_C`. For example, both `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_SSL_PROTO_TLS1_3` require `MBEDTLS_PSA_CRYPTO_C`, while in principle they should only require `MBEDTLS_PSA_CRYPTO_CLIENT`.
|
||||
|
||||
Considering this existing restriction which we do not plan to lift before 4.0, it is acceptable driver-only hashes and cipher support to have the same restriction in 3.x.
|
||||
|
||||
It is however desirable for the design to keep support for `MBEDTLS_PSA_CRYPTO_CLIENT` in mind, in order to avoid making it more difficult to add in the future.
|
||||
|
||||
#### For cipher: prioritize constrained devices and modern TLS
|
||||
|
||||
The primary target is a configuration like TF-M's medium profile, plus TLS with only AEAD ciphersuites.
|
||||
|
||||
This excludes things like:
|
||||
- Support for encrypted PEM, PKCS5 and PKCS12 encryption, and PKCS8 encrypted keys in PK parse. (Not widely used on highly constrained devices.)
|
||||
- Support for NIST-KW. (Same justification.)
|
||||
- Support for CMAC. (Same justification, plus can be directly accelerated.)
|
||||
- Support for CBC ciphersuites in TLS. (They've been recommended against for a while now.)
|
||||
|
||||
### Dual-dispatch for block cipher primitives
|
||||
|
||||
Considering the priorities stated above, initially we want to support GCM, CCM and CTR-DRBG. All three of them use the block cipher primitive only in the encrypt direction. Currently, GCM and CCM use the Cipher layer in order to work with AES, Aria and Camellia (DES is excluded by the standards due to its smaller block size) and CTR-DRBG directly uses the low-level API from `aes.h`. In all cases, access to the "block cipher primitive" is done by using "ECB mode" (which for both Cipher and `aes.h` only allows a single block, contrary to PSA which implements actual ECB mode).
|
||||
|
||||
The two AEAD modes, GCM and CCM, have very similar needs and positions in the stack, strongly suggesting using the same design for both. On the other hand, there are a number of differences between CTR-DRBG and them.
|
||||
- CTR-DRBG only uses AES (and there is no plan to extend it to other block ciphers at the moment), while GCM and CCM need to work with 3 block ciphers already.
|
||||
- CTR-DRBG holds a special position in the stack: most users don't care about it per se, they only care about getting random numbers - in fact PSA users don't even need to know what DRBG is used. In particular, no part of the stack is asking questions like "is CTR-DRBG-AES available?" - an RNG needs to be available and that's it - contrary to similar questions about AES-GCM etc. which are asked for example by TLS.
|
||||
|
||||
So, it makes sense to use different designs for CTR-DRBG on one hand, and GCM/CCM on the other hand:
|
||||
- CTR-DRBG can just check if `AES_C` is present and "fall back" to PSA if not.
|
||||
- GCM and CCM need an common abstraction layer that allows:
|
||||
- Using AES, Aria or Camellia in a uniform way.
|
||||
- Dispatching to built-in or driver.
|
||||
|
||||
The abstraction layer used by GCM and CCM may either be a new internal module, or a subset of the existing Cipher API, extended with the ability to dispatch to a PSA driver.
|
||||
|
||||
Reasons for making this layer's API a subset of the existing Cipher API:
|
||||
- No need to design, implement and test a new module. (Will need to test the new subset though, as well as the extended behaviour.)
|
||||
- No code change in GCM and CCM - only need to update dependencies.
|
||||
- No risk for code duplication between a potential new module and Cipher: source-level, and in in particular in builds that still have `CIPHER_C` enabled. (Compiled-code duplication could be avoided by excluding the new module in such builds, though.)
|
||||
- If want to support other users of Cipher later (such as NIST-KW, CMAC, PKCS5 and PKCS12), we can just extend dual-dispatch support to other modes/operations in Cipher and keep those extra modules unchanged as well.
|
||||
|
||||
Possible costs of re-using (a subset of) the existing Cipher API instead of defining a new one:
|
||||
- We carry over costs associated with `cipher_info_t` structures. (Currently the info structure is used for 3 things: (1) to check if the cipher is supported, (2) to check its block size, (3) because `setup()` requires it).
|
||||
- We carry over questionable implementation decisions, like dynamic allocation of context.
|
||||
|
||||
Those costs could be avoided by refactoring (parts of) Cipher, but that would probably mean either:
|
||||
- significant differences in how the `cipher.h` API is implemented between builds with the full Cipher or only a subset;
|
||||
- or more work to apply the simplifications to all of Cipher.
|
||||
|
||||
Prototyping both approaches showed better code size savings and cleaner code with a new internal module (see section "Internal "block cipher" abstraction (Cipher light)" below).
|
||||
|
||||
## Specification
|
||||
|
||||
### MD light
|
||||
|
||||
#### 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's driver subsystem has been initialized.
|
||||
|
||||
Usage note: for algorithms that are not enabled via PSA, calling `psa_can_do_hash` is generally safe: whether it returns 0 or 1, you can call a PSA hash function on the algorithm and it will return `PSA_ERROR_NOT_SUPPORTED`.
|
||||
|
||||
#### 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, MD light calls `mbedtls_md_error_from_psa` to convert its status code.
|
||||
|
||||
### 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
|
||||
|
||||
#### 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.
|
||||
|
||||
### Internal "block cipher" abstraction (previously known as "Cipher light")
|
||||
|
||||
#### Definition
|
||||
|
||||
The new module is automatically enabled in `config_adjust_legacy_crypto.h` by modules that need
|
||||
it (namely: CCM, GCM) only when `CIPHER_C` is not available, or the new module
|
||||
is needed for PSA dispatch (see next section). Note: CCM and GCM currently
|
||||
depend on the full `CIPHER_C` (enforced by `check_config.h`); this hard
|
||||
dependency would be replaced by the above auto-enablement.
|
||||
|
||||
The following API functions are offered:
|
||||
```
|
||||
void mbedtls_block_cipher_init(mbedtls_block_cipher_context_t *ctx);
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx);
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id);
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen);
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
```
|
||||
|
||||
The only supported ciphers are AES, ARIA and Camellia. They are identified by
|
||||
an `mbedtls_cipher_id_t` in the `setup()` function, because that's how they're
|
||||
identifed by callers (GCM/CCM).
|
||||
|
||||
#### Block cipher dual dispatch
|
||||
|
||||
Support for dual dispatch in the new internal module `block_cipher` is extremely similar to that in MD light.
|
||||
|
||||
A block cipher context contains either a legacy module's context (AES, ARIA, Camellia) or a PSA key identifier; it has a field indicating which one is in use. All fields are private.
|
||||
|
||||
The `engine` field is almost redundant with knowledge about `type`. However, when an algorithm is available both via a legacy module and a PSA accelerator, we will choose based on the runtime availability of the accelerator when the context is set up. This choice needs to be recorded in the context structure.
|
||||
|
||||
Support is determined at runtime using the new internal function
|
||||
```
|
||||
int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg);
|
||||
```
|
||||
|
||||
The job of this private function is to return 1 if `hash_alg` can be performed through PSA now, and 0 otherwise. It is only defined on algorithms that are enabled via PSA. As a starting point, return 1 if PSA crypto's driver subsystem has been initialized.
|
||||
|
||||
Each function in the module needs to know whether to dispatch via PSA or legacy. All functions consult the context's `engine` field, except `setup()` which will set it according to the key type and the return value of `psa_can_do_cipher()` as discussed above.
|
||||
|
||||
Note that this assumes that an operation that has been started via PSA can be completed. This implies that `mbedtls_psa_crypto_free` must not be called while an operation using PSA is in progress.
|
||||
|
||||
After calling a PSA function, `block_cipher` functions call `mbedtls_cipher_error_from_psa` to convert its status code.
|
||||
@@ -1,140 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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 check the first testing criterion mentioned in strategy.md,
|
||||
# end of section "Supporting builds with drivers without the software
|
||||
# implementation", namely: the sets of tests skipped in the default config and
|
||||
# the full config must be the same before and after the PR.
|
||||
#
|
||||
# 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: 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").
|
||||
|
||||
set -eu
|
||||
|
||||
: ${SKIP_SSL_OPT:=0}
|
||||
|
||||
cleanup() {
|
||||
make clean
|
||||
git checkout -- include/mbedtls/mbedtls_config.h include/psa/crypto_config.h
|
||||
}
|
||||
|
||||
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.
|
||||
# Note: this can optionally be updated to
|
||||
# HEAD=$(git branch --show-current)
|
||||
# when using a Git version above 2.22
|
||||
HEAD=$(git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# get the numbers before this PR for default and full
|
||||
cleanup
|
||||
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"
|
||||
|
||||
cleanup
|
||||
|
||||
# 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=";$suite;"
|
||||
total=$(grep -c "$pattern_suite" "$ref")
|
||||
sed_cmd="s/^.*$pattern_suite\(.*\);SKIP.*/\1/p"
|
||||
sed -n "$sed_cmd" "$ref" > skipped-ref
|
||||
sed -n "$sed_cmd" "$new" > skipped-new
|
||||
nb_ref=$(wc -l <skipped-ref)
|
||||
nb_new=$(wc -l <skipped-new)
|
||||
|
||||
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
|
||||
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
|
||||
@@ -1,344 +0,0 @@
|
||||
Bridges between legacy and PSA crypto APIs
|
||||
==========================================
|
||||
|
||||
## Introduction
|
||||
|
||||
### Goal of this document
|
||||
|
||||
This document explores the needs of applications that use both Mbed TLS legacy crypto interfaces and PSA crypto interfaces. Based on [requirements](#requirements), we [analyze gaps](#gap-analysis) and [API design](#api-design).
|
||||
|
||||
This is a design document. The target audience is library maintainers. See the companion document [“Transitioning to the PSA API”](../../psa-transition.md) for a user focus on the same topic.
|
||||
|
||||
### Keywords
|
||||
|
||||
* [TODO] A part of the analysis that isn't finished.
|
||||
* [OPEN] Open question: a specific aspect of the design where there are several plausible decisions.
|
||||
* [ACTION] A finalized part of the design that will need to be carried out.
|
||||
|
||||
### Context
|
||||
|
||||
Mbed TLS 3.x supports two cryptographic APIs:
|
||||
|
||||
* The legacy API `mbedtls_xxx` is inherited from PolarSSL.
|
||||
* The PSA API `psa_xxx` was introduced in Mbed TLS 2.17.
|
||||
|
||||
Mbed TLS is gradually shifting from the legacy API to the PSA API. Mbed TLS 4.0 will be the first version where the PSA API is considered the main API, and large parts of the legacy API will be removed.
|
||||
|
||||
In Mbed TLS 4.0, the cryptography will be provided by a separate project [TF-PSA-Crypto](https://github.com/Mbed-TLS/TF-PSA-Crypto). For simplicity, in this document, we just refer to the whole as “Mbed TLS”.
|
||||
|
||||
### Document history
|
||||
|
||||
This document was originally written when preparing Mbed TLS 3.6. Mbed TLS 3.6 includes both PSA and legacy APIs covering largely overlapping ground. Many legacy APIs will be removed in Mbed TLS 4.0.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Why mix APIs?
|
||||
|
||||
There is functionality that is tied to one API and is not directly available in the other API:
|
||||
|
||||
* Only PSA fully supports PSA accelerators and secure element integration.
|
||||
* Only PSA supports isolating cryptographic material in a secure service.
|
||||
* The legacy API has features that are not present (yet) in PSA, notably parsing and formatting asymmetric keys.
|
||||
|
||||
The legacy API can partially leverage PSA features via `MBEDTLS_USE_PSA_CRYPTO`, but this has limited scope.
|
||||
|
||||
In addition, many applications cannot be migrated in a single go. For large projects, it is impractical to rewrite a significant part of the code all at once. (For example, Mbed TLS itself will have taken more than 6 years to transition.) Projects that use one or more library in addition to Mbed TLS must follow the evolution of these libraries, each of which might have its own pace.
|
||||
|
||||
### Where mixing happens
|
||||
|
||||
Mbed TLS can be, and normally is, built with support for both APIs. Therefore no special effort is necessary to allow an application to use both APIs.
|
||||
|
||||
Special effort is necessary to use both APIs as part of the implementation of the same feature. From an informal analysis of typical application requirements, we identify four parts of the use of cryptography which can be provided by different APIs:
|
||||
|
||||
* Metadata manipulation: parsing and producing encrypted or signed files, finding mutually supported algorithms in a network protocol negotiation, etc.
|
||||
* Key management: parsing, generating, deriving and formatting cryptographic keys.
|
||||
* Data manipulation other than keys. In practice, most data formats within the scope of the legacy crypto APIs are trivial (ciphertexts, hashes, MACs, shared secrets). The one exception is ECDSA signatures.
|
||||
* Cryptographic operations: hash, sign, encrypt, etc.
|
||||
|
||||
From this, we deduce the following requirements:
|
||||
|
||||
* Convert between PSA and legacy metadata.
|
||||
* Creating a key with the legacy API and consuming it in the PSA API.
|
||||
* Creating a key with the PSA API and consuming it in the legacy API.
|
||||
* Manipulating data formats, other than keys, where the PSA API is lacking.
|
||||
|
||||
### Scope limitations
|
||||
|
||||
The goal of this document is to bridge the legacy API and the PSA API. The goal is not to provide a PSA way to do everything that is currently possible with the legacy API. The PSA API is less flexible in some regards, and extending it is out of scope in the present study.
|
||||
|
||||
With respect to the legacy API, we do not consider functionality of low-level modules for individual algorithms. Our focus is on applications that use high-level legacy crypto modules (md, cipher, pk) and need to combine that with uses of the PSA APIs.
|
||||
|
||||
## Gap analysis
|
||||
|
||||
The document [“Transitioning to the PSA API”](../../psa-transition.md) enumerates the public header files in Mbed TLS 3.4 and the API elements (especially enums and functions) that they provide, listing PSA equivalents where they exist. There are gaps in two cases:
|
||||
|
||||
* Where the PSA equivalents do not provide the same functionality. A typical example is parsing and formatting asymmetric keys.
|
||||
* To convert between data representations used by legacy APIs and data representations used by PSA APIs.
|
||||
|
||||
Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap analysis on two topics: metadata and keys. This chapter explores the gaps in each family of cryptographic mechanisms.
|
||||
|
||||
### Generic metadata gaps
|
||||
|
||||
#### Need for error code conversion
|
||||
|
||||
Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use.
|
||||
|
||||
Mbed TLS needs these conversions because it has many functions that expose one API (legacy/API) but are implemented on top of the other API. Most applications would convert legacy and PSA error code to their own error codes, and converting between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` is not particularly helpful for that. Application code might need such conversion functions when implementing an X.509 or TLS callback (returning `MBEDTLS_ERR_xxx`) on top of PSA functions, but this is a very limited use case.
|
||||
|
||||
Conclusion: no need for public error code conversion functions.
|
||||
|
||||
### Hash gap analysis
|
||||
|
||||
Hashes do not involve keys, and involves no nontrivial data format. Therefore the only gap is with metadata, namely specifying a hash algorithm.
|
||||
|
||||
Hashes are often used as building blocks for other mechanisms (HMAC, signatures, key derivation, etc.). Therefore metadata about hashes is relevant not only when calculating hashes, but also when performing many other cryptographic operations.
|
||||
|
||||
Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls_md_type_t`. Such functions exist in Mbed TLS 3.5 (`mbedtls_md_psa_alg_from_type`, `mbedtls_md_type_from_psa_alg`) but they are declared only in private headers.
|
||||
|
||||
### MAC gap analysis
|
||||
|
||||
[TODO]
|
||||
|
||||
### Cipher and AEAD gap analysis
|
||||
|
||||
[TODO]
|
||||
|
||||
### Key derivation gap analysis
|
||||
|
||||
[TODO]
|
||||
|
||||
### Random generation gap analysis
|
||||
|
||||
[TODO]
|
||||
|
||||
### Asymmetric cryptography gap analysis
|
||||
|
||||
#### Asymmetric cryptography metadata
|
||||
|
||||
The legacy API only has generic support for two key types: RSA and ECC, via the pk module. ECC keys can also be further classified according to their curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module.
|
||||
|
||||
An RSA or ECC key can potentially be used for different algorithms in the scope of the pk module:
|
||||
|
||||
* RSA: PKCS#1v1.5 signature, PSS signature, PKCS#1v1.5 encryption, OAEP encryption.
|
||||
* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement (via `mbedtls_pk_ec`).
|
||||
|
||||
ECC keys are also involved in EC-JPAKE, but this happens internally: the EC-JPAKE interface only needs one piece of metadata, namely, to identify a curve.
|
||||
|
||||
Since there is no algorithm that can be used with multiple types, and PSA keys have a policy that (for the most part) limits them to one algorithm, there does not seem to be a need to convert between legacy and PSA asymmetric key types on their own. The useful metadata conversions are:
|
||||
|
||||
* Selecting an **elliptic curve**.
|
||||
|
||||
This means converting between an `mbedtls_ecp_group_id` and a pair of `{psa_ecc_family_t; size_t}`.
|
||||
|
||||
This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_from_psa`, which were introduced into the public API between Mbed TLS 3.5 and 3.6 ([#8664](https://github.com/Mbed-TLS/mbedtls/pull/8664)).
|
||||
|
||||
* Selecting A **DHM group**.
|
||||
|
||||
PSA only supports predefined groups, whereas legacy only supports ad hoc groups. An existing application referring to `MBEDTLS_DHM_RFC7919_FFDHExxx` values would need to refer to `PSA_DH_FAMILY_RFC7919`; an existing application using arbitrary groups cannot migrate to PSA.
|
||||
|
||||
* Simultaneously supporting **a key type and an algorithm**.
|
||||
|
||||
On the legacy side, this is an `mbedtls_pk_type_t` value and more. For ECDSA, the choice between randomized and deterministic is made at compile time. For RSA, the choice of encryption or signature algorithm is made either by configuring the underlying `mbedtls_rsa_context` or when calling the operation function.
|
||||
|
||||
On the PSA side, this is a `psa_key_type_t` value and an algorithm which is normally encoded as policy information in a `psa_key_attributes_t`. The algorithm is also needed in its own right when calling operation functions.
|
||||
|
||||
#### Using a legacy key pair or public key with PSA
|
||||
|
||||
There are several scenarios where an application has a legacy key pair or public key (`mbedtls_pk_context`) and needs to create a PSA key object (`psa_key_id_t`).
|
||||
|
||||
Reasons for first creating a legacy key object, where it's impossible or impractical to directly create a PSA key:
|
||||
|
||||
* A very common case where the input is a legacy key object is parsing. PSA does not (yet) have an equivalent of the `mbedtls_pk_parse_xxx` functions.
|
||||
* The PSA key creation interface is less flexible in some cases. In particular, PSA RSA key generation does not (yet) allow choosing the public exponent.
|
||||
* The pk object may be created by a part of the application (or a third-party library) that hasn't been migrated to the PSA API yet.
|
||||
|
||||
Reasons for needing a PSA key object:
|
||||
|
||||
* Using the key with third-party interface that takes a PSA key identifier as input. (Mbed TLS itself has a few TLS functions that take PSA key identifiers, but as of Mbed TLS 3.5, it is always possible to use a legacy key instead.)
|
||||
* Benefiting from a PSA accelerator, or from PSA's world separation, even without `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority scenario: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.)
|
||||
|
||||
Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partially exists in the form of `mbedtls_pk_wrap_as_opaque`, but it is not fully satisfactory, for reasons that are detailed in “[API to create a PSA key from a PK context](#api-to-create-a-psa-key-from-a-pk-context)” below.
|
||||
|
||||
#### Using a PSA key as a PK context
|
||||
|
||||
There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 and TLS APIs or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents.
|
||||
|
||||
There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it has several limitations:
|
||||
|
||||
* It creates a PK key of type `MBEDTLS_PK_OPAQUE` that wraps the PSA key. This is good enough in some scenarios, but not others. For example, it's ok for pkwrite, because we've upgraded the pkwrite code to handle `MBEDTLS_PK_OPAQUE`. That doesn't help users of third-party libraries that haven't yet been upgraded.
|
||||
* It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object.
|
||||
* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. This is not a priority concern, since we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA. However, this function is useful to use specific PSA keys in X.509/TLS regardless of whether X.509/TLS use the PSA API for all cryptographic operations, so this is a wart in the current API.
|
||||
|
||||
It therefore appears that we need two ways to “convert” a PSA key to PK:
|
||||
|
||||
* Wrapping, which is what `mbedtls_pk_setup_opaque` does. This works for any PSA key but is limited by the key's lifetime and creates a PK object with limited functionality.
|
||||
* Copying, which requires a new function. This requires an exportable key but creates a fully independent, fully functional PK object.
|
||||
|
||||
Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable.
|
||||
|
||||
After some discussion, have not identified anything we want to change in the behavior of `mbedtls_pk_setup_opaque`. We only want to generalize it to non-`MBEDTLS_USE_PSA_CRYPTO` and to document it better.
|
||||
|
||||
#### Signature formats
|
||||
|
||||
The pk module uses signature formats intended for X.509. The PSA module uses the simplest sensible signature format.
|
||||
|
||||
* For RSA, the formats are the same.
|
||||
* For ECDSA, PSA uses a fixed-size concatenation of (r,s), whereas X.509 and pk use an ASN.1 DER encoding of the sequence (r,s).
|
||||
|
||||
Gap: We need APIs to convert between these two formats. The conversion code already exists under the hood, but it's in pieces that can't be called directly.
|
||||
|
||||
There is a design choice here: do we provide conversions functions for ECDSA specifically, or do we provide conversion functions that take an algorithm as argument and just happen to be a no-op with RSA? One factor is plausible extensions. These conversions functions will remain useful in Mbed TLS 4.x and perhaps beyond. We will at least add EdDSA support, and its signature encoding is the fixed-size concatenation (r,s) even in X.509. We may well also add support for some post-quantum signatures, and their concrete format is still uncertain.
|
||||
|
||||
Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. Therefore we are not going to add a generic function at this stage.
|
||||
|
||||
For ECDSA, there are two plausible APIs: follow the ASN.1/X.509 write/parse APIs, or present an ordinary input/output API. The ASN.1 APIs are the way they are to accommodate nested TLV structures. But ECDSA signatures do not appear nested in TLV structures in either TLS (there's just a signature field) or X.509 (the signature is inside a BITSTRING, not directly in a SEQUENCE). So there does not seem to be a need for an ASN.1-like API for the ASN.1 format, just the format conversion itself in a buffer that just contains the signature.
|
||||
|
||||
#### Asymmetric cryptography TODO
|
||||
|
||||
[TODO] Other gaps?
|
||||
|
||||
## New APIs
|
||||
|
||||
This section presents new APIs to implement based on the [gap analysis](#gap-analysis).
|
||||
|
||||
### General notes
|
||||
|
||||
Each action to implement a function entails:
|
||||
|
||||
* Implement the library function.
|
||||
* Document it precisely, including error conditions.
|
||||
* Unit-test it.
|
||||
* Mention it where relevant in the PSA transition guide.
|
||||
|
||||
### Hash APIs
|
||||
|
||||
Based on the [gap analysis](#hash-gap-analysis):
|
||||
|
||||
[ACTION] [#8340](https://github.com/Mbed-TLS/mbedtls/issues/8340) Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`.
|
||||
|
||||
### MAC APIs
|
||||
|
||||
[TODO]
|
||||
|
||||
### Cipher and AEAD APIs
|
||||
|
||||
[TODO]
|
||||
|
||||
### Key derivation APIs
|
||||
|
||||
[TODO]
|
||||
|
||||
### Random generation APIs
|
||||
|
||||
[TODO]
|
||||
|
||||
### Asymmetric cryptography APIs
|
||||
|
||||
#### Asymmetric cryptography metadata APIs
|
||||
|
||||
Based on the [gap analysis](#asymmetric-cryptography-metadata):
|
||||
|
||||
* No further work is needed about RSA specifically. The amount of metadata other than hashes is sufficiently small to be handled in ad hoc ways in applications, and hashes have [their own conversions](#hash-apis).
|
||||
* No further work is needed about ECC specifically. We have just added adequate functions.
|
||||
* No further work is needed about DHM specifically. There is no good way to translate the relevant information.
|
||||
* [OPEN] Is there a decent way to convert between `mbedtls_pk_type_t` plus extra information, and `psa_key_type_t` plus policy information? The two APIs are different in crucial ways, with different splits between key type, policy information and operation algorithm.
|
||||
Thinking so far: there isn't really a nice way to present this conversion. For a specific key, `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_copy_from_psa` do the job.
|
||||
|
||||
#### API to create a PSA key from a PK context
|
||||
|
||||
Based on the [gap analysis](#using-a-legacy-key-pair-or-public-key-with-psa):
|
||||
|
||||
Given an `mbedtls_pk_context`, we want a function that creates a PSA key with the same key material and algorithm. “Same key material” is straightforward, but “same algorithm” is not, because a PK context has incomplete algorithm information. For example, there is no way to distinguish between an RSA key that is intended for signature or for encryption. Between algorithms of the same nature, there is no way to distinguish a key intended for PKCS#1v1.5 and one intended for PKCS#1v2.1 (OAEP/PSS): this is indicated in the underlying RSA context, but the indication there is only a default that can be overridden by calling `mbedtls_pk_{sign,verify}_ext`. Also there is no way to distinguish between `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)` and `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`: in the legacy interface, this is only determined when actually doing a signature/verification operation. Therefore the function that creates the PSA key needs extra information to indicate which algorithm to put in the key's policy.
|
||||
|
||||
When creating a PSA key, apart from the key material, the key is determined by attributes, which fall under three categories:
|
||||
|
||||
* Type and size. These are directly related to the key material and can be deduced from it if the key material is in a structured format, which is the case with an `mbedtls_pk_context` input.
|
||||
* Policy. This includes the chosen algorithm, which as discussed above cannot be fully deduced from the `mbedtls_pk_context` object. Just choosing one algorithm is problematic because it doesn't allow implementation-specific extensions, such as Mbed TLS's enrollment algorithm. The intended usage flags cannot be deduced from the PK context either, but the conversion function could sensibly just enable all the relevant usage flags. Users who want a more restrictive usage can call `psa_copy_key` and `psa_destroy_key` to obtain a PSA key object with a more restrictive usage.
|
||||
* Persistence and location. This is completely orthogonal to the information from the `mbedtls_pk_context` object. It is convenient, but not necessary, for the conversion function to allow customizing these aspects. If it doesn't, users can call the conversion function and then call `psa_copy_key` and `psa_destroy_key` to move the key to its desired location.
|
||||
|
||||
To allow the full flexibility around policies, and make the creation of a persistent key more convenient, the conversion function shall take a `const psa_key_attributes_t *` input, like all other functions that create a PSA key. In addition, there shall be a helper function to populate a `psa_key_attributes_t` with a sensible default. This lets the caller choose a more flexible, or just different usage policy, unlike the default-then-copy approach which only allows restricting the policy.
|
||||
|
||||
This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not bake in the implementation-specific consideration that a PSA key has exactly two algorithms, and also allows the caller to benefit from default for the policy in more cases.
|
||||
|
||||
[ACTION] [#8708](https://github.com/Mbed-TLS/mbedtls/issues/8708) Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`.
|
||||
|
||||
```
|
||||
int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk,
|
||||
psa_key_usage_flags_t usage,
|
||||
psa_key_attributes_t *attributes);
|
||||
int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk,
|
||||
const psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t *key_id);
|
||||
```
|
||||
|
||||
* `mbedtls_pk_get_psa_attributes` does not change the id/lifetime fields of the attributes (which indicate a volatile key by default).
|
||||
* [OPEN] Or should it reset them to 0? Resetting is more convenient for the case where the pk key is a `MBEDTLS_PK_OPAQUE`. But that's an uncommon use case. It's probably less surprising if this function leaves the lifetime-related alone, since its job is to set the type-related and policy-related attributes.
|
||||
* `mbedtls_pk_get_psa_attributes` sets the type and size based on what's in the pk context.
|
||||
* The key type is a key pair if the context contains a private key and the indicated usage is a private-key usage. The key type is a public key if the context only contains a public key, in which case a private-key usage is an error.
|
||||
* `mbedtls_pk_get_psa_attributes` sets the usage flags based on the `usage` parameter. It extends the usage to other usage that is possible:
|
||||
* `EXPORT` and `COPY` are always set.
|
||||
* If `SIGN_{HASH,MESSAGE}` is set then so is `VERIFY_{HASH,MESSAGE}`.
|
||||
* If `DECRYPT` is set then so is `ENCRYPT`.
|
||||
* It is an error if `usage` has more than one flag set, or has a usage that is incompatible with the key type.
|
||||
* `mbedtls_pk_get_psa_attributes` sets the algorithm usage policy based on information in the key object and on `usage`.
|
||||
* For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_PKCS1V15_CRYPT` for an encrypt/decrypt usage.
|
||||
* For an RSA key with the `MBEDTLS_RSA_PKCS_V21` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.)
|
||||
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDSA` with a sign/verify usage, the algorithm policy is `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. In either case, the hash policy is `PSA_ALG_ANY_HASH`.
|
||||
* For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDKEY_DH` with the usage `PSA_KEY_USAGE_DERIVE`, the algorithm is `PSA_ALG_ECDH`.
|
||||
* For a `MBEDTLS_PK_OPAQUE`, this function reads the attributes of the existing PK key and copies them (without overriding the lifetime and key identifier in `attributes`), then applies a public-key restriction if needed.
|
||||
* Public-key restriction: if `usage` is a public-key usage, change the type to the corresponding public-key type, and remove private-key usage flags from the usage flags read from the existing key.
|
||||
* `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key).
|
||||
* The key type can be a public key even if the private key is available.
|
||||
* `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks.
|
||||
* `mbedtls_pk_import_into_psa` does not check that the policy in the attributes is sensible. That's on the user.
|
||||
|
||||
#### API to copy a PSA key to a PK context
|
||||
|
||||
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
|
||||
|
||||
[ACTION] [#8709](https://github.com/Mbed-TLS/mbedtls/issues/8709) Implement `mbedtls_pk_copy_from_psa` as described below.
|
||||
|
||||
```
|
||||
int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id,
|
||||
mbedtls_pk_context *pk);
|
||||
```
|
||||
|
||||
* `pk` must be initialized, but not set up.
|
||||
* It is an error if the key is neither a key pair nor a public key.
|
||||
* It is an error if the key is not exportable.
|
||||
* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse).
|
||||
* Once this function returns, the pk object is completely independent of the PSA key.
|
||||
* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`) if that is a matching operation type (sign/verify, encrypt/decrypt), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`).
|
||||
* For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today.
|
||||
* For an RSA key, the output key will allow both encrypt/decrypt and sign/verify regardless of the original key's policy. The original key's policy determines the output key's padding mode.
|
||||
* The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. Convey this in the documentation.
|
||||
|
||||
#### API to create a PK object that wraps a PSA key
|
||||
|
||||
Based on the [gap analysis](#using-a-psa-key-as-a-pk-context):
|
||||
|
||||
[ACTION] [#8712](https://github.com/Mbed-TLS/mbedtls/issues/8712) Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`.
|
||||
|
||||
[ACTION] [#8710](https://github.com/Mbed-TLS/mbedtls/issues/8710) Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly.
|
||||
|
||||
[OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`?
|
||||
|
||||
#### API to convert between signature formats
|
||||
|
||||
Based on the [gap analysis](#signature-formats):
|
||||
|
||||
[ACTION] [#7765](https://github.com/Mbed-TLS/mbedtls/issues/7765) Implement `mbedtls_ecdsa_raw_to_der` and `mbedtls_ecdsa_der_to_raw` as described below.
|
||||
|
||||
```
|
||||
int mbedtls_ecdsa_raw_to_der(size_t bits,
|
||||
const unsigned char *raw, size_t raw_len,
|
||||
unsigned char *der, size_t der_size, size_t *der_len);
|
||||
int mbedtls_ecdsa_der_to_raw(size_t bits,
|
||||
const unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t raw_size, size_t *raw_len);
|
||||
```
|
||||
|
||||
* These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`.
|
||||
* The input and output buffers can overlap.
|
||||
* The `bits` parameter is necessary in the DER-to-raw direction because the DER format lacks leading zeros, so something else needs to convey the size of (r,s). The `bits` parameter is redundant in the raw-to-DER direction, but we have it anyway because [it helps catch errors](https://github.com/Mbed-TLS/mbedtls/pull/8681#discussion_r1445980971), and it isn't a burden on the caller because the information is readily available in practice.
|
||||
* Should these functions rely on the ASN.1 module? We experimented [calling ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8681), [reimplementing simpler ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8696), and [providing the functions from the ASN.1 module](https://github.com/Mbed-TLS/mbedtls/pull/8703). Providing the functions from the ASN.1 module [won on a compromise of code size and simplicity](https://github.com/Mbed-TLS/mbedtls/issues/7765#issuecomment-1893670015).
|
||||
@@ -1,337 +0,0 @@
|
||||
This document lists current limitations of the PSA Crypto API (as of version
|
||||
1.1) that may impact our ability to (1) use it for all crypto operations in
|
||||
TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that
|
||||
is, goals G1 and G2 in [strategy.md](strategy.md) in the same directory).
|
||||
|
||||
This is supposed to be a complete list, based on a exhaustive review of crypto
|
||||
operations done in TLS and X.509 code, but of course it's still possible that
|
||||
subtle-but-important issues have been missed. The only way to be really sure
|
||||
is, of course, to actually do the migration work.
|
||||
|
||||
Limitations relevant for G1 (performing crypto operations)
|
||||
==========================================================
|
||||
|
||||
Restartable (aka interruptible) ECC operations
|
||||
----------------------------------------------
|
||||
|
||||
Support for interruptible ECDSA sign/verify was added to PSA in Mbed TLS 3.4.
|
||||
However, support for interruptible ECDH is not present yet. Also, PK, X.509 and
|
||||
TLS have not yet been adapted to take advantage of the new PSA APIs. See:
|
||||
- <https://github.com/Mbed-TLS/mbedtls/issues/7292>;
|
||||
- <https://github.com/Mbed-TLS/mbedtls/issues/7293>;
|
||||
- <https://github.com/Mbed-TLS/mbedtls/issues/7294>.
|
||||
|
||||
Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
|
||||
both enabled, some operations that should be restartable are not (ECDH in TLS
|
||||
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
|
||||
--------------------------------------------------
|
||||
|
||||
PSA Crypto has an API for FFDH, but it's not implemented in Mbed TLS yet.
|
||||
(Regarding FFDH, see the next section as well.) See issue [3261][ffdh] on
|
||||
github.
|
||||
|
||||
[ffdh]: https://github.com/Mbed-TLS/mbedtls/issues/3261
|
||||
|
||||
Arbitrary parameters for FFDH
|
||||
-----------------------------
|
||||
|
||||
(See also the first paragraph in the previous section.)
|
||||
|
||||
Currently, the PSA Crypto API can only perform FFDH with a limited set of
|
||||
well-known parameters (some of them defined in the spec, but implementations
|
||||
are free to extend that set).
|
||||
|
||||
TLS 1.2 (and earlier) on the other hand have the server send explicit
|
||||
parameters (P and G) in its ServerKeyExchange message. This has been found to
|
||||
be suboptimal for security, as it is prohibitively hard for the client to
|
||||
verify the strength of these parameters. This led to the development of RFC
|
||||
7919 which allows use of named groups in TLS 1.2 - however as this is only an
|
||||
extension, servers can still send custom parameters if they don't support the
|
||||
extension.
|
||||
|
||||
In TLS 1.3 the situation will be simpler: named groups are the only
|
||||
option, so the current PSA Crypto API is a good match for that. (Not
|
||||
coincidentally, all the groups used by RFC 7919 and TLS 1.3 are included
|
||||
in the PSA specification.)
|
||||
|
||||
There are several options here:
|
||||
|
||||
1. Implement support for custom FFDH parameters in PSA Crypto: this would pose
|
||||
non-trivial API design problem, but most importantly seems backwards, as
|
||||
the crypto community is moving away from custom FFDH parameters. (Could be
|
||||
done any time.)
|
||||
2. Drop the DHE-RSA and DHE-PSK key exchanges in TLS 1.2 when moving to PSA.
|
||||
(For people who want some algorithmic variety in case ECC collapses, FFDH
|
||||
would still be available in TLS 1.3, just not in 1.2.) (Can only be done in
|
||||
4.0 or another major version.)
|
||||
3. Variant of the precedent: only drop client-side support. Server-side is
|
||||
easy to support in terms of API/protocol, as the server picks the
|
||||
parameters: we just need remove the existing `mbedtls_ssl_conf_dh_param_xxx()`
|
||||
APIs and tell people to use `mbedtls_ssl_conf_groups()` instead. (Can only be
|
||||
done in 4.0 or another major version.)
|
||||
4. Implement RFC 7919, support DHE-RSA and DHE-PSK only in conjunction with it
|
||||
when moving to PSA. Server-side would work as above; unfortunately
|
||||
client-side the only option is to offer named groups and break the handshake
|
||||
if the server didn't take on our offer. This is not fully satisfying, but is
|
||||
perhaps the least unsatisfying option in terms of result; it's also probably
|
||||
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
|
||||
------------------
|
||||
|
||||
RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017
|
||||
(previously RFC 3447).
|
||||
|
||||
As standardized, the signature scheme takes several parameters, in addition to
|
||||
the hash algorithm potentially used to hash the message being signed:
|
||||
- a hash algorithm used for the encoding function
|
||||
- a mask generation function
|
||||
- most commonly MGF1, which in turn is parametrized by a hash algorithm
|
||||
- a salt length
|
||||
- a trailer field - the value is fixed to 0xBC by PKCS#1 v2.1, but was left
|
||||
configurable in the original scheme; 0xBC is used everywhere in practice.
|
||||
|
||||
Both the existing `mbedtls_` API and the PSA API support only MGF1 as the
|
||||
generation function (and only 0xBC as the trailer field), but there are
|
||||
discrepancies in handling the salt length and which of the various hash
|
||||
algorithms can differ from each other.
|
||||
|
||||
### API comparison
|
||||
|
||||
- RSA:
|
||||
- signature: `mbedtls_rsa_rsassa_pss_sign()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: always using the maximum legal value
|
||||
- signature: `mbedtls_rsa_rsassa_pss_sign_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: specified explicitly
|
||||
- verification: `mbedtls_rsassa_pss_verify()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash (from context, or argument = message hash)
|
||||
- salt length: any valid length accepted
|
||||
- verification: `mbedtls_rsassa_pss_verify_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash from dedicated argument
|
||||
- expected salt length: specified explicitly, can specify "ANY"
|
||||
- PK:
|
||||
- signature: not supported
|
||||
- verification: `mbedtls_pk_verify_ext()`
|
||||
- message hashed externally
|
||||
- encoding hash = MGF1 hash, specified explicitly
|
||||
- expected salt length: specified explicitly, can specify "ANY"
|
||||
- PSA:
|
||||
- algorithm specification:
|
||||
- hash alg used for message hashing, encoding and MGF1
|
||||
- salt length can be either "standard" (<= hashlen, see note) or "any"
|
||||
- signature generation:
|
||||
- salt length: always <= hashlen (see note) and random salt
|
||||
- verification:
|
||||
- salt length: either <= hashlen (see note), or any depending on algorithm
|
||||
|
||||
Note: above, "<= hashlen" means that hashlen is used if possible, but if it
|
||||
doesn't fit because the key is too short, then the maximum length that fits is
|
||||
used.
|
||||
|
||||
The RSA/PK API is in principle more flexible than the PSA Crypto API. The
|
||||
following sub-sections study whether and how this matters in practice.
|
||||
|
||||
### Use in X.509
|
||||
|
||||
RFC 4055 Section 3.1 defines the encoding of RSA-PSS that's used in X.509.
|
||||
It allows independently specifying the message hash (also used for encoding
|
||||
hash), the MGF (and its hash if MGF1 is used), and the salt length (plus an
|
||||
extra parameter "trailer field" that doesn't vary in practice"). These can be
|
||||
encoded as part of the key, and of the signature. If both encoding are
|
||||
presents, all values must match except possibly for the salt length, where the
|
||||
value from the signature parameters is used.
|
||||
|
||||
In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various
|
||||
objects (certificates, CRLs, CSRs). During parsing, the following properties
|
||||
are enforced:
|
||||
- the extra "trailer field" parameter must have its default value
|
||||
- the mask generation function is MGF1
|
||||
- encoding hash = message hashing algorithm (may differ from MGF1 hash)
|
||||
|
||||
When it comes to cryptographic operations, only two things are supported:
|
||||
- verifying the signature on a certificate from its parent;
|
||||
- verifying the signature on a CRL from the issuing CA.
|
||||
|
||||
The verification is done using `mbedtls_pk_verify_ext()`.
|
||||
|
||||
Note: since X.509 parsing ensures that message hash = encoding hash, and
|
||||
`mbedtls_pk_verify_ext()` uses encoding hash = mgf1 hash, it looks like all
|
||||
three hash algorithms must be equal, which would be good news as it would
|
||||
match a limitation of the PSA API.
|
||||
|
||||
It is unclear what parameters people use in practice. It looks like by default
|
||||
OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f).
|
||||
The `certtool` command provided by GnuTLS seems to be picking saltlen = hashlen
|
||||
by default (tested with GnuTLS 3.6.13). FIPS 186-4 requires 0 <= saltlen <=
|
||||
hashlen.
|
||||
|
||||
### Use in TLS
|
||||
|
||||
In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509.
|
||||
|
||||
In TLS 1.3, RSA-PSS signatures can be used directly in the protocol (in
|
||||
addition to indirect use via X.509). It has two sets of three signature
|
||||
algorithm identifiers (for SHA-256, SHA-384 and SHA-512), depending of what
|
||||
the OID of the public key is (rsaEncryption or RSASSA-PSS).
|
||||
|
||||
In both cases, it specifies that:
|
||||
- the mask generation function is MGF1
|
||||
- all three hashes are equal
|
||||
- the length of the salt MUST be equal to the length of the digest algorithm
|
||||
|
||||
When signing, the salt length picked by PSA is the one required by TLS 1.3
|
||||
(unless the key is unreasonably small).
|
||||
|
||||
When verifying signatures, PSA will by default enforce the salt len is the one
|
||||
required by TLS 1.3.
|
||||
|
||||
### Current testing - X509
|
||||
|
||||
All test files use the default trailer field of 0xBC, as enforced by our
|
||||
parser. (There's a negative test for that using the
|
||||
`x509_parse_rsassa_pss_params` test function and hex data.)
|
||||
|
||||
Files with "bad" in the name are expected to be invalid and rejected in tests.
|
||||
|
||||
**Test certificates:**
|
||||
|
||||
server9-bad-mgfhash.crt (announcing mgf1(sha224), signed with another mgf)
|
||||
Hash Algorithm: sha256
|
||||
Mask Algorithm: mgf1 with sha224
|
||||
Salt Length: 0xDE
|
||||
server9-bad-saltlen.crt (announcing saltlen = 0xDE, signed with another len)
|
||||
Hash Algorithm: sha256
|
||||
Mask Algorithm: mgf1 with sha256
|
||||
Salt Length: 0xDE
|
||||
server9-badsign.crt (one bit flipped in the signature)
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0xEA
|
||||
server9-defaults.crt
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0x14 (default)
|
||||
server9-sha224.crt
|
||||
Hash Algorithm: sha224
|
||||
Mask Algorithm: mgf1 with sha224
|
||||
Salt Length: 0xE2
|
||||
server9-sha256.crt
|
||||
Hash Algorithm: sha256
|
||||
Mask Algorithm: mgf1 with sha256
|
||||
Salt Length: 0xDE
|
||||
server9-sha384.crt
|
||||
Hash Algorithm: sha384
|
||||
Mask Algorithm: mgf1 with sha384
|
||||
Salt Length: 0xCE
|
||||
server9-sha512.crt
|
||||
Hash Algorithm: sha512
|
||||
Mask Algorithm: mgf1 with sha512
|
||||
Salt Length: 0xBE
|
||||
server9-with-ca.crt
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0xEA
|
||||
server9.crt
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0xEA
|
||||
|
||||
These certificates are signed with a 2048-bit key. It appears that they are
|
||||
all using saltlen = keylen - hashlen - 2, except for server9-defaults which is
|
||||
using saltlen = hashlen.
|
||||
|
||||
**Test CRLs:**
|
||||
|
||||
crl-rsa-pss-sha1-badsign.pem
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0xEA
|
||||
crl-rsa-pss-sha1.pem
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0xEA
|
||||
crl-rsa-pss-sha224.pem
|
||||
Hash Algorithm: sha224
|
||||
Mask Algorithm: mgf1 with sha224
|
||||
Salt Length: 0xE2
|
||||
crl-rsa-pss-sha256.pem
|
||||
Hash Algorithm: sha256
|
||||
Mask Algorithm: mgf1 with sha256
|
||||
Salt Length: 0xDE
|
||||
crl-rsa-pss-sha384.pem
|
||||
Hash Algorithm: sha384
|
||||
Mask Algorithm: mgf1 with sha384
|
||||
Salt Length: 0xCE
|
||||
crl-rsa-pss-sha512.pem
|
||||
Hash Algorithm: sha512
|
||||
Mask Algorithm: mgf1 with sha512
|
||||
Salt Length: 0xBE
|
||||
|
||||
These CRLs are signed with a 2048-bit key. It appears that they are
|
||||
all using saltlen = keylen - hashlen - 2.
|
||||
|
||||
**Test CSRs:**
|
||||
|
||||
server9.req.sha1
|
||||
Hash Algorithm: sha1 (default)
|
||||
Mask Algorithm: mgf1 with sha1 (default)
|
||||
Salt Length: 0x6A
|
||||
server9.req.sha224
|
||||
Hash Algorithm: sha224
|
||||
Mask Algorithm: mgf1 with sha224
|
||||
Salt Length: 0x62
|
||||
server9.req.sha256
|
||||
Hash Algorithm: sha256
|
||||
Mask Algorithm: mgf1 with sha256
|
||||
Salt Length: 0x5E
|
||||
server9.req.sha384
|
||||
Hash Algorithm: sha384
|
||||
Mask Algorithm: mgf1 with sha384
|
||||
Salt Length: 0x4E
|
||||
server9.req.sha512
|
||||
Hash Algorithm: sha512
|
||||
Mask Algorithm: mgf1 with sha512
|
||||
Salt Length: 0x3E
|
||||
|
||||
These CSRs are signed with a 2048-bit key. It appears that they are
|
||||
all using saltlen = keylen - hashlen - 2.
|
||||
|
||||
### Possible courses of action
|
||||
|
||||
There's no question about what to do with TLS (any version); the only question
|
||||
is about X.509 signature verification. Options include:
|
||||
|
||||
1. Doing all verifications with `PSA_ALG_RSA_PSS_ANY_SALT` - while this
|
||||
wouldn't cause a concrete security issue, this would be non-compliant.
|
||||
2. Doing verifications with `PSA_ALG_RSA_PSS` when we're lucky and the encoded
|
||||
saltlen happens to match hashlen, and falling back to `ANY_SALT` otherwise.
|
||||
Same issue as with the previous point, except more contained.
|
||||
3. Reject all certificates with saltlen != hashlen. This includes all
|
||||
certificates generated with OpenSSL using the default parameters, so it's
|
||||
probably not acceptable.
|
||||
4. Request an extension to the PSA Crypto API and use one of the above options
|
||||
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)
|
||||
============================================================
|
||||
|
||||
Currently none.
|
||||
@@ -1,486 +0,0 @@
|
||||
This document explains the strategy that was used so far in starting the
|
||||
migration to PSA Crypto and mentions future perspectives and open questions.
|
||||
|
||||
Goals
|
||||
=====
|
||||
|
||||
Several benefits are expected from migrating to PSA Crypto:
|
||||
|
||||
G1. Use PSA Crypto drivers when available.
|
||||
G2. Allow isolation of long-term secrets (for example, private keys).
|
||||
G3. Allow isolation of short-term secrets (for example, TLS session keys).
|
||||
G4. Have a clean, unified API for Crypto (retire the legacy API).
|
||||
G5. Code size: compile out our implementation when a driver is available.
|
||||
|
||||
As of Mbed TLS 3.2, most of (G1) and all of (G2) is implemented when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application
|
||||
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 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.
|
||||
- `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config),
|
||||
controls usage of PSA Crypto APIs to perform operations in X.509 and TLS
|
||||
(G1 above), as well as the availability of some new APIs (G2 above).
|
||||
- `PSA_CRYPTO_CONFIG` - disabled by default, supports builds with drivers and
|
||||
without the corresponding software implementation (G5 above).
|
||||
|
||||
The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
|
||||
are:
|
||||
- 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
|
||||
`psa_crypto_init()` before TLS/X.509 uses PSA functions. (This prevents us
|
||||
from even enabling the option by default.)
|
||||
- `MBEDTLS_PSA_CRYPTO_C` has a hard dependency on `MBEDTLS_ENTROPY_C ||
|
||||
MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's
|
||||
currently possible to compile TLS and X.509 without any of the options.
|
||||
Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
|
||||
out of the box on all platforms, and even less
|
||||
`MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG
|
||||
function.
|
||||
|
||||
The downside of this approach is that until we are able to make
|
||||
`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
|
||||
two versions of some parts of the code: one using PSA, the other using the
|
||||
legacy APIs. However, see next section for strategies that can lower that
|
||||
cost. The rest of this section explains the reasons for the
|
||||
incompatibilities mentioned above.
|
||||
|
||||
At the time of writing (early 2022) it is unclear what could be done about the
|
||||
backward compatibility issues, and in particular if the cost of implementing
|
||||
solutions to these problems would be higher or lower than the cost of
|
||||
maintaining dual code paths until the next major version. (Note: these
|
||||
solutions would probably also solve other problems at the same time.)
|
||||
|
||||
### `MBEDTLS_ECP_RESTARTABLE`
|
||||
|
||||
Currently this option controls not only the presence of restartable APIs in
|
||||
the crypto library, but also their use in the TLS and X.509 layers. Since PSA
|
||||
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.
|
||||
|
||||
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 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
|
||||
|
||||
1. Existing applications may not be calling `psa_crypto_init()` before using
|
||||
TLS, X.509 or PK. We can try to work around that by calling (the relevant
|
||||
part of) it ourselves under the hood as needed, but that would likely require
|
||||
splitting init between the parts that can fail and the parts that can't (see
|
||||
<https://github.com/ARM-software/psa-crypto-api/pull/536> for that).
|
||||
2. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
|
||||
configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
|
||||
auto-enable the latter, as it won't build or work out of the box on all
|
||||
platforms. There are two kinds of things we'd need to do if we want to work
|
||||
around that:
|
||||
1. Make it possible to enable the parts of PSA Crypto that don't require an
|
||||
RNG (typically, public key operations, symmetric crypto, some key
|
||||
management functions (destroy etc)) in configurations that don't have
|
||||
`ENTROPY_C`. This requires going through the PSA code base to adjust
|
||||
dependencies. Risk: there may be annoying dependencies, some of which may be
|
||||
surprising.
|
||||
2. For operations that require an RNG, provide an alternative function
|
||||
accepting an explicit `f_rng` parameter (see #5238), that would be
|
||||
available in entropy-less builds. (Then code using those functions still needs
|
||||
to have one version using it, for entropy-less builds, and one version using
|
||||
the standard function, for driver support in build with entropy.)
|
||||
|
||||
See <https://github.com/Mbed-TLS/mbedtls/issues/5156>.
|
||||
|
||||
Taking advantage of the existing abstractions layers - or not
|
||||
=============================================================
|
||||
|
||||
The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
|
||||
algorithm-agnostic APIs for a class of algorithms:
|
||||
|
||||
- MD for messages digests aka hashes (including HMAC)
|
||||
- Cipher for symmetric ciphers (included AEAD)
|
||||
- PK for asymmetric (aka public-key) cryptography (excluding key exchange)
|
||||
|
||||
Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
|
||||
|
||||
These abstraction layers typically provide, in addition to the API for crypto
|
||||
operations, types and numerical identifiers for algorithms (for
|
||||
example `mbedtls_cipher_mode_t` and its values). The
|
||||
current strategy is to keep using those identifiers in most of the code, in
|
||||
particular in existing structures and public APIs, even when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
|
||||
above, and is only potentially relevant for G4.)
|
||||
|
||||
The are multiple strategies that can be used regarding the place of those
|
||||
layers in the migration to PSA.
|
||||
|
||||
Silently call to PSA from the abstraction layer
|
||||
-----------------------------------------------
|
||||
|
||||
- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
|
||||
functions in the abstraction layer, that calls PSA instead of the legacy
|
||||
crypto API.
|
||||
- Upside: changes contained to a single place, no need to change TLS or X.509
|
||||
code anywhere.
|
||||
- Downside: tricky to implement if the PSA implementation is currently done on
|
||||
top of that layer (dependency loop).
|
||||
|
||||
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.
|
||||
|
||||
This strategy will probably be used for some time for the PK layer, while we
|
||||
figure out what the future of that layer is: parts of it (parse/write, ECDSA
|
||||
signatures in the format that X.509 & TLS want) are not covered by PSA, so
|
||||
they will need to keep existing in some way. (Also, the PK layer is a good
|
||||
place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
|
||||
part is not covered by PSA yet, if we decide to do that.)
|
||||
|
||||
Replace calls for each operation
|
||||
--------------------------------
|
||||
|
||||
- For every operation that's done through this layer in TLS or X.509, just
|
||||
replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
|
||||
- Upside: conceptually simple, and if the PSA implementation is currently done
|
||||
on top of that layer, avoids concerns about dependency loops.
|
||||
- Upside: opens the door to building TLS/X.509 without that layer, saving some
|
||||
code size.
|
||||
- Downside: TLS/X.509 code has to be done for each operation.
|
||||
|
||||
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
|
||||
--------------------------------------------
|
||||
|
||||
- Provide a new way to set up a context that causes operations on that context
|
||||
to be done via PSA.
|
||||
- Upside: changes mostly contained in one place, TLS/X.509 code only needs to
|
||||
be changed when setting up the context, but not when using it. In
|
||||
particular, no changes to/duplication of existing public APIs that expect a
|
||||
key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
|
||||
- Upside: avoids dependency loop when PSA implemented on top of that layer.
|
||||
- Downside: when the context is typically set up by the application, requires
|
||||
changes in application code.
|
||||
|
||||
This strategy is not useful when no context is used, for example with the
|
||||
one-shot function `mbedtls_md()`.
|
||||
|
||||
There are two variants of this strategy: one where using the new setup
|
||||
function also allows for key isolation (the key is only held by PSA,
|
||||
supporting both G1 and G2 in that area), and one without isolation (the key is
|
||||
still stored outside of PSA most of the time, supporting only G1).
|
||||
|
||||
This strategy, with support for key isolation, is currently (early 2022) used for
|
||||
private-key operations in the PK layer - see `mbedtls_pk_setup_opaque()`. This
|
||||
allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to
|
||||
the TLS/X.509 code, but a contained change in the application.
|
||||
|
||||
This strategy, without key isolation, was also previously used (until 3.1
|
||||
included) in the Cipher layer - see `mbedtls_cipher_setup_psa()`. This allowed
|
||||
use of PSA for cipher operations in TLS with no change to the application
|
||||
code, and a contained change in TLS code. (It only supported a subset of
|
||||
ciphers.)
|
||||
|
||||
Note: for private key operations in the PK layer, both the "silent" and the
|
||||
"opt-in" strategy can apply, and can complement each other, as one provides
|
||||
support for key isolation, but at the (unavoidable) code of change in
|
||||
application code, while the other requires no application change to get
|
||||
support for drivers, but fails to provide isolation support.
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
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, 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
|
||||
==================================================================
|
||||
|
||||
This section presents a plan towards G5: save code size by compiling out our
|
||||
software implementation when a driver is available.
|
||||
|
||||
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:
|
||||
|
||||
a. the library to build in a reasonably-complete configuration,
|
||||
b. with all tests passing,
|
||||
c. and no more tests skipped than the same configuration with software
|
||||
implementation.
|
||||
|
||||
Criterion (c) ensures not only test coverage, but that driver-based builds are
|
||||
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 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;
|
||||
this needs to be done in the library (for crypto operations and data) and
|
||||
tests.
|
||||
|
||||
Note: the first two steps enable use of drivers, but not by themselves removal
|
||||
of the software implementation.
|
||||
|
||||
Note: the fact that step 1 is not achieved for all of libmbedcrypto (see
|
||||
below) is the reason why criterion (a) has "a reasonably-complete
|
||||
configuration", to allow working around internal crypto dependencies when
|
||||
working on other parts such as X.509 and TLS - for example, a configuration
|
||||
without RSA PKCS#1 v2.1 still allows reasonable use of X.509 and TLS.
|
||||
|
||||
Note: this is a conceptual division that will sometimes translate to how the
|
||||
work is divided into PRs, sometimes not. For example, in situations where it's
|
||||
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 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 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.
|
||||
- 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:
|
||||
- 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:**
|
||||
|
||||
The most satisfying situation here is when we can just use the PSA Crypto API
|
||||
for information management as well. However sometimes it may not be
|
||||
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`).
|
||||
|
||||
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:**
|
||||
|
||||
There are currently two (complementary) ways for crypto-using code to check if a
|
||||
particular algorithm is supported: using `MBEDTLS_xxx` macros, and using
|
||||
`PSA_WANT_xxx` macros. For example, PSA-based code that want to use SHA-256
|
||||
will check for `PSA_WANT_ALG_SHA_256`, while legacy-based code that wants to
|
||||
use SHA-256 will check for `MBEDTLS_SHA256_C` if using the `mbedtls_sha256`
|
||||
API, or for `MBEDTLS_MD_C && MBEDTLS_SHA256_C` if using the `mbedtls_md` API.
|
||||
|
||||
Code that obeys `MBEDTLS_USE_PSA_CRYPTO` will want to use one of the two
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
**Note on testing**
|
||||
|
||||
Since supporting driver-only builds is not about adding features, but about
|
||||
supporting existing features in new types of builds, testing will not involve
|
||||
adding cases to the test suites, but instead adding new components in `all.sh`
|
||||
that build and run tests in newly-supported configurations. For example, if
|
||||
we're making some part of the library work with hashes provided only by
|
||||
drivers when `MBEDTLS_USE_PSA_CRYPTO` is defined, there should be a place in
|
||||
`all.sh` that builds and run tests in such a configuration.
|
||||
|
||||
There is however a risk, especially in step 3 where we change how dependencies
|
||||
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:
|
||||
|
||||
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
|
||||
==================================
|
||||
|
||||
This section briefly introduces questions and possible plans towards G4,
|
||||
mainly as they relate to choices in previous stages.
|
||||
|
||||
The role of the PK/Cipher/MD APIs in user migration
|
||||
---------------------------------------------------
|
||||
|
||||
We're currently taking advantage of the existing PK layer in order
|
||||
to reduce the number of places where library code needs to be changed. It's
|
||||
only natural to consider using the same strategy (with the PK, MD and Cipher
|
||||
layers) for facilitating migration of application code.
|
||||
|
||||
Note: a necessary first step for that would be to make sure PSA is no longer
|
||||
implemented of top of the concerned layers
|
||||
|
||||
### Zero-cost compatibility layer?
|
||||
|
||||
The most favourable case is if we can have a zero-cost abstraction (no
|
||||
runtime, RAM usage or code size penalty), for example just a bunch of
|
||||
`#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent.
|
||||
|
||||
Unfortunately that's unlikely to fully work. For example, the MD layer uses the
|
||||
same context type for hashes and HMACs, while the PSA API (rightfully) has
|
||||
distinct operation types. Similarly, the Cipher layer uses the same context
|
||||
type for unauthenticated and AEAD ciphers, which again the PSA API
|
||||
distinguishes.
|
||||
|
||||
It is unclear how much value, if any, a zero-cost compatibility layer that's
|
||||
incomplete (for example, for MD covering only hashes, or for Cipher covering
|
||||
only AEAD) or differs significantly from the existing API (for example,
|
||||
introducing new context types) would provide to users.
|
||||
|
||||
### Low-cost compatibility layers?
|
||||
|
||||
Another possibility is to keep most or all of the existing API for the PK, MD
|
||||
and Cipher layers, implemented on top of PSA, aiming for the lowest possible
|
||||
cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
|
||||
of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
|
||||
would initialize the correct part, and the rest of the functions be simple
|
||||
wrappers around PSA functions. This would vastly reduce the complexity of the
|
||||
layers compared to the existing (no need to dispatch through function
|
||||
pointers, just call the corresponding PSA API).
|
||||
|
||||
Since this would still represent a non-zero cost, not only in terms of code
|
||||
size, but also in terms of maintenance (testing, etc.) this would probably
|
||||
be a temporary solution: for example keep the compatibility layers in 4.0 (and
|
||||
make them optional), but remove them in 5.0.
|
||||
|
||||
Again, this provides the most value to users if we can manage to keep the
|
||||
existing API unchanged. Their might be conflicts between this goal and that of
|
||||
reducing the cost, and judgment calls may need to be made.
|
||||
|
||||
Note: when it comes to holding public keys in the PK layer, depending on how
|
||||
the rest of the code is structured, it may be worth holding the key data in
|
||||
memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
|
||||
slot only when needed (see current `ecdsa_verify_wrap` when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is defined) For example, when parsing a large
|
||||
number, N, of X.509 certificates (for example the list of trusted roots), it
|
||||
might be undesirable to use N PSA key slots for their public keys as long as
|
||||
the certs are loaded. OTOH, this could also be addressed by merging the "X.509
|
||||
parsing on-demand" (#2478), and then the public key data would be held as
|
||||
bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
|
||||
when it's actually used.
|
||||
|
||||
Note: the PK layer actually consists of two relatively distinct parts: crypto
|
||||
operations, which will be covered by PSA, and parsing/writing (exporting)
|
||||
from/to various formats, which is currently not fully covered by the PSA
|
||||
Crypto API.
|
||||
|
||||
### Algorithm identifiers and other identifiers
|
||||
|
||||
It should be easy to provide the user with a bunch of `#define`s for algorithm
|
||||
identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
|
||||
those would be in the MD, Cipher and PK compatibility layers mentioned above,
|
||||
but there might be some in other modules that may be worth considering, for
|
||||
example identifiers for elliptic curves.
|
||||
|
||||
### Lower layers
|
||||
|
||||
Generally speaking, we would retire all of the low-level, non-generic modules,
|
||||
such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
|
||||
compatibility APIs for them. People would be encouraged to switch to the PSA
|
||||
API. (The compatibility implementation of the existing PK, MD, Cipher APIs
|
||||
would mostly benefit people who already used those generic APis rather than
|
||||
the low-level, alg-specific ones.)
|
||||
|
||||
### APIs in TLS and X.509
|
||||
|
||||
Public APIs in TLS and X.509 may be affected by the migration in at least two
|
||||
ways:
|
||||
|
||||
1. APIs that rely on a legacy `mbedtls_` crypto type: for example
|
||||
`mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
|
||||
associated) private key. Currently the private key is passed as a
|
||||
`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
|
||||
Since some users would probably still be using the compatibility PK layer, it
|
||||
would need a way to easily extract the PSA key ID from the PK context.
|
||||
|
||||
2. APIs the accept list of identifiers: for example
|
||||
`mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
|
||||
could be changed to accept a list of pairs (`psa_ecc_family_t`, size) but we
|
||||
should probably take this opportunity to move to a identifier independent from
|
||||
the underlying crypto implementation and use TLS-specific identifiers instead
|
||||
(based on IANA values or custom enums), as is currently done in the new
|
||||
`mbedtls_ssl_conf_groups()` API, see #4859).
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
An question that needs careful consideration when we come around to removing
|
||||
the low-level crypto APIs and making PK, MD and Cipher optional compatibility
|
||||
layers is to be sure to preserve testing quality. A lot of the existing test
|
||||
cases use the low level crypto APIs; we would need to either keep using that
|
||||
API for tests, or manually migrate tests to the PSA Crypto API. Perhaps a
|
||||
combination of both, perhaps evolving gradually over time.
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# Purpose
|
||||
#
|
||||
# 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.)
|
||||
# - 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
|
||||
|
||||
# list mbedtls_ symbols of a given type in a static library
|
||||
syms() {
|
||||
TYPE="$1"
|
||||
FILE="$2"
|
||||
|
||||
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=$(get_file_with_extension "library/${NAME}")
|
||||
PREF="${CONFIG}-$NAME"
|
||||
|
||||
syms '[TRrD]' $FILE > ${PREF}-defined
|
||||
syms U $FILE > ${PREF}-unresolved
|
||||
|
||||
diff ${PREF}-defined ${PREF}-unresolved \
|
||||
| sed -n 's/^> //p' > ${PREF}-external
|
||||
sed 's/mbedtls_\([^_]*\).*/\1/' ${PREF}-external \
|
||||
| uniq -c | sort -rn > ${PREF}-modules
|
||||
|
||||
rm ${PREF}-defined ${PREF}-unresolved
|
||||
}
|
||||
|
||||
CONFIG="${1:-unknown}"
|
||||
|
||||
# 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,99 +0,0 @@
|
||||
Testing strategy for `MBEDTLS_USE_PSA_CRYPTO`
|
||||
=============================================
|
||||
|
||||
This document records the testing strategy used so far in implementing
|
||||
`MBEDTLS_USE_PSA_CRYPTO`.
|
||||
|
||||
|
||||
General considerations
|
||||
----------------------
|
||||
|
||||
There needs to be at least one build in `all.sh` that enables
|
||||
`MBEDTLS_USE_PSA_CRYPTO` and runs the full battery of tests; currently that's
|
||||
ensured by the fact that `scripts/config.py full` enables
|
||||
`MBEDTLS_USE_PSA_CRYPTO`. There needs to be at least one build with
|
||||
`MBEDTLS_USE_PSA_CRYPTO` disabled (as long as it's optional); currently that's
|
||||
ensured by the fact that it's disabled in the default config.
|
||||
|
||||
Generally, code review is enough to ensure that PSA APIs are indeed used where
|
||||
they should be when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
However, when it comes to TLS, we also have the option of using debug messages
|
||||
to confirm which code path is taken. This is generally unnecessary, except when
|
||||
a decision is made at run-time about whether to use the PSA or legacy code
|
||||
path. (For example, for record protection, previously (until 3.1), some ciphers were supported
|
||||
via PSA while some others weren't, with a run-time fallback. In this case, it's
|
||||
good to have a debug message checked by the test case to confirm that the
|
||||
right decision was made at run-time, i. e. that we didn't use the fallback for
|
||||
ciphers that are supposed to be supported.)
|
||||
|
||||
|
||||
New APIs meant for application use
|
||||
----------------------------------
|
||||
|
||||
For example, `mbedtls_pk_setup_opaque()` is meant to be used by applications
|
||||
in order to create PK contexts that can then be passed to existing TLS and
|
||||
X.509 APIs (which remain unchanged).
|
||||
|
||||
In that case, we want:
|
||||
|
||||
- unit testing of the new API and directly-related APIs - for example:
|
||||
- in `test_suite_pk` we have a new test function `pk_psa_utils` that exercises
|
||||
`mbedtls_pk_setup_opaque()` and checks that various utility functions
|
||||
(`mbedtls_pk_get_type()` etc.) work and the functions that are expected to
|
||||
fail (`mbedtls_pk_verify()` etc) return the expected error.
|
||||
- in `test_suite_pk` we modified the existing `pk_psa_sign` test function to
|
||||
check that signature generation works as expected
|
||||
- in `test_suite_pkwrite` we should have a new test function checking that
|
||||
exporting (writing out) the public part of the key works as expected and
|
||||
that exporting the private key fails as expected.
|
||||
- integration testing of the new API with each existing API which should
|
||||
accepts a context created this way - for example:
|
||||
- in `programs/ssl/ssl_client2` a new option `key_opaque` that causes the
|
||||
new API to be used, and one or more tests in `ssl-opt.sh` using that.
|
||||
(We should have the same server-side.)
|
||||
- in `test_suite_x509write` we have a new test function
|
||||
`x509_csr_check_opaque()` checking integration of the new API with the
|
||||
existing `mbedtls_x509write_csr_set_key()`. (And also
|
||||
`mbedtls_x509write_crt_set_issuer_key()` since #5710.)
|
||||
|
||||
For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, testing in
|
||||
`test_suite_ssl` was historically not possible, so we only have testing in
|
||||
`ssl-opt.sh`.
|
||||
|
||||
New APIs meant for internal use
|
||||
-------------------------------
|
||||
|
||||
For example, `mbedtls_cipher_setup_psa()` (no longer used, soon to be
|
||||
deprecated - #5261) was meant to be used by the TLS layer, but probably not
|
||||
directly by applications.
|
||||
|
||||
In that case, we want:
|
||||
|
||||
- unit testing of the new API and directly-related APIs - for example:
|
||||
- in `test_suite_cipher`, the existing test functions `auth_crypt_tv` and
|
||||
`test_vec_crypt` gained a new parameter `use_psa` and corresponding test
|
||||
cases
|
||||
- integration testing:
|
||||
- usually already covered by existing tests for higher-level modules:
|
||||
- for example simple use of `mbedtls_cipher_setup_psa()` in TLS is already
|
||||
covered by running the existing TLS tests in a build with
|
||||
`MBEDTLS_USA_PSA_CRYPTO` enabled
|
||||
- however if use of the new API in higher layers involves more logic that
|
||||
use of the old API, specific integrations test may be required
|
||||
- for example, the logic to fall back from `mbedtls_cipher_setup_psa()` to
|
||||
`mbedtls_cipher_setup()` in TLS is tested by `run_test_psa` in
|
||||
`ssl-opt.sh`.
|
||||
|
||||
Internal changes
|
||||
----------------
|
||||
|
||||
For example, use of PSA to compute the TLS 1.2 PRF.
|
||||
|
||||
Changes in this category rarely require specific testing, as everything should
|
||||
be already be covered by running the existing tests in a build with
|
||||
`MBEDTLS_USE_PSA_CRYPTO` enabled; however we need to make sure the existing
|
||||
test have sufficient coverage, and improve them if necessary.
|
||||
|
||||
However, if additional logic is involved, or there are run-time decisions about
|
||||
whether to use the PSA or legacy code paths, specific tests might be in order.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user