Merge branch 'iotssl-1770' into development_thomas_dee

This commit is contained in:
Hanno Becker 2018-11-02 10:52:49 +00:00
commit 710f203541
309 changed files with 33188 additions and 10041 deletions

View file

@ -38,4 +38,4 @@ Version:
## Question
**Please first check for answers in the [Mbed TLS knowledge Base](https://tls.mbed.org/kb), and preferably file an issue in the [Mbed TLS support forum](https://tls.mbed.org/discussions)**
**Please first check for answers in the [Mbed TLS knowledge Base](https://tls.mbed.org/kb), and preferably file an issue in the [Mbed TLS support forum](https://forums.mbed.com/c/mbed-tls)**

3
.gitignore vendored
View file

@ -21,5 +21,8 @@ massif-*
*.ilk
*.lib
# Python build artifacts:
*.pyc
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
*.dir/

425
.pylint Normal file
View file

@ -0,0 +1,425 @@
[MASTER]
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Use multiple processes to speed up Pylint.
jobs=1
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Pickle collected data for later comparisons.
persistent=yes
# Specify a configuration file.
#rcfile=
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=
[REPORTS]
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio).You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Tells whether to display a full report or only the messages
reports=no
# Activate the evaluation score.
score=yes
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
[SIMILARITIES]
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
# Minimum lines number of a similarity.
min-similarity-lines=4
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=79
# Maximum number of lines in a module
max-module-lines=2000
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[BASIC]
# Naming hint for argument names
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct argument names
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Naming hint for attribute names
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct attribute names
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming hint for function names
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct function names
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for method names
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct method names
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Naming hint for variable names
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct variable names
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in a if statement
max-bool-expr=5
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of statements in function / method body
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[IMPORTS]
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

View file

@ -9,6 +9,7 @@ script:
- tests/scripts/check-generated-files.sh
- tests/scripts/check-doxy-blocks.pl
- tests/scripts/check-names.sh
- tests/scripts/check-files.py
- tests/scripts/doxygen.sh
- cmake -D CMAKE_BUILD_TYPE:String="Check" .
- make

View file

@ -1,5 +1,9 @@
cmake_minimum_required(VERSION 2.6)
project("mbed TLS" C)
if(TEST_CPP)
project("mbed TLS" C CXX)
else()
project("mbed TLS" C)
endif()
option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF)
option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF)
@ -8,8 +12,13 @@ option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
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(MSVC)
if(CMAKE_COMPILER_IS_MSVC)
option(ENABLE_TESTING "Build mbed TLS tests." OFF)
else()
option(ENABLE_TESTING "Build mbed TLS tests." ON)
@ -27,9 +36,27 @@ set(NULL_ENTROPY_WARNING "${WARNING_BORDER}"
"${NULL_ENTROPY_WARN_L3}"
"${WARNING_BORDER}")
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}")
find_package(PythonInterp)
find_package(Perl)
if(PERL_FOUND)
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.pl -f ${CMAKE_CURRENT_SOURCE_DIR}/include/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()
# If NULL Entropy is configured, display an appropriate warning
execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.pl -f ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/config.h get MBEDTLS_TEST_NULL_ENTROPY
RESULT_VARIABLE result)
@ -56,9 +83,37 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
FORCE)
# Create a symbolic link from ${base_name} in the binary directory
# to the corresponding path in the source directory.
function(link_to_source base_name)
# Get OS dependent path to use in `execute_process`
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" link)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}" target)
if (NOT EXISTS ${link})
if (CMAKE_HOST_UNIX)
set(command ln -s ${target} ${link})
else()
if (IS_DIRECTORY ${target})
set(command cmd.exe /c mklink /j ${link} ${target})
else()
set(command cmd.exe /c mklink /h ${link} ${target})
endif()
endif()
execute_process(COMMAND ${command}
RESULT_VARIABLE result
ERROR_VARIABLE output)
if (NOT ${result} EQUAL 0)
message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
endif()
endif()
endfunction(link_to_source)
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
if(CMAKE_COMPILER_IS_GNUCC)
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
@ -77,30 +132,34 @@ if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
endif(CMAKE_COMPILER_IS_GNUCC)
endif(CMAKE_COMPILER_IS_GNU)
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
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 "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -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 "-Werror -fsanitize=memory -O3")
set(CMAKE_C_FLAGS_MEMSANDBG "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
endif(CMAKE_COMPILER_IS_CLANG)
if(MSVC)
if(CMAKE_COMPILER_IS_IAR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts --warnings_are_errors -Ohz")
endif(CMAKE_COMPILER_IS_IAR)
if(CMAKE_COMPILER_IS_MSVC)
# Strictest warnings, and treat as errors
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
endif(MSVC)
endif(CMAKE_COMPILER_IS_MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(LIB_INSTALL_DIR)
@ -164,3 +223,12 @@ if(ENABLE_TESTING)
)
endif(UNIX)
endif()
# 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()

View file

@ -26,38 +26,70 @@ Making a Contribution
1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
1. Mbed TLS is released under the Apache license, and as such, all the added files should include the Apache license header.
Backports
---------
Mbed TLS maintains some legacy branches, which are released as LTS versions. Mbed TLS should follow backwards compatibility rules, to fit with existing users. As such, backporting to these branches should be handled according to the following rules:
1. If the contribution is a new feature or enhancement, no backporting is needed.
1. Bug fixes should be backported to the legacy branches containing these bugs.
1. Changes in the API do not require backporting. If a bug fix introduced a new API, such as new error codes, the bug fix should be implemented differently in the legacy branch.
API/ABI 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.
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.
Where changes to an existing interface are necessary, functions in the public interface which need to be changed, are marked as 'deprecated'. This is done with the preprocessor symbols `MBEDTLS_DEPRECATED_WARNING` and `MBEDTLS_DEPRECATED_REMOVED`. Then, a new function with a new name but similar if not identical behaviour to the original function containing the necessary changes should be created alongside the existing deprecated function.
When a build is made with the deprecation preprocessor symbols defined, a compiler warning will be generated to warn a user that the function will be removed at some point in the future, notifying users that they should change from the older deprecated function to the newer function at their own convenience.
Therefore, no changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. As described above, if a function needs to be changed, a new function needs to be created alongside it, with a new name, and whatever change is necessary, such as a new parameter or the addition of a return value.
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.
2. 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.
3. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be addtional 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/ARMmbed/mbedtls/tree/development) by contributors.
Currently maintained LTS branches are:
It would be highly appreciated if a contribution would be backported to a legacy branch in addition to the [development branch](https://github.com/ARMmbed/mbedtls/tree/development).
At the moment, the legacy branches are:
1. [mbedtls-1.3](https://github.com/ARMmbed/mbedtls/tree/mbedtls-1.3)
1. [mbedtls-2.1](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.1)
2. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
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 an elaborate test suite in `tests/` that initially requires Perl 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.
As mentioned, tests that show the correctness of the feature or bug fix should be added to the pull request, if no such tests exist.
Mbed TLS includes a comprehensive set of test suites in the `tests/` directory that are dynamically generated to produce the actual test source files (e.g. `test_suite_mpi.c`). These files are generated from a `function file` (e.g. `suites/test_suite_mpi.function`) and a `data file` (e.g. `suites/test_suite_mpi.data`). The function file contains the test functions. The data file contains the test cases, specified as parameters that will be passed to the test function.
[A Knowledge Base article describing how to add additional tests is available on the Mbed TLS website](https://tls.mbed.org/kb/development/test_suites).
A 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.
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/ARMmbed/mbedtls/tree/development/tests/git-scripts) prior to pushing your changes, for catching some of the issues as early as possible.
Documentation
-------------
Mbed TLS should be well documented. If documentation is needed, speak out!
Mbed TLS is well documented, but if you think documentation is needed, speak out!
1. All interfaces should be documented through Doxygen. New APIs should introduce Doxygen documentation.
1. Complex parts in the code should include comments.
1. If needed, a Readme file is advised.
1. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
1. A [ChangeLog](https://github.com/ARMmbed/mbedtls/blob/development/ChangeLog) entry should be added for this contribution.
2. Complex parts in the code should include comments.
3. If needed, a Readme file is advised.
4. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
5. A [ChangeLog](https://github.com/ARMmbed/mbedtls/blob/development/ChangeLog) entry should be added for this contribution.

277
ChangeLog
View file

@ -2,6 +2,274 @@ mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS x.x.x branch released xxxx-xx-xx
Security
* Fix overly strict DN comparison when looking for CRLs
belonging to a particular CA. This previously lead to
ignoring CRLs when the CRL's issuer name and the CA's
subject name differed in their string encoding (e.g.,
one using PrintableString and the other UTF8String) or
in the choice of upper and lower case. Reported by
HenrikRosenquistAndersson in #1784.
Features
* Add support for temporarily suspending expensive ECC computations after
some configurable amount of operations, to be used in single-threaded
constrained systems where ECC is time consuming and blocking until
completion cannot be tolerated. This is enabled by
MBEDTLS_ECP_RESTARTABLE at compile time (disabled by default) and
configured by mbedtls_ecp_set_max_ops() at runtime. It applies to new
xxx_restartable functions in ECP, ECDSA, PK and X.509 (CRL not supported
yet), and to existing functions in ECDH and SSL (currently only
implemented client-side, for ECDHE-ECDSA ciphersuites in TLS 1.2,
including client authentication).
* Add support for Arm CPU DSP extensions to accelerate asymmetric key
operations. On CPUs where the extensions are available, they can accelerate
MPI multiplications used in ECC and RSA cryptography. Contributed by
Aurelien Jarno.
Bugfix
* Fix wrong order of freeing in programs/ssl/ssl_server2 example
application leading to a memory leak in case both
MBEDTLS_MEMORY_BUFFER_ALLOC_C and MBEDTLS_MEMORY_BACKTRACE are set.
Fixes #2069.
* Fix a bug in the update function for SSL ticket keys which previously
invalidated keys of a lifetime of less than a 1s. Fixes #1968.
* Fix failure in hmac_drbg in the benchmark sample application, when
MBEDTLS_THREADING_C is defined. Found by TrinityTonic, #1095
* Fix a bug in the record decryption routine ssl_decrypt_buf()
which lead to accepting properly authenticated but improperly
padded records in case of CBC ciphersuites using Encrypt-then-MAC.
* Fix memory leak and freeing without initialization in the example
program programs/x509/cert_write. Fixes #1422.
* Ignore IV in mbedtls_cipher_set_iv() when the cipher mode is MBEDTLS_MODE_ECB
Fix for #1091 raised by ezdevelop
Changes
* Removed support for Yotta as a build tool.
* Add tests for session resumption in DTLS.
* Close a test gap in (D)TLS between the client side and the server side:
test the handling of large packets and small packets on the client side
in the same way as on the server side.
* Change the dtls_client and dtls_server samples to work by default over
IPv6 and optionally by a build option over IPv4.
= mbed TLS 2.13.1 branch released 2018-09-06
API Changes
* Extend the platform module with an abstraction mbedtls_platform_gmtime_r()
whose implementation should behave as a thread-safe version of gmtime().
This allows users to configure such an implementation at compile time when
the target system cannot be deduced automatically, by setting the option
MBEDTLS_PLATFORM_GMTIME_R_ALT. At this stage Mbed TLS is only able to
automatically select implementations for Windows and POSIX C libraries.
Bugfix
* Fix build failures on platforms where only gmtime() is available but
neither gmtime_r() nor gmtime_s() are present. Fixes #1907.
= mbed TLS 2.13.0 branch released 2018-08-31
Security
* Fix an issue in the X.509 module which could lead to a buffer overread
during certificate extensions parsing. In case of receiving malformed
input (extensions length field equal to 0), an illegal read of one byte
beyond the input buffer is made. Found and analyzed by Nathan Crandall.
Features
* Add support for fragmentation of outgoing DTLS handshake messages. This
is controlled by the maximum fragment length as set locally or negotiated
with the peer, as well as by a new per-connection MTU option, set using
mbedtls_ssl_set_mtu().
* Add support for auto-adjustment of MTU to a safe value during the
handshake when flights do not get through (RFC 6347, section 4.1.1.1,
last paragraph).
* Add support for packing multiple records within a single datagram,
enabled by default.
* Add support for buffering out-of-order handshake messages in DTLS.
The maximum amount of RAM used for this can be controlled by the
compile-time constant MBEDTLS_SSL_DTLS_MAX_BUFFERING defined
in mbedtls/config.h.
API Changes
* Add function mbedtls_ssl_set_datagram_packing() to configure
the use of datagram packing (enabled by default).
Bugfix
* Fix a potential memory leak in mbedtls_ssl_setup() function. An allocation
failure in the function could lead to other buffers being leaked.
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
MBEDTLS_ARC4_C and MBEDTLS_CIPHER_NULL_CIPHER weren't also defined. #1890
* Fix a memory leak in ecp_mul_comb() if ecp_precompute_comb() fails.
Fix contributed by Espressif Systems.
* Add ecc extensions only if an ecc based ciphersuite is used.
This improves compliance to RFC 4492, and as a result, solves
interoperability issues with BouncyCastle. Raised by milenamil in #1157.
* Replace printf with mbedtls_printf in the ARIA module. Found by
TrinityTonic in #1908.
* Fix potential use-after-free in mbedtls_ssl_get_max_frag_len()
and mbedtls_ssl_get_record_expansion() after a session reset. Fixes #1941.
* Fix a bug that caused SSL/TLS clients to incorrectly abort the handshake
with TLS versions 1.1 and earlier when the server requested authentication
without providing a list of CAs. This was due to an overly strict bounds
check in parsing the CertificateRequest message,
introduced in Mbed TLS 2.12.0. Fixes #1954.
* Fix a miscalculation of the maximum record expansion in
mbedtls_ssl_get_record_expansion() in case of ChachaPoly ciphersuites,
or CBC ciphersuites in (D)TLS versions 1.1 or higher. Fixes #1913, #1914.
* Fix undefined shifts with negative values in certificates parsing
(found by Catena cyber using oss-fuzz)
* Fix memory leak and free without initialization in pk_encrypt
and pk_decrypt example programs. Reported by Brace Stout. Fixes #1128.
* Remove redundant else statement. Raised by irwir. Fixes #1776.
Changes
* Copy headers preserving timestamps when doing a "make install".
Contributed by xueruini.
* Allow the forward declaration of public structs. Contributed by Dawid
Drozd. Fixes #1215 raised by randombit.
* Improve compatibility with some alternative CCM implementations by using
CCM test vectors from RAM.
* Add support for buffering of out-of-order handshake messages.
* Add warnings to the documentation of the HKDF module to reduce the risk
of misusing the mbedtls_hkdf_extract() and mbedtls_hkdf_expand()
functions. Fixes #1775. Reported by Brian J. Murray.
= mbed TLS 2.12.0 branch released 2018-07-25
Security
* Fix a vulnerability in TLS ciphersuites based on CBC and using SHA-384,
in (D)TLS 1.0 to 1.2, that allowed an active network attacker to
partially recover the plaintext of messages under some conditions by
exploiting timing measurements. With DTLS, the attacker could perform
this recovery by sending many messages in the same connection. With TLS
or if mbedtls_ssl_conf_dtls_badmac_limit() was used, the attack only
worked if the same secret (for example a HTTP Cookie) has been repeatedly
sent over connections manipulated by the attacker. Connections using GCM
or CCM instead of CBC, using hash sizes other than SHA-384, or using
Encrypt-then-Mac (RFC 7366) were not affected. The vulnerability was
caused by a miscalculation (for SHA-384) in a countermeasure to the
original Lucky 13 attack. Found by Kenny Paterson, Eyal Ronen and Adi
Shamir.
* Fix a vulnerability in TLS ciphersuites based on CBC, in (D)TLS 1.0 to
1.2, that allowed a local attacker, able to execute code on the local
machine as well as manipulate network packets, to partially recover the
plaintext of messages under some conditions by using a cache attack
targetting an internal MD/SHA buffer. With TLS or if
mbedtls_ssl_conf_dtls_badmac_limit() was used, the attack only worked if
the same secret (for example a HTTP Cookie) has been repeatedly sent over
connections manipulated by the attacker. Connections using GCM or CCM
instead of CBC or using Encrypt-then-Mac (RFC 7366) were not affected.
Found by Kenny Paterson, Eyal Ronen and Adi Shamir.
* Add a counter-measure against a vulnerability in TLS ciphersuites based
on CBC, in (D)TLS 1.0 to 1.2, that allowed a local attacker, able to
execute code on the local machine as well as manipulate network packets,
to partially recover the plaintext of messages under some conditions (see
previous entry) by using a cache attack targeting the SSL input record
buffer. Connections using GCM or CCM instead of CBC or using
Encrypt-then-Mac (RFC 7366) were not affected. Found by Kenny Paterson,
Eyal Ronen and Adi Shamir.
Features
* Add new crypto primitives from RFC 7539: stream cipher Chacha20, one-time
authenticator Poly1305 and AEAD construct Chacha20-Poly1305. Contributed
by Daniel King.
* Add support for CHACHA20-POLY1305 ciphersuites from RFC 7905.
* Add platform support for the Haiku OS. (https://www.haiku-os.org).
Contributed by Augustin Cavalier.
* Make the receive and transmit buffers independent sizes, for situations
where the outgoing buffer can be fixed at a smaller size than the incoming
buffer, which can save some RAM. If buffer lengths are kept equal, there
is no functional difference. Contributed by Angus Gratton, and also
independently contributed again by Paul Sokolovsky.
* Add support for key wrapping modes based on AES as defined by
NIST SP 800-38F algorithms KW and KWP and by RFC 3394 and RFC 5649.
* Add support for 128-bit keys in CTR_DRBG. Note that using keys shorter
than 256 bits limits the security of generated material to 128 bits.
Bugfix
* Fix the key_app_writer example which was writing a leading zero byte which
was creating an invalid ASN.1 tag. Found by Aryeh R. Fixes #1257.
* Fix compilation error on C++, because of a variable named new.
Found and fixed by Hirotaka Niisato in #1783.
* Fix "no symbols" warning issued by ranlib when building on Mac OS X. Fix
contributed by tabascoeye.
* Clarify documentation for mbedtls_ssl_write() to include 0 as a valid
return value. Found by @davidwu2000. #839
* Fix a memory leak in mbedtls_x509_csr_parse(), found by catenacyber,
Philippe Antoine. Fixes #1623.
* Remove unused headers included in x509.c. Found by Chris Hanson and fixed
by Brendan Shanks. Part of a fix for #992.
* Fix compilation error when MBEDTLS_ARC4_C is disabled and
MBEDTLS_CIPHER_NULL_CIPHER is enabled. Found by TrinityTonic in #1719.
* Added length checks to some TLS parsing functions. Found and fixed by
Philippe Antoine from Catena cyber. #1663.
* Fix the inline assembly for the MPI multiply helper function for i386 and
i386 with SSE2. Found by László Langó. Fixes #1550
* Fix namespacing in header files. Remove the `mbedtls` namespacing in
the `#include` in the header files. Resolves #857
* Fix compiler warning of 'use before initialisation' in
mbedtls_pk_parse_key(). Found by Martin Boye Petersen and fixed by Dawid
Drozd. #1098
* Fix decryption for zero length messages (which contain all padding) when a
CBC based ciphersuite is used together with Encrypt-then-MAC. Previously,
such a message was wrongly reported as an invalid record and therefore lead
to the connection being terminated. Seen most often with OpenSSL using
TLS 1.0. Reported by @kFYatek and by Conor Murphy on the forum. Fix
contributed by Espressif Systems. Fixes #1632
* Fix ssl_client2 example to send application data with 0-length content
when the request_size argument is set to 0 as stated in the documentation.
Fixes #1833.
* Correct the documentation for `mbedtls_ssl_get_session()`. This API has
deep copy of the session, and the peer certificate is not lost. Fixes #926.
* Fix build using -std=c99. Fixed by Nick Wilson.
Changes
* Fail when receiving a TLS alert message with an invalid length, or invalid
zero-length messages when using TLS 1.2. Contributed by Espressif Systems.
* Change the default behaviour of mbedtls_hkdf_extract() to return an error
when calling with a NULL salt and non-zero salt_len. Contributed by
Brian J Murray
* Change the shebang line in Perl scripts to look up perl in the PATH.
Contributed by fbrosson.
* Allow overriding the time on Windows via the platform-time abstraction.
Fixed by Nick Wilson.
* Use gmtime_r/gmtime_s for thread-safety. Fixed by Nick Wilson.
= mbed TLS 2.11.0 branch released 2018-06-18
Features
* Add additional block mode, OFB (Output Feedback), to the AES module and
cipher abstraction module.
* Implement the HMAC-based extract-and-expand key derivation function
(HKDF) per RFC 5869. Contributed by Thomas Fossati.
* Add support for the CCM* block cipher mode as defined in IEEE Std. 802.15.4.
* Add support for the XTS block cipher mode with AES (AES-XTS).
Contributed by Aorimn in pull request #414.
* In TLS servers, support offloading private key operations to an external
cryptoprocessor. Private key operations can be asynchronous to allow
non-blocking operation of the TLS server stack.
Bugfix
* Fix the cert_write example to handle certificates signed with elliptic
curves as well as RSA. Fixes #777 found by dbedev.
* Fix for redefinition of _WIN32_WINNT to avoid overriding a definition
used by user applications. Found and fixed by Fabio Alessandrelli.
* Fix compilation warnings with IAR toolchain, on 32 bit platform.
Reported by rahmanih in #683
* Fix braces in mbedtls_memory_buffer_alloc_status(). Found by sbranden, #552.
Changes
* Changed CMake defaults for IAR to treat all compiler warnings as errors.
* Changed the Clang parameters used in the CMake build files to work for
versions later than 3.6. Versions of Clang earlier than this may no longer
work. Fixes #1072
= mbed TLS 2.10.0 branch released 2018-06-06
Features
* Add support for ARIA cipher (RFC 5794) and associated TLS ciphersuites
(RFC 6209). Disabled by default, see MBEDTLS_ARIA_C in config.h
API Changes
* Extend the platform module with a util component that contains
functionality shared by multiple Mbed TLS modules. At this stage
@ -13,6 +281,15 @@ API Changes
Therefore, mbedtls_platform_zeroize() is moved to the platform module to
facilitate testing and maintenance.
Bugfix
* Fix an issue with MicroBlaze support in bn_mul.h which was causing the
build to fail. Found by zv-io. Fixes #1651.
Changes
* Support TLS testing in out-of-source builds using cmake. Fixes #1193.
* Fix redundant declaration of mbedtls_ssl_list_ciphersuites. Raised by
TrinityTonic. #1359.
= mbed TLS 2.9.0 branch released 2018-04-30
Security

View file

@ -23,7 +23,7 @@ tests: lib
ifndef WINDOWS
install: no_test
mkdir -p $(DESTDIR)/include/mbedtls
cp -r include/mbedtls $(DESTDIR)/include
cp -rp include/mbedtls $(DESTDIR)/include
mkdir -p $(DESTDIR)/lib
cp -RP library/libmbedtls.* $(DESTDIR)/lib
@ -61,9 +61,21 @@ NULL_ENTROPY_WARN_L3=**** AND IS *NOT* SUITABLE FOR PRODUCTION USE ****\n
NULL_ENTROPY_WARNING=\n$(WARNING_BORDER)$(NULL_ENTROPY_WARN_L1)$(NULL_ENTROPY_WARN_L2)$(NULL_ENTROPY_WARN_L3)$(WARNING_BORDER)
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.pl get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY && ([ $$? -eq 0 ]) && \
echo '$(CTR_DRBG_128_BIT_KEY_WARNING)'
# If NULL Entropy is configured, display an appropriate warning
-scripts/config.pl get MBEDTLS_TEST_NULL_ENTROPY && ([ $$? -eq 0 ]) && \
echo '$(NULL_ENTROPY_WARNING)'

View file

@ -11,47 +11,16 @@ Compiler options can be set using conventional environment variables such as `CC
Compiling
---------
There are currently four active build systems used within Mbed TLS releases:
There are currently three active build systems used within Mbed TLS releases:
- yotta
- GNU Make
- CMake
- Microsoft Visual Studio (Microsoft Visual Studio 2010 or later)
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.
Yotta, as a build system, is slightly different from the other build systems:
- it provides a minimalistic configuration file by default
- depending on the yotta target, features of Mbed OS may be used in examples and tests
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`. Also, when loading shared libraries using dlopen(), you'll need to load libmbedcrypto first, then libmbedx509, before you can load libmbedtls.
### Yotta
[yotta](http://yottabuild.org) is a package manager and build system developed by Mbed, and is the build system of Mbed OS 16.03. To install it on your platform, please follow the yotta [installation instructions](http://docs.yottabuild.org/#installing).
Once yotta is installed, you can use it to download the latest version of Mbed TLS from the yotta registry with:
yotta install mbedtls
and build it with:
yotta build
If, on the other hand, you already have a copy of Mbed TLS from a source other than the yotta registry, for example from cloning our GitHub repository, or from downloading a tarball of the standalone edition, then you'll first need to generate the yotta module by running:
yotta/create-module.sh
This should be executed from the root Mbed TLS project directory. This will create the yotta module in the `yotta/module` directory within it. You can then change to that directory and build as usual:
cd yotta/module
yotta build
In any case, you'll probably want to set the yotta target before building unless it has already been set globally. For more information on using yotta, please consult the [yotta documentation](http://docs.yottabuild.org/).
For more details on the yotta/Mbed OS edition of Mbed TLS, including example programs, please consult the [Readme at the root of the yotta module](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/README.md).
### 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.
@ -78,11 +47,11 @@ In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if th
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 -W`), so it 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 overriden from the command line.
Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -W`), 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 overriden from the command line.
Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue.
In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS knowledge base](https://tls.mbed.org/kb).
In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS Knowledge Base](https://tls.mbed.org/kb).
### CMake
@ -169,7 +138,7 @@ The solution file `mbedTLS.sln` contains all the basic projects needed to build
Example programs
----------------
We've included example programs for a lot of different features and uses in `programs/`. Most programs only focus on a single feature or usage scenario, so keep that in mind when copying parts of the code.
We've included example programs for a lot of different features and uses in [`programs/`](programs/README.md). Most programs only focus on a single feature or usage scenario, so keep that in mind when copying parts of the code.
Tests
-----
@ -192,7 +161,7 @@ We provide some non-standard configurations focused on specific use cases in the
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:
Mbed TLS can be ported to many different architectures, OS's and platforms. Before starting a port, you may find the following Knowledge Base articles useful:
- [Porting Mbed TLS to a new environment or OS](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS)
- [What external dependencies does Mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
@ -211,7 +180,7 @@ To accept the Contributors Licence Agreement (CLA), individual contributors c
### Making a Contribution
1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://tls.mbed.org/discussions) around a feature idea or a bug.
1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://forums.mbed.com/c/mbed-tls) around a feature idea or a bug.
2. Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the "development" branch as a basis.
3. Write a test which shows that the bug was fixed or that the feature works as expected.
4. Send a pull request and bug us until it gets merged and published. Contributions may need some modifications, so work with us to get your change accepted. We will include your name in the ChangeLog :)

View file

@ -81,7 +81,7 @@
* 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_MAX_CONTENT_LEN 512
#define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
#include "mbedtls/check_config.h"

View file

@ -82,6 +82,7 @@
#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

View file

@ -24,7 +24,7 @@
*/
/**
* @mainpage mbed TLS v2.9.0 source code documentation
* @mainpage mbed TLS v2.13.1 source code documentation
*
* This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in

View file

@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
PROJECT_NAME = "mbed TLS v2.9.0"
PROJECT_NAME = "mbed TLS v2.13.1"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
@ -664,7 +664,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ..
INPUT = ../include input
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -696,7 +696,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = ../configs ../yotta/module
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded

View file

@ -9,3 +9,8 @@ if(INSTALL_MBEDTLS_HEADERS)
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endif(INSTALL_MBEDTLS_HEADERS)
# Make config.h available in an out-of-source build. ssl-opt.sh requires it.
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
link_to_source(mbedtls)
endif()

View file

@ -13,6 +13,11 @@
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
* techniques -- Encryption algorithms -- Part 2: Asymmetric
* ciphers</em>.
*
* The AES-XTS block mode is standardized by NIST SP 800-38E
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
* and described in detail by IEEE P1619
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
@ -53,7 +58,8 @@
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
/* Error codes in range 0x0023-0x0025 */
/* Error codes in range 0x0021-0x0025 */
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
@ -73,7 +79,7 @@ extern "C" {
/**
* \brief The AES context-type definition.
*/
typedef struct
typedef struct mbedtls_aes_context
{
int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys. */
@ -88,6 +94,19 @@ typedef struct
}
mbedtls_aes_context;
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief The AES XTS context-type definition.
*/
typedef struct mbedtls_aes_xts_context
{
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
encryption or decryption. */
mbedtls_aes_context tweak; /*!< The AES context used for tweak
computation. */
} mbedtls_aes_xts_context;
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#else /* MBEDTLS_AES_ALT */
#include "aes_alt.h"
#endif /* MBEDTLS_AES_ALT */
@ -109,6 +128,25 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx );
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function initializes the specified AES XTS context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES XTS context to initialize.
*/
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
/**
* \brief This function releases and clears the specified AES XTS context.
*
* \param ctx The AES XTS context to clear.
*/
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function sets the encryption key.
*
@ -141,6 +179,44 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function prepares an XTS context for encryption and
* sets the encryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* \param key The encryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function prepares an XTS context for decryption and
* sets the decryption key.
*
* \param ctx The AES XTS context to which the key should be bound.
* \param key The decryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* \param keybits The size of \p key passed in bits. Valid options are:
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function performs an AES single-block encryption or
* decryption operation.
@ -212,6 +288,49 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief This function performs an AES-XTS encryption or decryption
* operation for an entire XTS data unit.
*
* AES-XTS encrypts or decrypts blocks based on their location as
* defined by a data unit number. The data unit number must be
* provided by \p data_unit.
*
* NIST SP 800-38E limits the maximum size of a data unit to 2^20
* AES blocks. If the data unit is larger than this, this function
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
*
* \param ctx The AES XTS context to use for AES XTS operations.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of a data unit in bytes. This can be any
* length between 16 bytes and 2^24 bytes inclusive
* (between 1 and 2^20 block cipher blocks).
* \param data_unit The address of the data unit encoded as an array of 16
* bytes in little-endian format. For disk encryption, this
* is typically the index of the block device sector that
* contains the data.
* \param input The buffer holding the input data (which is an entire
* data unit). This function reads \p length bytes from \p
* input.
* \param output The buffer holding the output data (which is an entire
* data unit). This function writes \p length bytes to \p
* output.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
* smaller than an AES block in size (16 bytes) or if \p
* length is larger than 2^20 blocks (16 MiB).
*/
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
const unsigned char data_unit[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief This function performs an AES-CFB128 encryption or decryption
@ -295,6 +414,56 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/**
* \brief This function performs an AES-OFB (Output Feedback Mode)
* encryption or decryption operation.
*
* For OFB, you must set up the context with
* mbedtls_aes_setkey_enc(), regardless of whether you are
* performing an encryption or decryption operation. This is
* because OFB mode uses the same key schedule for encryption and
* decryption.
*
* The OFB operation is identical for encryption or decryption,
* therefore no operation mode needs to be specified.
*
* \note Upon exit, the content of iv, the Initialisation Vector, is
* updated so that you can call the same function again on the next
* block(s) of data and get the same result as if it was encrypted
* in one call. This allows a "streaming" usage, by initialising
* iv_off to 0 before the first call, and preserving its value
* between calls.
*
* For non-streaming use, the iv should be initialised on each call
* to a unique value, and iv_off set to 0 on each call.
*
* If you need to retain the contents of the initialisation vector,
* you must either save it manually or use the cipher module
* instead.
*
* \warning For the OFB mode, the initialisation vector must be unique
* every encryption operation. Reuse of an initialisation vector
* will compromise security.
*
* \param ctx The AES context to use for encryption or decryption.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* \param iv The initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief This function performs an AES-CTR encryption or decryption
@ -309,7 +478,49 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
* must use the context initialized with mbedtls_aes_setkey_enc()
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
*
* \warning You must keep the maximum use of your counter in mind.
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that an AES block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The AES context to use for encryption or decryption.
* \param length The length of the input data.

View file

@ -53,7 +53,7 @@ extern "C" {
* security risk. We recommend considering stronger ciphers instead.
*
*/
typedef struct
typedef struct mbedtls_arc4_context
{
int x; /*!< permutation index */
int y; /*!< permutation index */

331
include/mbedtls/aria.h Normal file
View file

@ -0,0 +1,331 @@
/**
* \file aria.h
*
* \brief ARIA block cipher
*
* The ARIA algorithm is a symmetric block cipher that can encrypt and
* decrypt information. It is defined by the Korean Agency for
* Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in
* Korean, but see http://210.104.33.10/ARIA/index-e.html in English)
* and also described by the IETF in <em>RFC 5794</em>.
*/
/* Copyright (C) 2006-2018, 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 MBEDTLS_ARIA_H
#define MBEDTLS_ARIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */
#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */
#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maxiumum number of rounds in ARIA. */
#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH -0x005C /**< Invalid key length. */
#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */
#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED -0x0058 /**< ARIA hardware accelerator failed. */
#if !defined(MBEDTLS_ARIA_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The ARIA context-type definition.
*/
typedef struct mbedtls_aria_context
{
unsigned char nr; /*!< The number of rounds (12, 14 or 16) */
/*! The ARIA round keys. */
uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
}
mbedtls_aria_context;
#else /* MBEDTLS_ARIA_ALT */
#include "aria_alt.h"
#endif /* MBEDTLS_ARIA_ALT */
/**
* \brief This function initializes the specified ARIA context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The ARIA context to initialize.
*/
void mbedtls_aria_init( mbedtls_aria_context *ctx );
/**
* \brief This function releases and clears the specified ARIA context.
*
* \param ctx The ARIA context to clear.
*/
void mbedtls_aria_free( mbedtls_aria_context *ctx );
/**
* \brief This function sets the encryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* \param key The encryption key.
* \param keybits The size of data passed in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH
* on failure.
*/
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function sets the decryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* \param key The decryption key.
* \param keybits The size of data passed. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function performs an ARIA single-block encryption or
* decryption operation.
*
* It performs encryption or decryption (depending on whether
* the key was set for encryption on decryption) on the input
* data buffer defined in the \p input parameter.
*
* mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or
* mbedtls_aria_setkey_dec() must be called before the first
* call to this API with the same context.
*
* \param ctx The ARIA context to use for encryption or decryption.
* \param input The 16-Byte buffer holding the input data.
* \param output The 16-Byte buffer holding the output data.
* \return \c 0 on success.
*/
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief This function performs an ARIA-CBC encryption or decryption operation
* on full blocks.
*
* It performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer defined in
* the \p input parameter.
*
* It can be called as many times as needed, until all the input
* data is processed. mbedtls_aria_init(), and either
* mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called
* before the first call to this API with the same context.
*
* \note This function operates on aligned blocks, that is, the input size
* must be a multiple of the ARIA block size of 16 Bytes.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the same function again on the next
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If you need to retain the contents of the IV, you should
* either save it manually or use the cipher module instead.
*
*
* \param ctx The ARIA context to use for encryption or decryption.
* \param mode The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
* #MBEDTLS_ARIA_DECRYPT.
* \param length The length of the input data in Bytes. This must be a
* multiple of the block size (16 Bytes).
* \param iv Initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success, or #MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH
* on failure.
*/
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief This function performs an ARIA-CFB128 encryption or decryption
* operation.
*
* It performs the operation defined in the \p mode
* parameter (encrypt or decrypt), on the input data buffer
* defined in the \p input parameter.
*
* For CFB, you must set up the context with mbedtls_aria_setkey_enc(),
* regardless of whether you are performing an encryption or decryption
* operation, that is, regardless of the \p mode parameter. This is
* because CFB mode uses the same key schedule for encryption and
* decryption.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the same function again on the next
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If you need to retain the contents of the
* IV, you must either save it manually or use the cipher
* module instead.
*
*
* \param ctx The ARIA context to use for encryption or decryption.
* \param mode The ARIA operation: #MBEDTLS_ARIA_ENCRYPT or
* #MBEDTLS_ARIA_DECRYPT.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* \param iv The initialization vector (updated after use).
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success.
*/
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief This function performs an ARIA-CTR encryption or decryption
* operation.
*
* This function performs the operation defined in the \p mode
* parameter (encrypt/decrypt), on the input data buffer
* defined in the \p input parameter.
*
* Due to the nature of CTR, you must use the same key schedule
* for both encryption and decryption operations. Therefore, you
* must use the context initialized with mbedtls_aria_setkey_enc()
* for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that an ARIA block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx The ARIA context to use for encryption or decryption.
* \param length The length of the input data.
* \param nc_off The offset in the current \p stream_block, for
* resuming within the current cipher stream. The
* offset pointer should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream block for resuming. This is
* overwritten by the function.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
*
* \return \c 0 on success.
*/
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine.
*
* \return \c 0 on success, or \c 1 on failure.
*/
int mbedtls_aria_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* aria.h */

View file

@ -177,7 +177,7 @@ extern "C" {
/**
* \brief MPI structure
*/
typedef struct
typedef struct mbedtls_mpi
{
int s; /*!< integer sign */
size_t n; /*!< total # of limbs */

View file

@ -55,7 +55,7 @@ extern "C" {
/**
* \brief Blowfish context structure
*/
typedef struct
typedef struct mbedtls_blowfish_context
{
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
uint32_t S[4][256]; /*!< key dependent S-boxes */
@ -174,7 +174,46 @@ int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
/**
* \brief Blowfish-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**64
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 4 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 4 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**32 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter.
*
* Note that for both stategies, sizes are measured in blocks and
* that a Blowfish block is 8 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx Blowfish context
* \param length The length of the data

View file

@ -49,7 +49,14 @@
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
#if defined(__i386__)
/*
* Disable use of the i386 assembly code below if option -O0, to disable all
* compiler optimisations, is passed, detected with __OPTIMIZE__
* This is done as the number of registers used in the assembly code doesn't
* work with the -O0 option.
*/
#if defined(__i386__) && defined(__OPTIMIZE__)
#define MULADDC_INIT \
asm( \
@ -142,7 +149,7 @@
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#else
@ -154,7 +161,7 @@
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
@ -521,7 +528,7 @@
"swi r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4" "r5", "r6", "r7", "r8", \
: "r3", "r4", "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "r12", "r13" \
);
@ -558,9 +565,8 @@
#endif /* TriCore */
/*
* gcc -O0 by default uses r7 for the frame pointer, so it complains about our
* use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
* passing that option is not easy when building with yotta.
* Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about
* our use of r7 below, unless -fomit-frame-pointer is passed.
*
* On the other hand, -fomit-frame-pointer is implied by any -Ox options with
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
@ -630,6 +636,23 @@
"r6", "r7", "r8", "r9", "cc" \
);
#elif defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
#define MULADDC_INIT \
asm(
#define MULADDC_CORE \
"ldr r0, [%0], #4 \n\t" \
"ldr r1, [%1] \n\t" \
"umaal r1, %2, %3, r0 \n\t" \
"str r1, [%1], #4 \n\t"
#define MULADDC_STOP \
: "=r" (s), "=r" (d), "=r" (c) \
: "r" (b), "0" (s), "1" (d), "2" (c) \
: "r0", "r1", "memory" \
);
#else
#define MULADDC_INIT \

View file

@ -51,7 +51,7 @@ extern "C" {
/**
* \brief CAMELLIA context structure
*/
typedef struct
typedef struct mbedtls_camellia_context
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
@ -187,12 +187,54 @@ int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
/**
* \brief CAMELLIA-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
*
* \warning You must never reuse a nonce value with the same key. Doing so
* would void the encryption for the two messages encrypted with
* the same nonce and key.
*
* There are two common strategies for managing nonces with CTR:
*
* 1. You can handle everything as a single message processed over
* successive calls to this function. In that case, you want to
* set \p nonce_counter and \p nc_off to 0 for the first call, and
* then preserve the values of \p nonce_counter, \p nc_off and \p
* stream_block across calls to this function as they will be
* updated by this function.
*
* With this strategy, you must not encrypt more than 2**128
* blocks of data with the same key.
*
* 2. You can encrypt separate messages by dividing the \p
* nonce_counter buffer in two areas: the first one used for a
* per-message nonce, handled by yourself, and the second one
* updated by this function internally.
*
* For example, you might reserve the first 12 bytes for the
* per-message nonce, and the last 4 bytes for internal use. In that
* case, before calling this function on a new message you need to
* set the first 12 bytes of \p nonce_counter to your chosen nonce
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
* stream_block to be ignored). That way, you can encrypt at most
* 2**96 messages of up to 2**32 blocks each with the same key.
*
* The per-message nonce (or information sufficient to reconstruct
* it) needs to be communicated with the ciphertext and must be unique.
* The recommended way to ensure uniqueness is to use a message
* counter. An alternative is to generate random nonces, but this
* limits the number of messages that can be securely encrypted:
* for example, with 96-bit random nonces, you should not encrypt
* more than 2**32 messages with the same key.
*
* Note that for both stategies, sizes are measured in blocks and
* that a CAMELLIA block is 16 bytes.
*
* \warning Upon return, \p stream_block contains sensitive data. Its
* content must not be written to insecure storage and should be
* securely discarded as soon as it's no longer needed.
*
* \param ctx CAMELLIA context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming

View file

@ -14,6 +14,18 @@
* <li>Nonce - A unique value that is assigned to the payload and the
* associated data.</li></ul>
*
* Definition of CCM:
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
* RFC 3610 "Counter with CBC-MAC (CCM)"
*
* Related:
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
*
* Definition of CCM*:
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
* Integer representation is fixed most-significant-octet-first order and
* the representation of octets is most-significant-bit-first order. This is
* consistent with RFC 3610.
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@ -56,7 +68,8 @@ extern "C" {
* \brief The CCM context-type definition. The CCM context is passed
* to the APIs called.
*/
typedef struct {
typedef struct mbedtls_ccm_context
{
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
}
mbedtls_ccm_context;
@ -102,7 +115,6 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
/**
* \brief This function encrypts a buffer using CCM.
*
*
* \note The tag is written to a separate buffer. To concatenate
* the \p tag with the \p output, as done in <em>RFC-3610:
* Counter with CBC-MAC (CCM)</em>, use
@ -112,15 +124,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
* \param ctx The CCM context to use for encryption.
* \param length The length of the input data in Bytes.
* \param iv Initialization vector (nonce).
* \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
* \param tag The buffer holding the tag.
* \param tag_len The length of the tag to generate in Bytes:
* \param tag The buffer holding the authentication field.
* \param tag_len The length of the authentication field to generate in Bytes:
* 4, 6, 8, 10, 12, 14 or 16.
*
* \return \c 0 on success.
@ -133,21 +147,64 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
unsigned char *tag, size_t tag_len );
/**
* \brief This function performs a CCM authenticated decryption of a
* buffer.
* \brief This function encrypts a buffer using CCM*.
*
* \param ctx The CCM context to use for decryption.
* \note The tag is written to a separate buffer. To concatenate
* the \p tag with the \p output, as done in <em>RFC-3610:
* Counter with CBC-MAC (CCM)</em>, use
* \p tag = \p output + \p length, and make sure that the
* output buffer is at least \p length + \p tag_len wide.
*
* \note When using this function in a variable tag length context,
* the tag length has to be encoded into the \p iv passed to
* this function.
*
* \param ctx The CCM context to use for encryption.
* \param length The length of the input data in Bytes.
* \param iv Initialization vector.
* \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
* \param iv Initialization vector (nonce).
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
* \param tag The buffer holding the tag.
* \param tag_len The length of the tag in Bytes.
* \param tag The buffer holding the authentication field.
* \param tag_len The length of the authentication field to generate in Bytes:
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing 0 as \p tag_len means that the message is no
* longer authenticated.
*
* \return \c 0 on success.
* \return A CCM or cipher-specific error code on failure.
*/
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len );
/**
* \brief This function performs a CCM authenticated decryption of a
* buffer.
*
* \param ctx The CCM context to use for decryption.
* \param length The length of the input data in Bytes.
* \param iv Initialization vector (nonce).
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
* \param tag The buffer holding the authentication field.
* \param tag_len The length of the authentication field in Bytes.
* 4, 6, 8, 10, 12, 14 or 16.
*
* \return \c 0 on success. This indicates that the message is authentic.
@ -160,6 +217,43 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
/**
* \brief This function performs a CCM* authenticated decryption of a
* buffer.
*
* \note When using this function in a variable tag length context,
* the tag length has to be decoded from \p iv and passed to
* this function as \p tag_len. (\p tag needs to be adjusted
* accordingly.)
*
* \param ctx The CCM context to use for decryption.
* \param length The length of the input data in Bytes.
* \param iv Initialization vector (nonce).
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
* or 13. The length L of the message length field is
* 15 - \p iv_len.
* \param add The additional data field.
* \param add_len The length of additional data in Bytes.
* Must be less than 2^16 - 2^8.
* \param input The buffer holding the input data.
* \param output The buffer holding the output data.
* Must be at least \p length Bytes wide.
* \param tag The buffer holding the authentication field.
* \param tag_len The length of the authentication field in Bytes.
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing 0 as \p tag_len means that the message is no
* longer authenticated.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
* \return A cipher-specific error code on calculation failure.
*/
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**

212
include/mbedtls/chacha20.h Normal file
View file

@ -0,0 +1,212 @@
/**
* \file chacha20.h
*
* \brief This file contains ChaCha20 definitions and functions.
*
* ChaCha20 is a stream cipher that can encrypt and decrypt
* information. ChaCha was created by Daniel Bernstein as a variant of
* its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf
* ChaCha20 is the variant with 20 rounds, that was also standardized
* in RFC 7539.
*
* \author Daniel King <damaki.gh@gmail.com>
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), 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 MBEDTLS_CHACHA20_H
#define MBEDTLS_CHACHA20_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdint.h>
#include <stddef.h>
#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */
#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CHACHA20_ALT)
typedef struct mbedtls_chacha20_context
{
uint32_t state[16]; /*! The state (before round operations). */
uint8_t keystream8[64]; /*! Leftover keystream bytes. */
size_t keystream_bytes_used; /*! Number of keystream bytes already used. */
}
mbedtls_chacha20_context;
#else /* MBEDTLS_CHACHA20_ALT */
#include "chacha20_alt.h"
#endif /* MBEDTLS_CHACHA20_ALT */
/**
* \brief This function initializes the specified ChaCha20 context.
*
* It must be the first API called before using
* the context.
*
* It is usually followed by calls to
* \c mbedtls_chacha20_setkey() and
* \c mbedtls_chacha20_starts(), then one or more calls to
* to \c mbedtls_chacha20_update(), and finally to
* \c mbedtls_chacha20_free().
*
* \param ctx The ChaCha20 context to initialize.
*/
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx );
/**
* \brief This function releases and clears the specified ChaCha20 context.
*
* \param ctx The ChaCha20 context to clear.
*/
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx );
/**
* \brief This function sets the encryption/decryption key.
*
* \note After using this function, you must also call
* \c mbedtls_chacha20_starts() to set a nonce before you
* start encrypting/decrypting data with
* \c mbedtls_chacha_update().
*
* \param ctx The ChaCha20 context to which the key should be bound.
* \param key The encryption/decryption key. Must be 32 bytes in length.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
*/
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
const unsigned char key[32] );
/**
* \brief This function sets the nonce and initial counter value.
*
* \note A ChaCha20 context can be re-used with the same key by
* calling this function to change the nonce.
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality guarantees for the
* messages encrypted with the same nonce and key.
*
* \param ctx The ChaCha20 context to which the nonce should be bound.
* \param nonce The nonce. Must be 12 bytes in size.
* \param counter The initial counter value. This is usually 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
* NULL.
*/
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
const unsigned char nonce[12],
uint32_t counter );
/**
* \brief This function encrypts or decrypts data.
*
* Since ChaCha20 is a stream cipher, the same operation is
* used for encrypting and decrypting data.
*
* \note The \p input and \p output pointers must either be equal or
* point to non-overlapping buffers.
*
* \note \c mbedtls_chacha20_setkey() and
* \c mbedtls_chacha20_starts() must be called at least once
* to setup the context before this function can be called.
*
* \note This function can be called multiple times in a row in
* order to encrypt of decrypt data piecewise with the same
* key and nonce.
*
* \param ctx The ChaCha20 context to use for encryption or decryption.
* \param size The length of the input data in bytes.
* \param input The buffer holding the input data.
* This pointer can be NULL if size == 0.
* \param output The buffer holding the output data.
* Must be able to hold \p size bytes.
* This pointer can be NULL if size == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or
* output pointers are NULL.
*/
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
size_t size,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function encrypts or decrypts data with ChaCha20 and
* the given key and nonce.
*
* Since ChaCha20 is a stream cipher, the same operation is
* used for encrypting and decrypting data.
*
* \warning You must never use the same (key, nonce) pair more than
* once. This would void any confidentiality guarantees for
* the messages encrypted with the same nonce and key.
*
* \note The \p input and \p output pointers must either be equal or
* point to non-overlapping buffers.
*
* \param key The encryption/decryption key. Must be 32 bytes in length.
* \param nonce The nonce. Must be 12 bytes in size.
* \param counter The initial counter value. This is usually 0.
* \param size The length of the input data in bytes.
* \param input The buffer holding the input data.
* This pointer can be NULL if size == 0.
* \param output The buffer holding the output data.
* Must be able to hold \p size bytes.
* This pointer can be NULL if size == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input,
* or output is NULL.
*/
int mbedtls_chacha20_crypt( const unsigned char key[32],
const unsigned char nonce[12],
uint32_t counter,
size_t size,
const unsigned char* input,
unsigned char* output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The ChaCha20 checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_chacha20_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CHACHA20_H */

View file

@ -0,0 +1,355 @@
/**
* \file chachapoly.h
*
* \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and
* functions.
*
* ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
* with Associated Data (AEAD) that can be used to encrypt and
* authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
* Bernstein and was standardized in RFC 7539.
*
* \author Daniel King <damaki.gh@gmail.com>
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), 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 MBEDTLS_CHACHAPOLY_H
#define MBEDTLS_CHACHAPOLY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
/* for shared error codes */
#include "poly1305.h"
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */
MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */
}
mbedtls_chachapoly_mode_t;
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
#include "chacha20.h"
typedef struct mbedtls_chachapoly_context
{
mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */
mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */
uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */
uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */
int state; /**< The current state of the context. */
mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */
}
mbedtls_chachapoly_context;
#else /* !MBEDTLS_CHACHAPOLY_ALT */
#include "chachapoly_alt.h"
#endif /* !MBEDTLS_CHACHAPOLY_ALT */
/**
* \brief This function initializes the specified ChaCha20-Poly1305 context.
*
* It must be the first API called before using
* the context. It must be followed by a call to
* \c mbedtls_chachapoly_setkey() before any operation can be
* done, and to \c mbedtls_chachapoly_free() once all
* operations with that context have been finished.
*
* In order to encrypt or decrypt full messages at once, for
* each message you should make a single call to
* \c mbedtls_chachapoly_crypt_and_tag() or
* \c mbedtls_chachapoly_auth_decrypt().
*
* In order to encrypt messages piecewise, for each
* message you should make a call to
* \c mbedtls_chachapoly_starts(), then 0 or more calls to
* \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
* \c mbedtls_chachapoly_update(), then one call to
* \c mbedtls_chachapoly_finish().
*
* \warning Decryption with the piecewise API is discouraged! Always
* use \c mbedtls_chachapoly_auth_decrypt() when possible!
*
* If however this is not possible because the data is too
* large to fit in memory, you need to:
*
* - call \c mbedtls_chachapoly_starts() and (if needed)
* \c mbedtls_chachapoly_update_aad() as above,
* - call \c mbedtls_chachapoly_update() multiple times and
* ensure its output (the plaintext) is NOT used in any other
* way than placing it in temporary storage at this point,
* - call \c mbedtls_chachapoly_finish() to compute the
* authentication tag and compared it in constant time to the
* tag received with the ciphertext.
*
* If the tags are not equal, you must immediately discard
* all previous outputs of \c mbedtls_chachapoly_update(),
* otherwise you can now safely use the plaintext.
*
* \param ctx The ChachaPoly context to initialize.
*/
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );
/**
* \brief This function releases and clears the specified ChaCha20-Poly1305 context.
*
* \param ctx The ChachaPoly context to clear.
*/
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );
/**
* \brief This function sets the ChaCha20-Poly1305 symmetric encryption key.
*
* \param ctx The ChaCha20-Poly1305 context to which the key should be
* bound.
* \param key The 256-bit (32 bytes) key.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx or \p key are NULL.
*/
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] );
/**
* \brief This function starts a ChaCha20-Poly1305 encryption or
* decryption operation.
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality and authenticity
* guarantees for the messages encrypted with the same nonce
* and key.
*
* \note If the context is being used for AAD only (no data to
* encrypt or decrypt) then \p mode can be set to any value.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context.
* \param nonce The nonce/IV to use for the message. Must be 12 bytes.
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx or \p mac are NULL.
*/
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
const unsigned char nonce[12],
mbedtls_chachapoly_mode_t mode );
/**
* \brief This function feeds additional data to be authenticated
* into an ongoing ChaCha20-Poly1305 operation.
*
* The Additional Authenticated Data (AAD), also called
* Associated Data (AD) is only authenticated but not
* encrypted nor included in the encrypted output. It is
* usually transmitted separately from the ciphertext or
* computed locally by each party.
*
* \note This function is called before data is encrypted/decrypted.
* I.e. call this function to process the AAD before calling
* \c mbedtls_chachapoly_update().
*
* You may call this function multiple times to process
* an arbitrary amount of AAD. It is permitted to call
* this function 0 times, if no AAD is used.
*
* This function cannot be called any more if data has
* been processed by \c mbedtls_chachapoly_update(),
* or if the context has been finished.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context to use.
* \param aad_len The length (in bytes) of the AAD. The length has no
* restrictions.
* \param aad Buffer containing the AAD.
* This pointer can be NULL if aad_len == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx or \p aad are NULL.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operations has not been started or has been
* finished, or if the AAD has been finished.
*/
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
const unsigned char *aad,
size_t aad_len );
/**
* \brief Thus function feeds data to be encrypted or decrypted
* into an on-going ChaCha20-Poly1305
* operation.
*
* The direction (encryption or decryption) depends on the
* mode that was given when calling
* \c mbedtls_chachapoly_starts().
*
* You may call this function multiple times to process
* an arbitrary amount of data. It is permitted to call
* this function 0 times, if no data is to be encrypted
* or decrypted.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \param ctx The ChaCha20-Poly1305 context to use.
* \param len The length (in bytes) of the data to encrypt or decrypt.
* \param input The buffer containing the data to encrypt or decrypt.
* This pointer can be NULL if len == 0.
* \param output The buffer to where the encrypted or decrypted data is written.
* Must be able to hold \p len bytes.
* This pointer can be NULL if len == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx, \p input, or \p output are NULL.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
*/
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
size_t len,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function finished the ChaCha20-Poly1305 operation and
* generates the MAC (authentication tag).
*
* \param ctx The ChaCha20-Poly1305 context to use.
* \param mac The buffer to where the 128-bit (16 bytes) MAC is written.
*
* \warning Decryption with the piecewise API is discouraged, see the
* warning on \c mbedtls_chachapoly_init().
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if \p ctx or \p mac are NULL.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
*/
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
unsigned char mac[16] );
/**
* \brief This function performs a complete ChaCha20-Poly1305
* authenticated encryption with the previously-set key.
*
* \note Before using this function, you must set the key with
* \c mbedtls_chachapoly_setkey().
*
* \warning You must never use the same nonce twice with the same key.
* This would void any confidentiality and authenticity
* guarantees for the messages encrypted with the same nonce
* and key.
*
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
* \param length The length (in bytes) of the data to encrypt or decrypt.
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
* \param aad The buffer containing the additional authenticated data (AAD).
* This pointer can be NULL if aad_len == 0.
* \param aad_len The length (in bytes) of the AAD data to process.
* \param input The buffer containing the data to encrypt or decrypt.
* This pointer can be NULL if ilen == 0.
* \param output The buffer to where the encrypted or decrypted data is written.
* This pointer can be NULL if ilen == 0.
* \param tag The buffer to where the computed 128-bit (16 bytes) MAC is written.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if one or more of the required parameters are NULL.
*/
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char *input,
unsigned char *output,
unsigned char tag[16] );
/**
* \brief This function performs a complete ChaCha20-Poly1305
* authenticated decryption with the previously-set key.
*
* \note Before using this function, you must set the key with
* \c mbedtls_chachapoly_setkey().
*
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
* \param length The length (in bytes) of the data to decrypt.
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
* \param aad The buffer containing the additional authenticated data (AAD).
* This pointer can be NULL if aad_len == 0.
* \param aad_len The length (in bytes) of the AAD data to process.
* \param tag The buffer holding the authentication tag.
* \param input The buffer containing the data to decrypt.
* This pointer can be NULL if ilen == 0.
* \param output The buffer to where the decrypted data is written.
* This pointer can be NULL if ilen == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if one or more of the required parameters are NULL.
* \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
* if the data was not authentic.
*/
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char tag[16],
const unsigned char *input,
unsigned char *output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The ChaCha20-Poly1305 checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_chachapoly_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CHACHAPOLY_H */

View file

@ -4,7 +4,7 @@
* \brief Consistency checks for configuration options
*/
/*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -87,6 +87,11 @@
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_NIST_KW_C) && \
( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
@ -191,6 +196,10 @@
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif

View file

@ -37,7 +37,7 @@
#include <stddef.h>
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#define MBEDTLS_CIPHER_MODE_AEAD
#endif
@ -45,7 +45,8 @@
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif
#if defined(MBEDTLS_ARC4_C)
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
defined(MBEDTLS_CHACHA20_C)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
@ -86,6 +87,8 @@ typedef enum {
MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */
MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */
MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */
MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */
} mbedtls_cipher_id_t;
/**
@ -145,6 +148,31 @@ typedef enum {
MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */
MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */
MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */
MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */
MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */
MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */
MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */
MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */
MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */
MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
} mbedtls_cipher_type_t;
/** Supported cipher modes. */
@ -153,11 +181,13 @@ typedef enum {
MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
MBEDTLS_MODE_OFB, /**< The OFB cipher mode - unsupported. */
MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
} mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
@ -206,7 +236,8 @@ typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
* Cipher information. Allows calling cipher functions
* in a generic way.
*/
typedef struct {
typedef struct mbedtls_cipher_info_t
{
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
@ -247,7 +278,8 @@ typedef struct {
/**
* Generic cipher context.
*/
typedef struct {
typedef struct mbedtls_cipher_context_t
{
/** Information about the associated cipher. */
const mbedtls_cipher_info_t *cipher_info;
@ -273,7 +305,8 @@ typedef struct {
/** Number of Bytes that have not been processed yet. */
size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode. */
/** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
* for XTS-mode. */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
/** IV size in Bytes, for ciphers with variable-length IVs. */
@ -560,11 +593,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
*/
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function adds additional data for AEAD ciphers.
* Only supported with GCM. Must be called
* exactly once, after mbedtls_cipher_reset().
* Currently supported with GCM and ChaCha20+Poly1305.
* Must be called exactly once, after mbedtls_cipher_reset().
*
* \param ctx The generic cipher context.
* \param ad The additional data to use.
@ -575,7 +608,7 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
*/
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic cipher update function. It encrypts or
@ -633,10 +666,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function writes a tag for AEAD ciphers.
* Only supported with GCM.
* Currently supported with GCM and ChaCha20+Poly1305.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context.
@ -651,7 +684,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
/**
* \brief This function checks the tag for AEAD ciphers.
* Only supported with GCM.
* Currently supported with GCM and ChaCha20+Poly1305.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context.
@ -663,7 +696,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
*/
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic all-in-one encryption/decryption function,

View file

@ -64,6 +64,14 @@ struct mbedtls_cipher_base_t
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/** Encrypt using OFB (Full length) */
int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
unsigned char *iv,
const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
@ -71,6 +79,13 @@ struct mbedtls_cipher_base_t
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/** Encrypt or decrypt using XTS. */
int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
const unsigned char data_unit[16],
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
/** Encrypt using STREAM */
int (*stream_func)( void *ctx, size_t length,

View file

@ -28,7 +28,7 @@
#ifndef MBEDTLS_CMAC_H
#define MBEDTLS_CMAC_H
#include "mbedtls/cipher.h"
#include "cipher.h"
#ifdef __cplusplus
extern "C" {

View file

@ -1378,7 +1378,8 @@
#define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED
#define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED
#define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED
#define SSL_BUFFER_LEN MBEDTLS_SSL_BUFFER_LEN
#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \
? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) )
#define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES
#define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT
#define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED

View file

@ -8,7 +8,7 @@
* memory footprint.
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -48,10 +48,14 @@
* Requires support for asm() in compiler.
*
* Used in:
* library/aria.c
* library/timing.c
* library/padlock.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
@ -84,6 +88,28 @@
*/
//#define MBEDTLS_NO_UDBL_DIVISION
/**
* \def MBEDTLS_NO_64BIT_MULTIPLICATION
*
* The platform lacks support for 32x32 -> 64-bit multiplication.
*
* Used in:
* library/poly1305.c
*
* Some parts of the library may use multiplication of two unsigned 32-bit
* operands with a 64-bit result in order to speed up computations. On some
* platforms, this is not available in hardware and has to be implemented in
* software, usually in a library provided by the toolchain.
*
* Sometimes it is not desirable to have to link to that library. This option
* removes the dependency of that library on platforms that lack a hardware
* 64-bit multiplier by embedding a software implementation in Mbed TLS.
*
* Note that depending on the compiler, this may decrease performance compared
* to using the library function provided by the toolchain.
*/
//#define MBEDTLS_NO_64BIT_MULTIPLICATION
/**
* \def MBEDTLS_HAVE_SSE2
*
@ -111,12 +137,21 @@
/**
* \def MBEDTLS_HAVE_TIME_DATE
*
* System has time.h and time(), gmtime() and the clock is correct.
* System has time.h, time(), and an implementation for
* mbedtls_platform_gmtime_r() (see below).
* The time needs to be correct (not necesarily very accurate, but at least
* the date should be correct). This is used to verify the validity period of
* X.509 certificates.
*
* Comment if your system does not have a correct clock.
*
* \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
* behaves similarly to the gmtime_r() function from the C standard. Refer to
* the documentation for mbedtls_platform_gmtime_r() for more information.
*
* \note It is possible to configure an implementation for
* mbedtls_platform_gmtime_r() at compile-time by using the macro
* MBEDTLS_PLATFORM_GMTIME_R_ALT.
*/
#define MBEDTLS_HAVE_TIME_DATE
@ -271,23 +306,29 @@
*/
//#define MBEDTLS_AES_ALT
//#define MBEDTLS_ARC4_ALT
//#define MBEDTLS_ARIA_ALT
//#define MBEDTLS_BLOWFISH_ALT
//#define MBEDTLS_CAMELLIA_ALT
//#define MBEDTLS_CCM_ALT
//#define MBEDTLS_CHACHA20_ALT
//#define MBEDTLS_CHACHAPOLY_ALT
//#define MBEDTLS_CMAC_ALT
//#define MBEDTLS_DES_ALT
//#define MBEDTLS_DHM_ALT
//#define MBEDTLS_ECJPAKE_ALT
//#define MBEDTLS_GCM_ALT
//#define MBEDTLS_NIST_KW_ALT
//#define MBEDTLS_MD2_ALT
//#define MBEDTLS_MD4_ALT
//#define MBEDTLS_MD5_ALT
//#define MBEDTLS_POLY1305_ALT
//#define MBEDTLS_RIPEMD160_ALT
//#define MBEDTLS_RSA_ALT
//#define MBEDTLS_SHA1_ALT
//#define MBEDTLS_SHA256_ALT
//#define MBEDTLS_SHA512_ALT
//#define MBEDTLS_XTEA_ALT
/*
* When replacing the elliptic curve module, pleace consider, that it is
* implemented with two .c files:
@ -509,6 +550,20 @@
*/
#define MBEDTLS_CIPHER_MODE_CTR
/**
* \def MBEDTLS_CIPHER_MODE_OFB
*
* Enable Output Feedback mode (OFB) for symmetric ciphers.
*/
#define MBEDTLS_CIPHER_MODE_OFB
/**
* \def MBEDTLS_CIPHER_MODE_XTS
*
* Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
*/
#define MBEDTLS_CIPHER_MODE_XTS
/**
* \def MBEDTLS_CIPHER_NULL_CIPHER
*
@ -622,6 +677,26 @@
*/
#define MBEDTLS_ECP_NIST_OPTIM
/**
* \def MBEDTLS_ECP_RESTARTABLE
*
* Enable "non-blocking" ECC operations that can return early and be resumed.
*
* This allows various functions to pause by returning
* #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
* order to further progress and eventually complete their operation. This is
* controlled through mbedtls_ecp_set_max_ops() which limits the maximum
* number of ECC operations a function may perform before pausing; see
* mbedtls_ecp_set_max_ops() for more information.
*
* This is useful in non-threaded environments if you want to avoid blocking
* for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
*
* Uncomment this macro to enable restartable ECC computations.
*/
//#define MBEDTLS_ECP_RESTARTABLE
/**
* \def MBEDTLS_ECDSA_DETERMINISTIC
*
@ -1128,6 +1203,17 @@
*/
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
/**
* \def MBEDTLS_SSL_ASYNC_PRIVATE
*
* Enable asynchronous external private key operations in SSL. This allows
* you to configure an SSL connection to call an external cryptographic
* module to perform private key operations instead of performing the
* operation inside the library.
*
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/**
* \def MBEDTLS_SSL_DEBUG_ALL
*
@ -1617,7 +1703,7 @@
* Enable the AES block cipher.
*
* Module: library/aes.c
* Caller: library/ssl_tls.c
* Caller: library/cipher.c
* library/pem.c
* library/ctr_drbg.c
*
@ -1692,7 +1778,7 @@
* Enable the ARCFOUR stream cipher.
*
* Module: library/arc4.c
* Caller: library/ssl_tls.c
* Caller: library/cipher.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
@ -1786,7 +1872,7 @@
* Enable the Camellia block cipher.
*
* Module: library/camellia.c
* Caller: library/ssl_tls.c
* Caller: library/cipher.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
@ -1835,6 +1921,58 @@
*/
#define MBEDTLS_CAMELLIA_C
/**
* \def MBEDTLS_ARIA_C
*
* Enable the ARIA block cipher.
*
* Module: library/aria.c
* Caller: library/cipher.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
*
* MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
* MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
* MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
*/
//#define MBEDTLS_ARIA_C
/**
* \def MBEDTLS_CCM_C
*
@ -1861,6 +1999,26 @@
*/
#define MBEDTLS_CERTS_C
/**
* \def MBEDTLS_CHACHA20_C
*
* Enable the ChaCha20 stream cipher.
*
* Module: library/chacha20.c
*/
#define MBEDTLS_CHACHA20_C
/**
* \def MBEDTLS_CHACHAPOLY_C
*
* Enable the ChaCha20-Poly1305 AEAD algorithm.
*
* Module: library/chachapoly.c
*
* This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
*/
#define MBEDTLS_CHACHAPOLY_C
/**
* \def MBEDTLS_CIPHER_C
*
@ -1889,14 +2047,16 @@
/**
* \def MBEDTLS_CTR_DRBG_C
*
* Enable the CTR_DRBG AES-256-based random generator.
* 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-256 random number generator.
* This module provides the CTR_DRBG AES random number generator.
*/
#define MBEDTLS_CTR_DRBG_C
@ -1921,7 +2081,7 @@
*
* Module: library/des.c
* Caller: library/pem.c
* library/ssl_tls.c
* library/cipher.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
@ -2091,6 +2251,21 @@
*/
//#define MBEDTLS_HAVEGE_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
/**
* \def MBEDTLS_HMAC_DRBG_C
*
@ -2105,6 +2280,19 @@
*/
#define MBEDTLS_HMAC_DRBG_C
/**
* \def MBEDTLS_NIST_KW_C
*
* Enable the Key Wrapping mode for 128-bit block ciphers,
* as defined in NIST SP 800-38F. Only KW and KWP modes
* are supported. At the moment, only AES is approved by NIST.
*
* Module: library/nist_kw.c
*
* Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
*/
//#define MBEDTLS_NIST_KW_C
/**
* \def MBEDTLS_MD_C
*
@ -2388,6 +2576,16 @@
*/
#define MBEDTLS_PLATFORM_C
/**
* \def MBEDTLS_POLY1305_C
*
* Enable the Poly1305 MAC algorithm.
*
* Module: library/poly1305.c
* Caller: library/chachapoly.c
*/
#define MBEDTLS_POLY1305_C
/**
* \def MBEDTLS_RIPEMD160_C
*
@ -2743,6 +2941,7 @@
//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
/* HMAC_DRBG options */
//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
@ -2798,7 +2997,68 @@
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
/* SSL options */
//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
*
* Maximum fragment length in bytes.
*
* Determines the size of both the incoming and outgoing TLS I/O buffers.
*
* Uncommenting MBEDTLS_SSL_IN_CONTENT_LEN and/or MBEDTLS_SSL_OUT_CONTENT_LEN
* will override this length by setting maximum incoming and/or outgoing
* fragment length, respectively.
*/
//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384
/** \def MBEDTLS_SSL_IN_CONTENT_LEN
*
* Maximum incoming fragment length in bytes.
*
* Uncomment to set the size of the inward TLS buffer independently of the
* outward buffer.
*/
//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384
/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
*
* Maximum outgoing fragment length in bytes.
*
* Uncomment to set the size of the outward TLS buffer independently of the
* inward buffer.
*
* It is possible to save RAM by setting a smaller outward buffer, while keeping
* the default inward 16384 byte buffer to conform to the TLS specification.
*
* The minimum required outward buffer size is determined by the handshake
* protocol's usage. Handshaking will fail if the outward buffer is too small.
* The specific size requirement depends on the configured ciphers and any
* certificate data which is sent during the handshake.
*
* For absolute minimum RAM usage, it's best to enable
* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH and reduce MBEDTLS_SSL_MAX_CONTENT_LEN. This
* reduces both incoming and outgoing buffer sizes. However this is only
* guaranteed if the other end of the connection also supports the TLS
* max_fragment_len extension. Otherwise the connection may fail.
*/
//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384
/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
*
* Maximum number of heap-allocated bytes for the purpose of
* DTLS handshake message reassembly and future message buffering.
*
* This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
* to account for a reassembled handshake message of maximum size,
* together with its reassembly bitmap.
*
* A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
* should be sufficient for all practical situations as it allows
* to reassembly a large handshake message (such as a certificate)
* while buffering multiple smaller handshake messages.
*
*/
//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
@ -2872,25 +3132,33 @@
*/
//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
/**
* Uncomment the macro to let Mbed TLS use your alternate implementation of
* mbedtls_platform_gmtime_r(). This replaces the default implementation in
* platform_util.c.
*
* gmtime() is not a thread-safe function as defined in the C standard. The
* library will try to use safer implementations of this function, such as
* gmtime_r() when available. However, if Mbed TLS cannot identify the target
* system, the implementation of mbedtls_platform_gmtime_r() will default to
* using the standard gmtime(). In this case, calls from the library to
* gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
* if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
* library are also guarded with this mutex to avoid race conditions. However,
* if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
* unconditionally use the implementation for mbedtls_platform_gmtime_r()
* supplied at compile time.
*/
//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
/* \} name SECTION: Customisation configuration options */
/* Target and application specific configurations */
//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h"
#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE
#endif
/*
/* Target and application specific configurations
*
* Allow user to override any previous default.
*
* Use two macro names for that, as:
* - with yotta the prefix YOTTA_CFG_ is forced
* - without yotta is looks weird to have a YOTTA prefix.
*/
#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
#elif defined(MBEDTLS_USER_CONFIG_FILE)
#if defined(MBEDTLS_USER_CONFIG_FILE)
#include MBEDTLS_USER_CONFIG_FILE
#endif

View file

@ -8,8 +8,11 @@
* Recommendation for Random Number Generation Using Deterministic Random
* Bit Generators</em>.
*
* The Mbed TLS implementation of CTR_DRBG uses AES-256 as the underlying
* block cipher.
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* as the underlying block cipher.
*
* \warning Using 128-bit keys for CTR_DRBG limits the security of generated
* keys and operations that use random values generated to 128-bit security.
*/
/*
* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
@ -36,7 +39,7 @@
#include "aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#include "threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
@ -45,7 +48,13 @@
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read or write error in file. */
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher. */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#define MBEDTLS_CTR_DRBG_KEYSIZE 16 /**< The key size used by the cipher (compile-time choice: 128 bits). */
#else
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher (compile-time choice: 256 bits). */
#endif
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
@ -108,7 +117,7 @@ extern "C" {
/**
* \brief The CTR_DRBG context structure.
*/
typedef struct
typedef struct mbedtls_ctr_drbg_context
{
unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< The reseed counter. */

View file

@ -61,7 +61,7 @@ extern "C" {
* security risk. We recommend considering stronger ciphers
* instead.
*/
typedef struct
typedef struct mbedtls_des_context
{
uint32_t sk[32]; /*!< DES subkeys */
}
@ -70,7 +70,7 @@ mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
typedef struct mbedtls_des3_context
{
uint32_t sk[96]; /*!< 3DES subkeys */
}

View file

@ -96,7 +96,7 @@ extern "C" {
/**
* \brief The DHM context structure.
*/
typedef struct
typedef struct mbedtls_dhm_context
{
size_t len; /*!< The size of \p P in Bytes. */
mbedtls_mpi P; /*!< The prime modulus. */

View file

@ -50,9 +50,13 @@ typedef enum
} mbedtls_ecdh_side;
/**
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
* \brief The ECDH context structure.
*/
typedef struct
typedef struct mbedtls_ecdh_context
{
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
@ -63,6 +67,10 @@ typedef struct
mbedtls_ecp_point Vi; /*!< The blinding value. */
mbedtls_ecp_point Vf; /*!< The unblinding value. */
mbedtls_mpi _d; /*!< The previous \p d. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
int restart_enabled; /*!< The flag for restartable mode. */
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif
}
mbedtls_ecdh_context;
@ -83,9 +91,8 @@ mbedtls_ecdh_context;
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
@ -112,7 +119,7 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or
* \return Another \c MBEDTLS_ERR_ECP_XXX or
* \c MBEDTLS_MPI_XXX error code on failure.
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
@ -155,7 +162,9 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
@ -197,7 +206,7 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
* 0: The key of the peer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
@ -220,7 +229,9 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypai
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
@ -266,13 +277,31 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief This function enables restartable EC computations for this
* context. (Default: disabled.)
*
* \see \c mbedtls_ecp_set_max_ops()
*
* \note It is not possible to safely disable restartable
* computations once enabled, except by free-ing the context,
* which cancels possible in-progress operations.
*
* \param ctx The ECDH context.
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif

View file

@ -55,15 +55,65 @@
/** The maximal size of an ECDSA signature in Bytes. */
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
/**
* \brief The ECDSA context structure.
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The ECDSA context structure.
*
* \warning Performing multiple operations concurrently on the same
* ECDSA context is not supported; objects of this type
* should not be shared between multiple threads.
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Internal restart context for ecdsa_verify()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
/**
* \brief Internal restart context for ecdsa_sign()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief Internal restart context for ecdsa_sign_det()
*
* \note Opaque struct, defined in ecdsa.c
*/
typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
#endif
/**
* \brief General context for resuming ECDSA operations
*/
typedef struct
{
mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and
shared administrative info */
mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */
mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */
#endif
} mbedtls_ecdsa_restart_ctx;
#else /* MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_ecdsa_restart_ctx;
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
@ -205,6 +255,40 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, in a restartable way.
*
* \see \c mbedtls_ecdsa_write_signature()
*
* \note This function is like \c mbedtls_ecdsa_write_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context.
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash.
* \param hlen The length of the hash.
* \param sig The buffer that holds the signature.
* \param slen The length of the signature written.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
@ -288,6 +372,37 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen );
/**
* \brief This function reads and verifies an ECDSA signature,
* in a restartable way.
*
* \see \c mbedtls_ecdsa_read_signature()
*
* \note This function is like \c mbedtls_ecdsa_read_signature()
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param ctx The ECDSA context.
* \param hash The message hash.
* \param hlen The size of the hash.
* \param sig The signature to read and verify.
* \param slen The size of \p sig.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
* signature in \p sig, but its length is less than \p siglen.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*/
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx );
/**
* \brief This function generates an ECDSA keypair on the given curve.
*
@ -332,6 +447,18 @@ void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif

View file

@ -68,7 +68,7 @@ typedef enum {
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct
typedef struct mbedtls_ecjpake_context
{
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */

View file

@ -50,6 +50,7 @@
#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< The buffer contains a valid signature followed by more data. */
#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 /**< The ECP hardware accelerator failed. */
#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */
#ifdef __cplusplus
extern "C" {
@ -92,7 +93,7 @@ typedef enum
/**
* Curve information, for use by other modules.
*/
typedef struct
typedef struct mbedtls_ecp_curve_info
{
mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */
uint16_t tls_id; /*!< The TLS NamedCurve identifier. */
@ -111,7 +112,7 @@ typedef struct
* Otherwise, \p X and \p Y are its standard (affine)
* coordinates.
*/
typedef struct
typedef struct mbedtls_ecp_point
{
mbedtls_mpi X; /*!< The X coordinate of the ECP point. */
mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */
@ -156,7 +157,7 @@ mbedtls_ecp_point;
* reduction. It must return 0 on success and non-zero on failure.
*
*/
typedef struct
typedef struct mbedtls_ecp_group
{
mbedtls_ecp_group_id id; /*!< An internal group identifier. */
mbedtls_mpi P; /*!< The prime modulus of the base field. */
@ -181,6 +182,70 @@ typedef struct
}
mbedtls_ecp_group;
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Internal restart context for multiplication
*
* \note Opaque struct
*/
typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx;
/**
* \brief Internal restart context for ecp_muladd()
*
* \note Opaque struct
*/
typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx;
/**
* \brief General context for resuming ECC operations
*/
typedef struct
{
unsigned ops_done; /*!< current ops count */
unsigned depth; /*!< call depth (0 = top-level) */
mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */
mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */
} mbedtls_ecp_restart_ctx;
/*
* Operation counts for restartable functions
*/
#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */
#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */
#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */
#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */
/**
* \brief Internal; for restartable functions in other modules.
* Check and update basic ops budget.
*
* \param grp Group structure
* \param rs_ctx Restart context
* \param ops Number of basic ops to do
*
* \return \c 0 if doing \p ops basic ops is still allowed,
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise.
*/
int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
mbedtls_ecp_restart_ctx *rs_ctx,
unsigned ops );
/* Utility macro for checking and updating ops budget */
#define MBEDTLS_ECP_BUDGET( ops ) \
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \
(unsigned) (ops) ) );
#else /* MBEDTLS_ECP_RESTARTABLE */
#define MBEDTLS_ECP_BUDGET( ops ) /* no-op; for compatibility */
/* We want to declare restartable versions of existing functions anyway */
typedef void mbedtls_ecp_restart_ctx;
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \name SECTION: Module settings
*
@ -251,7 +316,7 @@ mbedtls_ecp_group;
* \note Members are deliberately in the same order as in the
* ::mbedtls_ecdsa_context structure.
*/
typedef struct
typedef struct mbedtls_ecp_keypair
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
@ -270,6 +335,75 @@ mbedtls_ecp_keypair;
*/
#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Set the maximum number of basic operations done in a row.
*
* If more operations are needed to complete a computation,
* #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the
* function performing the computation. It is then the
* caller's responsibility to either call again with the same
* parameters until it returns 0 or an error code; or to free
* the restart context if the operation is to be aborted.
*
* It is strictly required that all input parameters and the
* restart context be the same on successive calls for the
* same operation, but output parameters need not be the
* same; they must not be used until the function finally
* returns 0.
*
* This only applies to functions whose documentation
* mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the
* SSL module). For functions that accept a "restart context"
* argument, passing NULL disables restart and makes the
* function equivalent to the function with the same name
* with \c _restartable removed. For functions in the ECDH
* module, restart is disabled unless the function accepts
* an "ECDH context" argument and
* mbedtls_ecdh_enable_restart() was previously called on
* that context. For function in the SSL module, restart is
* only enabled for specific sides and key exchanges
* (currently only for clients and ECDHE-ECDSA).
*
* \param max_ops Maximum number of basic operations done in a row.
* Default: 0 (unlimited).
* Lower (non-zero) values mean ECC functions will block for
* a lesser maximum amount of time.
*
* \note A "basic operation" is defined as a rough equivalent of a
* multiplication in GF(p) for the NIST P-256 curve.
* As an indication, with default settings, a scalar
* multiplication (full run of \c mbedtls_ecp_mul()) is:
* - about 3300 basic operations for P-256
* - about 9400 basic operations for P-384
*
* \note Very low values are not always respected: sometimes
* functions need to block for a minimum number of
* operations, and will do so even if max_ops is set to a
* lower value. That minimum depends on the curve size, and
* can be made lower by decreasing the value of
* \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the
* lowest effective value for various curves and values of
* that parameter (w for short):
* w=6 w=5 w=4 w=3 w=2
* P-256 208 208 160 136 124
* P-384 682 416 320 272 248
* P-521 1364 832 640 544 496
*
* \note This setting is currently ignored by Curve25519.
*/
void mbedtls_ecp_set_max_ops( unsigned max_ops );
/**
* \brief Check if restart is enabled (max_ops != 0)
*
* \return \c 0 if \c max_ops == 0 (restart disabled)
* \return \c 1 otherwise (restart enabled)
*/
int mbedtls_ecp_restart_is_enabled( void );
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \brief This function retrieves the information defined in
* mbedtls_ecp_curve_info() for all supported curves in order
@ -366,6 +500,18 @@ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
*/
void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*/
void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*/
void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
* \brief This function copies the contents of point \p Q into
* point \p P.
@ -597,6 +743,36 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief This function performs multiplication of a point by
* an integer: \p R = \p m * \p P in a restartable way.
*
* \see mbedtls_ecp_mul()
*
* \note This function does the same as \c mbedtls_ecp_mul(), but
* it can return early and restart according to the limit set
* with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param grp The ECP group.
* \param R The destination point.
* \param m The integer by which to multiply.
* \param P The point to multiply.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
* key, or \p P is not a valid public key.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx );
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@ -623,6 +799,39 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q );
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q in a
* restartable way.
*
* \see \c mbedtls_ecp_muladd()
*
* \note This function works the same as \c mbedtls_ecp_muladd(),
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param grp The ECP group.
* \param R The destination point.
* \param m The integer by which to multiply \p P.
* \param P The point to multiply by \p m.
* \param n The integer by which to multiply \p Q.
* \param Q The point to be multiplied by \p n.
* \param rs_ctx The restart context (NULL disables restart).
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_ecp_muladd_restartable(
mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx );
/**
* \brief This function checks that a point is a valid public key
* on this curve.
@ -665,6 +874,23 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_po
*/
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
/**
* \brief This function generates a private key.
*
* \param grp The ECP group.
* \param d The destination MPI (secret part).
* \param f_rng The RNG function.
* \param p_rng The RNG parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
* on failure.
*/
int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function generates a keypair with a configurable base
* point.

View file

@ -107,7 +107,7 @@ typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, s
/**
* \brief Entropy source state
*/
typedef struct
typedef struct mbedtls_entropy_source_state
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
@ -120,7 +120,7 @@ mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct
typedef struct mbedtls_entropy_context
{
int accumulator_started;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)

View file

@ -4,7 +4,7 @@
* \brief Error to string translation
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -53,7 +53,7 @@
* GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
* THREADING 3 0x001A-0x001E
* AES 4 0x0020-0x0022 0x0023-0x0025
* AES 5 0x0020-0x0022 0x0021-0x0025
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
* XTEA 2 0x0028-0x0028 0x0029-0x0029
* BASE64 2 0x002A-0x002C
@ -62,7 +62,8 @@
* DES 2 0x0032-0x0032 0x0033-0x0033
* CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 11 0x0042-0x0052 0x0043-0x0045
* NET 13 0x0042-0x0052 0x0043-0x0049
* ARIA 4 0x0058-0x005E
* ASN1 7 0x0060-0x006C
* CMAC 1 0x007A-0x007A
* PBKDF2 1 0x007C-0x007C
@ -76,6 +77,10 @@
* SHA1 1 0x0035-0x0035
* SHA256 1 0x0037-0x0037
* SHA512 1 0x0039-0x0039
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056
* PLATFORM 1 0x0070-0x0070
*
* High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors
@ -86,11 +91,12 @@
* DHM 3 11
* PK 3 15 (Started from top)
* RSA 4 11
* ECP 4 9 (Started from top)
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* CIPHER 6 8
* SSL 6 17 (Started from top)
* SSL 7 31
* SSL 6 23 (Started from top)
* SSL 7 32
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/

View file

@ -53,7 +53,8 @@ extern "C" {
/**
* \brief The GCM context structure.
*/
typedef struct {
typedef struct mbedtls_gcm_context
{
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
uint64_t HL[16]; /*!< Precalculated HTable low. */
uint64_t HH[16]; /*!< Precalculated HTable high. */
@ -113,21 +114,41 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
* the same as input buffer. If the buffers overlap, the output
* buffer must trail at least 8 Bytes behind the input buffer.
*
* \warning When this function performs a decryption, it outputs the
* authentication tag and does not verify that the data is
* authentic. You should use this function to perform encryption
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
*
* \param ctx The GCM context to use for encryption or decryption.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param length The length of the input data. This must be a multiple of
* 16 except in the last call before mbedtls_gcm_finish().
* \param mode The operation to perform:
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
* The ciphertext is written to \p output and the
* authentication tag is written to \p tag.
* - #MBEDTLS_GCM_DECRYPT to perform decryption.
* The plaintext is written to \p output and the
* authentication tag is written to \p tag.
* Note that this mode is not recommended, because it does
* not verify the authenticity of the data. For this reason,
* you should use mbedtls_gcm_auth_decrypt() instead of
* calling this function in decryption mode.
* \param length The length of the input data, which is equal to the length
* of the output data.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
* \param input The buffer holding the input data. Its size is \b length.
* \param output The buffer for holding the output data. It must have room
* for \b length bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag.
*
* \return \c 0 on success.
* \return \c 0 if the encryption or decryption was performed
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
* this does not indicate that the data is authentic.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the encryption or decryption failed.
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
@ -150,19 +171,23 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context.
* \param length The length of the input data. This must be a multiple
* of 16 except in the last call before mbedtls_gcm_finish().
* \param length The length of the ciphertext to decrypt, which is also
* the length of the decrypted plaintext.
* \param iv The initialization vector.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data.
* \param add_len The length of the additional data.
* \param tag The buffer holding the tag.
* \param tag_len The length of the tag.
* \param input The buffer holding the input data.
* \param output The buffer for holding the output data.
* \param tag The buffer holding the tag to verify.
* \param tag_len The length of the tag to verify.
* \param input The buffer holding the ciphertext. Its size is \b length.
* \param output The buffer for holding the decrypted plaintext. It must
* have room for \b length bytes.
*
* \return 0 if successful and authenticated.
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
* \return \c 0 if successful and authenticated.
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid.
* \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific
* error code if the decryption failed.
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,

View file

@ -35,7 +35,7 @@ extern "C" {
/**
* \brief HAVEGE state structure
*/
typedef struct
typedef struct mbedtls_havege_state
{
int PT1, PT2, offset[2];
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];

135
include/mbedtls/hkdf.h Normal file
View file

@ -0,0 +1,135 @@
/**
* \file hkdf.h
*
* \brief This file contains the HKDF interface.
*
* The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
* specified by RFC 5869.
*/
/*
* Copyright (C) 2016-2018, 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 MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
#include "md.h"
/**
* \name HKDF Error codes
* \{
*/
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */
/* \} name */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
* (HKDF).
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros of
* md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len );
/**
* \brief Take the input keying material \p ikm and extract from it a
* fixed-length pseudorandom key \p prk.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the
* hash function output in bytes.
* \param salt An optional salt value (a non-secret random value);
* if the salt is not provided, a string of all zeros
* of md.size length is used as the salt.
* \param salt_len The length in bytes of the optional \p salt.
* \param ikm The input keying material.
* \param ikm_len The length in bytes of \p ikm.
* \param[out] prk A pseudorandom key of at least md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk );
/**
* \brief Expand the supplied \p prk into several additional pseudorandom
* keys, which is the output of the HKDF.
*
* \warning This function should only be used if the security of it has been
* studied and established in that particular context (eg. TLS 1.3
* key schedule). For standard HKDF security guarantees use
* \c mbedtls_hkdf instead.
*
* \param md A hash function; md.size denotes the length of the hash
* function output in bytes.
* \param prk A pseudorandom key of at least md.size bytes. \p prk is
* usually the output from the HKDF extract step.
* \param prk_len The length in bytes of \p prk.
* \param info An optional context and application specific information
* string. This can be a zero-length string.
* \param info_len The length of \p info in bytes.
* \param okm The output keying material of \p okm_len bytes.
* \param okm_len The length of the output keying material in bytes. This
* must be less than or equal to 255 * md.size bytes.
*
* \return 0 on success.
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
* MD layer.
*/
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len );
#ifdef __cplusplus
}
#endif
#endif /* hkdf.h */

View file

@ -27,7 +27,7 @@
#include "md.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#include "threading.h"
#endif
/*
@ -74,7 +74,7 @@ extern "C" {
/**
* HMAC_DRBG context.
*/
typedef struct
typedef struct mbedtls_hmac_drbg_context
{
/* Working state: the key K is not stored explicitely,
* but is implied by the HMAC context */

View file

@ -80,7 +80,8 @@ typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* The generic message-digest context.
*/
typedef struct {
typedef struct mbedtls_md_context_t
{
/** Information about the associated message digest. */
const mbedtls_md_info_t *md_info;

View file

@ -55,7 +55,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct
typedef struct mbedtls_md2_context
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */

View file

@ -56,7 +56,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct
typedef struct mbedtls_md4_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */

View file

@ -55,7 +55,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct
typedef struct mbedtls_md5_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */

View file

@ -1,7 +1,7 @@
/**
* \file net.h
*
* \brief Deprecated header file that includes mbedtls/net_sockets.h
* \brief Deprecated header file that includes net_sockets.h
*
* \deprecated Superseded by mbedtls/net_sockets.h
*/
@ -25,7 +25,7 @@
*/
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "mbedtls/net_sockets.h"
#include "net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */

View file

@ -1,7 +1,23 @@
/**
* \file net_sockets.h
*
* \brief Network communication functions
* \brief Network sockets abstraction layer to integrate Mbed TLS into a
* BSD-style sockets API.
*
* The network sockets module provides an example integration of the
* Mbed TLS library into a BSD sockets implementation. The module is
* intended to be an example of how Mbed TLS can be integrated into a
* networking stack, as well as to be Mbed TLS's network integration
* for its supported platforms.
*
* The module is intended only to be used with the Mbed TLS library and
* is not intended to be used by third party application software
* directly.
*
* The supported platforms are as follows:
* * Microsoft Windows and Windows CE
* * POSIX/Unix platforms including Linux, OS X
*
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@ -68,7 +84,7 @@ extern "C" {
* (eg two file descriptors for combined IPv4 + IPv6 support, or additional
* structures for hand-made UDP demultiplexing).
*/
typedef struct
typedef struct mbedtls_net_context
{
int fd; /**< The underlying file descriptor */
}

178
include/mbedtls/nist_kw.h Normal file
View file

@ -0,0 +1,178 @@
/**
* \file nist_kw.h
*
* \brief This file provides an API for key wrapping (KW) and key wrapping with
* padding (KWP) as defined in NIST SP 800-38F.
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
*
* Key wrapping specifies a deterministic authenticated-encryption mode
* of operation, according to <em>NIST SP 800-38F: Recommendation for
* Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its
* purpose is to protect cryptographic keys.
*
* Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP.
* https://tools.ietf.org/html/rfc3394
* https://tools.ietf.org/html/rfc5649
*
*/
/*
* Copyright (C) 2018, Arm Limited (or its affiliates), 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 MBEDTLS_NIST_KW_H
#define MBEDTLS_NIST_KW_H
#include "cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
MBEDTLS_KW_MODE_KW = 0,
MBEDTLS_KW_MODE_KWP = 1
} mbedtls_nist_kw_mode_t;
#if !defined(MBEDTLS_NIST_KW_ALT)
// Regular implementation
//
/**
* \brief The key wrapping context-type definition. The key wrapping context is passed
* to the APIs called.
*
* \note The definition of this type may change in future library versions.
* Don't make any assumptions on this context!
*/
typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
} mbedtls_nist_kw_context;
#else /* MBEDTLS_NIST_key wrapping_ALT */
#include "nist_kw_alt.h"
#endif /* MBEDTLS_NIST_KW_ALT */
/**
* \brief This function initializes the specified key wrapping context
* to make references valid and prepare the context
* for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free().
*
* \param ctx The key wrapping context to initialize.
*
*/
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx );
/**
* \brief This function initializes the key wrapping context set in the
* \p ctx parameter and sets the encryption key.
*
* \param ctx The key wrapping context.
* \param cipher The 128-bit block cipher to use. Only AES is supported.
* \param key The Key Encryption Key (KEK).
* \param keybits The KEK size in bits. This must be acceptable by the cipher.
* \param is_wrap Specify whether the operation within the context is wrapping or unwrapping
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input.
* \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers
* which are not supported.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits,
const int is_wrap );
/**
* \brief This function releases and clears the specified key wrapping context
* and underlying cipher sub-context.
*
* \param ctx The key wrapping context to clear.
*/
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx );
/**
* \brief This function encrypts a buffer using key wrapping.
*
* \param ctx The key wrapping context to use for encryption.
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
* \param input The buffer holding the input data.
* \param in_len The length of the input data in Bytes.
* The input uses units of 8 Bytes called semiblocks.
* <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li>
* <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul>
* \param[out] output The buffer holding the output data.
* <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li>
* <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of
* 8 bytes for KWP (15 bytes at most).</li></ul>
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
* \param[in] out_size The capacity of the output buffer.
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t* out_len, size_t out_size );
/**
* \brief This function decrypts a buffer using key wrapping.
*
* \param ctx The key wrapping context to use for decryption.
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
* \param input The buffer holding the input data.
* \param in_len The length of the input data in Bytes.
* The input uses units of 8 Bytes called semiblocks.
* The input must be a multiple of semiblocks.
* <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li>
* <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul>
* \param[out] output The buffer holding the output data.
* The output buffer's minimal length is 8 bytes shorter than \p in_len.
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
* For KWP mode, the length could be up to 15 bytes shorter than \p in_len,
* depending on how much padding was added to the data.
* \param[in] out_size The capacity of the output buffer.
*
* \return \c 0 on success.
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
* \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext.
* \return cipher-specific error code on failure of the underlying cipher.
*/
int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t* out_len, size_t out_size);
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**
* \brief The key wrapping checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_nist_kw_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_NIST_KW_H */

View file

@ -97,6 +97,8 @@
/* ISO arc for standard certificate and CRL extensions */
#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
/**
* Private Internet Extensions
* { iso(1) identified-organization(3) dod(6) internet(1)
@ -219,12 +221,12 @@
#define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
@ -241,7 +243,20 @@
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
/*
* Key Wrapping algorithms
*/
/*
* RFC 5649
*/
#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */
#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */
#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */
#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
/*
* PKCS#5 OIDs
*/
@ -388,7 +403,8 @@ extern "C" {
/**
* \brief Base OID descriptor structure
*/
typedef struct {
typedef struct mbedtls_oid_descriptor_t
{
const char *asn1; /*!< OID ASN.1 representation */
size_t asn1_len; /*!< length of asn1 */
const char *name; /*!< official name (e.g. from RFC) */

View file

@ -51,7 +51,7 @@ extern "C" {
/**
* \brief PEM context structure
*/
typedef struct
typedef struct mbedtls_pem_context
{
unsigned char *buf; /*!< buffer for decoded data */
size_t buflen; /*!< length of the buffer */

View file

@ -87,7 +87,7 @@ typedef enum {
* \brief Options for RSASSA-PSS signature verification.
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
*/
typedef struct
typedef struct mbedtls_pk_rsassa_pss_options
{
mbedtls_md_type_t mgf1_hash_id;
int expected_salt_len;
@ -107,7 +107,7 @@ typedef enum
/**
* \brief Item to send to the debug module
*/
typedef struct
typedef struct mbedtls_pk_debug_item
{
mbedtls_pk_debug_type type;
const char *name;
@ -125,12 +125,26 @@ typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
/**
* \brief Public key container
*/
typedef struct
typedef struct mbedtls_pk_context
{
const mbedtls_pk_info_t * pk_info; /**< Public key informations */
const mbedtls_pk_info_t * pk_info; /**< Public key information */
void * pk_ctx; /**< Underlying public key context */
} mbedtls_pk_context;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Context for resuming operations
*/
typedef struct
{
const mbedtls_pk_info_t * pk_info; /**< Public key information */
void * rs_ctx; /**< Underlying restart context */
} mbedtls_pk_restart_ctx;
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_pk_restart_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#if defined(MBEDTLS_RSA_C)
/**
* Quick access to an RSA context inside a PK context.
@ -190,6 +204,18 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx );
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*/
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/**
* \brief Initialize a PK context with the information given
* and allocates the type-specific PK subcontext.
@ -286,6 +312,32 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len );
/**
* \brief Restartable version of \c mbedtls_pk_verify()
*
* \note Performs the same job as \c mbedtls_pk_verify(), but can
* return early and restart according to the limit set with
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_verify().
*
* \param ctx PK context to use
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes)
* \param sig Signature to verify
* \param sig_len Signature length
* \param rs_ctx Restart context (NULL to disable restart)
*
* \return See \c mbedtls_pk_verify(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
mbedtls_pk_restart_ctx *rs_ctx );
/**
* \brief Verify signature, with options.
* (Includes verification of the padding depending on type.)
@ -349,6 +401,35 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Restartable version of \c mbedtls_pk_sign()
*
* \note Performs the same job as \c mbedtls_pk_sign(), but can
* return early and restart according to the limit set with
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_sign().
*
* \param ctx PK context to use - must hold a private key
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes)
* \param sig Place to write the signature
* \param sig_len Number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
* \param rs_ctx Restart context (NULL to disable restart)
*
* \return See \c mbedtls_pk_sign(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx );
/**
* \brief Decrypt message (including padding if relevant).
*

View file

@ -59,6 +59,21 @@ struct mbedtls_pk_info_t
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/** Verify signature (restartable) */
int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx );
/** Make signature (restartable) */
int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng, void *rs_ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/** Decrypt message */
int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
@ -80,6 +95,14 @@ struct mbedtls_pk_info_t
/** Free the given context */
void (*ctx_free_func)( void *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/** Allocate the restart context */
void * (*rs_alloc_func)( void );
/** Free the restart context */
void (*rs_free_func)( void *rs_ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/** Interface with the debug module */
void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items );

View file

@ -50,7 +50,8 @@ extern "C" {
/**
* Context for PKCS #11 private keys.
*/
typedef struct {
typedef struct mbedtls_pkcs11_context
{
pkcs11h_certificate_t pkcs11h_cert;
int len;
} mbedtls_pkcs11_context;

View file

@ -40,9 +40,11 @@
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#include "platform_time.h"
#endif
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
@ -121,8 +123,8 @@ extern "C" {
#else
/* For size_t */
#include <stddef.h>
extern void * (*mbedtls_calloc)( size_t n, size_t size );
extern void (*mbedtls_free)( void *ptr );
extern void *mbedtls_calloc( size_t n, size_t size );
extern void mbedtls_free( void *ptr );
/**
* \brief This function dynamically sets the memory-management
@ -315,7 +317,8 @@ int mbedtls_platform_set_nv_seed(
* \note This structure may be used to assist platform-specific
* setup or teardown operations.
*/
typedef struct {
typedef struct mbedtls_platform_context
{
char dummy; /**< A placeholder member, as empty structs are not portable. */
}
mbedtls_platform_context;

View file

@ -25,7 +25,17 @@
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include "mbedtls/platform_time.h"
#include <time.h>
#endif /* MBEDTLS_HAVE_TIME_DATE */
#ifdef __cplusplus
extern "C" {
@ -55,6 +65,37 @@ extern "C" {
*/
void mbedtls_platform_zeroize( void *buf, size_t len );
#if defined(MBEDTLS_HAVE_TIME_DATE)
/**
* \brief Platform-specific implementation of gmtime_r()
*
* The function is a thread-safe abstraction that behaves
* similarly to the gmtime_r() function from Unix/POSIX.
*
* Mbed TLS will try to identify the underlying platform and
* make use of an appropriate underlying implementation (e.g.
* gmtime_r() for POSIX and gmtime_s() for Windows). If this is
* not possible, then gmtime() will be used. In this case, calls
* from the library to gmtime() will be guarded by the mutex
* mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
* enabled. It is recommended that calls from outside the library
* are also guarded by this mutex.
*
* If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
* unconditionally use the alternative implementation for
* mbedtls_platform_gmtime_r() supplied by the user at compile time.
*
* \param tt Pointer to an object containing time (in seconds) since the
* epoch to be converted
* \param tm_buf Pointer to an object where the results will be stored
*
* \return Pointer to an object of type struct tm on success, otherwise
* NULL
*/
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf );
#endif /* MBEDTLS_HAVE_TIME_DATE */
#ifdef __cplusplus
}
#endif

181
include/mbedtls/poly1305.h Normal file
View file

@ -0,0 +1,181 @@
/**
* \file poly1305.h
*
* \brief This file contains Poly1305 definitions and functions.
*
* Poly1305 is a one-time message authenticator that can be used to
* authenticate messages. Poly1305-AES was created by Daniel
* Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic
* Poly1305 algorithm (not tied to AES) was also standardized in RFC
* 7539.
*
* \author Daniel King <damaki.gh@gmail.com>
*/
/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), 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 MBEDTLS_POLY1305_H
#define MBEDTLS_POLY1305_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdint.h>
#include <stddef.h>
#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 /**< Invalid input parameter(s). */
#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */
#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED -0x005B /**< Poly1305 hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_POLY1305_ALT)
typedef struct mbedtls_poly1305_context
{
uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */
uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */
uint32_t acc[5]; /** The accumulator number. */
uint8_t queue[16]; /** The current partial block of data. */
size_t queue_len; /** The number of bytes stored in 'queue'. */
}
mbedtls_poly1305_context;
#else /* MBEDTLS_POLY1305_ALT */
#include "poly1305_alt.h"
#endif /* MBEDTLS_POLY1305_ALT */
/**
* \brief This function initializes the specified Poly1305 context.
*
* It must be the first API called before using
* the context.
*
* It is usually followed by a call to
* \c mbedtls_poly1305_starts(), then one or more calls to
* \c mbedtls_poly1305_update(), then one call to
* \c mbedtls_poly1305_finish(), then finally
* \c mbedtls_poly1305_free().
*
* \param ctx The Poly1305 context to initialize.
*/
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx );
/**
* \brief This function releases and clears the specified Poly1305 context.
*
* \param ctx The Poly1305 context to clear.
*/
void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx );
/**
* \brief This function sets the one-time authentication key.
*
* \warning The key must be unique and unpredictable for each
* invocation of Poly1305.
*
* \param ctx The Poly1305 context to which the key should be bound.
* \param key The buffer containing the 256-bit key.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if ctx or key are NULL.
*/
int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
const unsigned char key[32] );
/**
* \brief This functions feeds an input buffer into an ongoing
* Poly1305 computation.
*
* It is called between \c mbedtls_cipher_poly1305_starts() and
* \c mbedtls_cipher_poly1305_finish().
* It can be called repeatedly to process a stream of data.
*
* \param ctx The Poly1305 context to use for the Poly1305 operation.
* \param ilen The length of the input data (in bytes). Any value is accepted.
* \param input The buffer holding the input data.
* This pointer can be NULL if ilen == 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if ctx or input are NULL.
*/
int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief This function generates the Poly1305 Message
* Authentication Code (MAC).
*
* \param ctx The Poly1305 context to use for the Poly1305 operation.
* \param mac The buffer to where the MAC is written. Must be big enough
* to hold the 16-byte MAC.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if ctx or mac are NULL.
*/
int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
unsigned char mac[16] );
/**
* \brief This function calculates the Poly1305 MAC of the input
* buffer with the provided key.
*
* \warning The key must be unique and unpredictable for each
* invocation of Poly1305.
*
* \param key The buffer containing the 256-bit key.
* \param ilen The length of the input data (in bytes). Any value is accepted.
* \param input The buffer holding the input data.
* This pointer can be NULL if ilen == 0.
* \param mac The buffer to where the MAC is written. Must be big enough
* to hold the 16-byte MAC.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
* if key, input, or mac are NULL.
*/
int mbedtls_poly1305_mac( const unsigned char key[32],
const unsigned char *input,
size_t ilen,
unsigned char mac[16] );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The Poly1305 checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_poly1305_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_POLY1305_H */

View file

@ -46,7 +46,7 @@ extern "C" {
/**
* \brief RIPEMD-160 context structure
*/
typedef struct
typedef struct mbedtls_ripemd160_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */

View file

@ -92,7 +92,7 @@ extern "C" {
* is deprecated. All manipulation should instead be done through
* the public interface functions.
*/
typedef struct
typedef struct mbedtls_rsa_context
{
int ver; /*!< Always 0.*/
size_t len; /*!< The size of \p N in Bytes. */

View file

@ -58,7 +58,7 @@ extern "C" {
* stronger message digests instead.
*
*/
typedef struct
typedef struct mbedtls_sha1_context
{
uint32_t total[2]; /*!< The number of Bytes processed. */
uint32_t state[5]; /*!< The intermediate digest state. */

View file

@ -53,7 +53,7 @@ extern "C" {
* checksum calculations. The choice between these two is
* made in the call to mbedtls_sha256_starts_ret().
*/
typedef struct
typedef struct mbedtls_sha256_context
{
uint32_t total[2]; /*!< The number of Bytes processed. */
uint32_t state[8]; /*!< The intermediate digest state. */

View file

@ -52,7 +52,7 @@ extern "C" {
* checksum calculations. The choice between these two is
* made in the call to mbedtls_sha512_starts_ret().
*/
typedef struct
typedef struct mbedtls_sha512_context
{
uint64_t total[2]; /*!< The number of Bytes processed. */
uint64_t state[8]; /*!< The intermediate digest state. */

View file

@ -62,7 +62,7 @@
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#include "platform_time.h"
#endif
/*
@ -120,6 +120,9 @@
#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */
#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */
#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */
#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */
/*
* Various constants
@ -219,7 +222,7 @@
#endif
/*
* Maxium fragment length in bytes,
* Maximum fragment length in bytes,
* determines the size of each of the two internal I/O buffers.
*
* Note: the RFC defines the default size of SSL / TLS messages. If you
@ -233,6 +236,22 @@
#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */
#endif
#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN)
#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
#endif
#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN)
#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
#endif
/*
* Maximum number of heap-allocated bytes for the purpose of
* DTLS handshake message reassembly and future message buffering.
*/
#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING)
#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
#endif
/* \} name SECTION: Module settings */
/*
@ -536,7 +555,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx,
*/
typedef int mbedtls_ssl_get_timer_t( void * ctx );
/* Defined below */
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
typedef struct mbedtls_ssl_context mbedtls_ssl_context;
@ -553,6 +571,218 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Callback type: start external signature operation.
*
* This callback is called during an SSL handshake to start
* a signature decryption operation using an
* external processor. The parameter \p cert contains
* the public key; it is up to the callback function to
* determine how to access the associated private key.
*
* This function typically sends or enqueues a request, and
* does not wait for the operation to complete. This allows
* the handshake step to be non-blocking.
*
* The parameters \p ssl and \p cert are guaranteed to remain
* valid throughout the handshake. On the other hand, this
* function must save the contents of \p hash if the value
* is needed for later processing, because the \p hash buffer
* is no longer valid after this function returns.
*
* This function may call mbedtls_ssl_set_async_operation_data()
* to store an operation context for later retrieval
* by the resume or cancel callback.
*
* \note For RSA signatures, this function must produce output
* that is consistent with PKCS#1 v1.5 in the same way as
* mbedtls_rsa_pkcs1_sign(). Before the private key operation,
* apply the padding steps described in RFC 8017, section 9.2
* "EMSA-PKCS1-v1_5" as follows.
* - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5
* encoding, treating \p hash as the DigestInfo to be
* padded. In other words, apply EMSA-PKCS1-v1_5 starting
* from step 3, with `T = hash` and `tLen = hash_len`.
* - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5
* encoding, treating \p hash as the hash to be encoded and
* padded. In other words, apply EMSA-PKCS1-v1_5 starting
* from step 2, with `digestAlgorithm` obtained by calling
* mbedtls_oid_get_oid_by_md() on \p md_alg.
*
* \note For ECDSA signatures, the output format is the DER encoding
* `Ecdsa-Sig-Value` defined in
* [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4).
*
* \param ssl The SSL connection instance. It should not be
* modified other than via
* mbedtls_ssl_set_async_operation_data().
* \param cert Certificate containing the public key.
* In simple cases, this is one of the pointers passed to
* mbedtls_ssl_conf_own_cert() when configuring the SSL
* connection. However, if other callbacks are used, this
* property may not hold. For example, if an SNI callback
* is registered with mbedtls_ssl_conf_sni(), then
* this callback determines what certificate is used.
* \param md_alg Hash algorithm.
* \param hash Buffer containing the hash. This buffer is
* no longer valid when the function returns.
* \param hash_len Size of the \c hash buffer in bytes.
*
* \return 0 if the operation was started successfully and the SSL
* stack should call the resume callback immediately.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
* was started successfully and the SSL stack should return
* immediately without calling the resume callback yet.
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
* processor does not support this key. The SSL stack will
* use the private key object instead.
* \return Any other error indicates a fatal failure and is
* propagated up the call chain. The callback should
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
* directed in the documentation of this callback.
*/
typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl,
mbedtls_x509_crt *cert,
mbedtls_md_type_t md_alg,
const unsigned char *hash,
size_t hash_len );
/**
* \brief Callback type: start external decryption operation.
*
* This callback is called during an SSL handshake to start
* an RSA decryption operation using an
* external processor. The parameter \p cert contains
* the public key; it is up to the callback function to
* determine how to access the associated private key.
*
* This function typically sends or enqueues a request, and
* does not wait for the operation to complete. This allows
* the handshake step to be non-blocking.
*
* The parameters \p ssl and \p cert are guaranteed to remain
* valid throughout the handshake. On the other hand, this
* function must save the contents of \p input if the value
* is needed for later processing, because the \p input buffer
* is no longer valid after this function returns.
*
* This function may call mbedtls_ssl_set_async_operation_data()
* to store an operation context for later retrieval
* by the resume or cancel callback.
*
* \warning RSA decryption as used in TLS is subject to a potential
* timing side channel attack first discovered by Bleichenbacher
* in 1998. This attack can be remotely exploitable
* in practice. To avoid this attack, you must ensure that
* if the callback performs an RSA decryption, the time it
* takes to execute and return the result does not depend
* on whether the RSA decryption succeeded or reported
* invalid padding.
*
* \param ssl The SSL connection instance. It should not be
* modified other than via
* mbedtls_ssl_set_async_operation_data().
* \param cert Certificate containing the public key.
* In simple cases, this is one of the pointers passed to
* mbedtls_ssl_conf_own_cert() when configuring the SSL
* connection. However, if other callbacks are used, this
* property may not hold. For example, if an SNI callback
* is registered with mbedtls_ssl_conf_sni(), then
* this callback determines what certificate is used.
* \param input Buffer containing the input ciphertext. This buffer
* is no longer valid when the function returns.
* \param input_len Size of the \p input buffer in bytes.
*
* \return 0 if the operation was started successfully and the SSL
* stack should call the resume callback immediately.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
* was started successfully and the SSL stack should return
* immediately without calling the resume callback yet.
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
* processor does not support this key. The SSL stack will
* use the private key object instead.
* \return Any other error indicates a fatal failure and is
* propagated up the call chain. The callback should
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
* directed in the documentation of this callback.
*/
typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl,
mbedtls_x509_crt *cert,
const unsigned char *input,
size_t input_len );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
/**
* \brief Callback type: resume external operation.
*
* This callback is called during an SSL handshake to resume
* an external operation started by the
* ::mbedtls_ssl_async_sign_t or
* ::mbedtls_ssl_async_decrypt_t callback.
*
* This function typically checks the status of a pending
* request or causes the request queue to make progress, and
* does not wait for the operation to complete. This allows
* the handshake step to be non-blocking.
*
* This function may call mbedtls_ssl_get_async_operation_data()
* to retrieve an operation context set by the start callback.
* It may call mbedtls_ssl_set_async_operation_data() to modify
* this context.
*
* Note that when this function returns a status other than
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any
* resources associated with the operation.
*
* \param ssl The SSL connection instance. It should not be
* modified other than via
* mbedtls_ssl_set_async_operation_data().
* \param output Buffer containing the output (signature or decrypted
* data) on success.
* \param output_len On success, number of bytes written to \p output.
* \param output_size Size of the \p output buffer in bytes.
*
* \return 0 if output of the operation is available in the
* \p output buffer.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
* is still in progress. Subsequent requests for progress
* on the SSL connection will call the resume callback
* again.
* \return Any other error means that the operation is aborted.
* The SSL handshake is aborted. The callback should
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
* directed in the documentation of this callback.
*/
typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
unsigned char *output,
size_t *output_len,
size_t output_size );
/**
* \brief Callback type: cancel external operation.
*
* This callback is called if an SSL connection is closed
* while an asynchronous operation is in progress. Note that
* this callback is not called if the
* ::mbedtls_ssl_async_resume_t callback has run and has
* returned a value other than
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case
* the asynchronous operation has already completed.
*
* This function may call mbedtls_ssl_get_async_operation_data()
* to retrieve an operation context set by the start callback.
*
* \param ssl The SSL connection instance. It should not be
* modified.
*/
typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
/*
* This structure is used for storing current session data.
*/
@ -669,6 +899,16 @@ struct mbedtls_ssl_config
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */
mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */
mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */
void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
const int *sig_hashes; /*!< allowed signature hashes */
#endif
@ -792,14 +1032,14 @@ struct mbedtls_ssl_context
int renego_records_seen; /*!< Records since renego request, or with DTLS,
number of retransmissions of request if
renego_max_records is < 0 */
#endif
#endif /* MBEDTLS_SSL_RENEGOTIATION */
int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */
int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
unsigned badmac_seen; /*!< records with a bad MAC received */
#endif
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
@ -855,11 +1095,11 @@ struct mbedtls_ssl_context
uint16_t in_epoch; /*!< DTLS epoch for incoming records */
size_t next_record_offset; /*!< offset of the next record in datagram
(equal to in_left if none) */
#endif
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
uint64_t in_window_top; /*!< last validated record seq_num */
uint64_t in_window; /*!< bitmask for replay detection */
#endif
#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
size_t in_hslen; /*!< current handshake message length,
including the handshake header */
@ -868,6 +1108,11 @@ struct mbedtls_ssl_context
int keep_current_message; /*!< drop or reuse current message
on next call to record layer? */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint8_t disable_datagram_packing; /*!< Disable packing multiple records
* within a single datagram. */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/*
* Record layer (outgoing data)
*/
@ -882,12 +1127,18 @@ struct mbedtls_ssl_context
size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */
unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_ZLIB_SUPPORT)
unsigned char *compress_buf; /*!< zlib data buffer */
#endif
#endif /* MBEDTLS_ZLIB_SUPPORT */
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
signed char split_done; /*!< current record already splitted? */
#endif
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
/*
* PKI layer
@ -900,11 +1151,11 @@ struct mbedtls_ssl_context
#if defined(MBEDTLS_X509_CRT_PARSE_C)
char *hostname; /*!< expected peer CN for verification
(and SNI if available) */
#endif
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_ALPN)
const char *alpn_chosen; /*!< negotiated protocol */
#endif
#endif /* MBEDTLS_SSL_ALPN */
/*
* Information for DTLS hello verify
@ -912,7 +1163,7 @@ struct mbedtls_ssl_context
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
unsigned char *cli_id; /*!< transport-level ID of the client */
size_t cli_id_len; /*!< length of cli_id */
#endif
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
/*
* Secure renegotiation
@ -924,7 +1175,7 @@ struct mbedtls_ssl_context
size_t verify_data_len; /*!< length of verify data stored */
char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
#endif
#endif /* MBEDTLS_SSL_RENEGOTIATION */
};
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@ -946,14 +1197,6 @@ extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl);
extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl);
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
/**
* \brief Returns the list of ciphersuites supported by the SSL/TLS module.
*
* \return a statically allocated array of ciphersuites, the last
* entry is 0.
*/
const int *mbedtls_ssl_list_ciphersuites( void );
/**
* \brief Return the name of the ciphersuite associated with the
* given ID
@ -1152,6 +1395,52 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
mbedtls_ssl_recv_t *f_recv,
mbedtls_ssl_recv_timeout_t *f_recv_timeout );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
/**
* \brief Set the Maximum Tranport Unit (MTU).
* Special value: 0 means unset (no limit).
* This represents the maximum size of a datagram payload
* handled by the transport layer (usually UDP) as determined
* by the network link and stack. In practice, this controls
* the maximum size datagram the DTLS layer will pass to the
* \c f_send() callback set using \c mbedtls_ssl_set_bio().
*
* \note The limit on datagram size is converted to a limit on
* record payload by subtracting the current overhead of
* encapsulation and encryption/authentication if any.
*
* \note This can be called at any point during the connection, for
* example when a Path Maximum Transfer Unit (PMTU)
* estimate becomes available from other sources,
* such as lower (or higher) protocol layers.
*
* \note This setting only controls the size of the packets we send,
* and does not restrict the size of the datagrams we're
* willing to receive. Client-side, you can request the
* server to use smaller records with \c
* mbedtls_ssl_conf_max_frag_len().
*
* \note If both a MTU and a maximum fragment length have been
* configured (or negotiated with the peer), the resulting
* lower limit on record payload (see first note) is used.
*
* \note This can only be used to decrease the maximum size
* of datagrams (hence records, see first note) sent. It
* cannot be used to increase the maximum size of records over
* the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN.
*
* \note Values lower than the current record layer expansion will
* result in an error when trying to send data.
*
* \note Using record compression together with a non-zero MTU value
* will result in an error when trying to send data.
*
* \param ssl SSL context
* \param mtu Value of the path MTU in bytes
*/
void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/**
* \brief Set the timeout period for mbedtls_ssl_read()
* (Default: no timeout.)
@ -1315,6 +1604,85 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/**
* \brief Configure asynchronous private key operation callbacks.
*
* \param conf SSL configuration context
* \param f_async_sign Callback to start a signature operation. See
* the description of ::mbedtls_ssl_async_sign_t
* for more information. This may be \c NULL if the
* external processor does not support any signature
* operation; in this case the private key object
* associated with the certificate will be used.
* \param f_async_decrypt Callback to start a decryption operation. See
* the description of ::mbedtls_ssl_async_decrypt_t
* for more information. This may be \c NULL if the
* external processor does not support any decryption
* operation; in this case the private key object
* associated with the certificate will be used.
* \param f_async_resume Callback to resume an asynchronous operation. See
* the description of ::mbedtls_ssl_async_resume_t
* for more information. This may not be \c NULL unless
* \p f_async_sign and \p f_async_decrypt are both
* \c NULL.
* \param f_async_cancel Callback to cancel an asynchronous operation. See
* the description of ::mbedtls_ssl_async_cancel_t
* for more information. This may be \c NULL if
* no cleanup is needed.
* \param config_data A pointer to configuration data which can be
* retrieved with
* mbedtls_ssl_conf_get_async_config_data(). The
* library stores this value without dereferencing it.
*/
void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_async_sign_t *f_async_sign,
mbedtls_ssl_async_decrypt_t *f_async_decrypt,
mbedtls_ssl_async_resume_t *f_async_resume,
mbedtls_ssl_async_cancel_t *f_async_cancel,
void *config_data );
/**
* \brief Retrieve the configuration data set by
* mbedtls_ssl_conf_async_private_cb().
*
* \param conf SSL configuration context
* \return The configuration data set by
* mbedtls_ssl_conf_async_private_cb().
*/
void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf );
/**
* \brief Retrieve the asynchronous operation user context.
*
* \note This function may only be called while a handshake
* is in progress.
*
* \param ssl The SSL context to access.
*
* \return The asynchronous operation user context that was last
* set during the current handshake. If
* mbedtls_ssl_set_async_operation_data() has not yet been
* called during the current handshake, this function returns
* \c NULL.
*/
void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl );
/**
* \brief Retrieve the asynchronous operation user context.
*
* \note This function may only be called while a handshake
* is in progress.
*
* \param ssl The SSL context to access.
* \param ctx The new value of the asynchronous operation user context.
* Call mbedtls_ssl_get_async_operation_data() later during the
* same handshake to retrieve this value.
*/
void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
void *ctx );
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
/**
* \brief Callback type: generate a cookie
*
@ -1456,6 +1824,38 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
/**
* \brief Allow or disallow packing of multiple handshake records
* within a single datagram.
*
* \param ssl The SSL context to configure.
* \param allow_packing This determines whether datagram packing may
* be used or not. A value of \c 0 means that every
* record will be sent in a separate datagram; a
* value of \c 1 means that, if space permits,
* multiple handshake messages (including CCS) belonging to
* a single flight may be packed within a single datagram.
*
* \note This is enabled by default and should only be disabled
* for test purposes, or if datagram packing causes
* interoperability issues with peers that don't support it.
*
* \note Allowing datagram packing reduces the network load since
* there's less overhead if multiple messages share the same
* datagram. Also, it increases the handshake efficiency
* since messages belonging to a single datagram will not
* be reordered in transit, and so future message buffering
* or flight retransmission (if no buffering is used) as
* means to deal with reordering are needed less frequently.
*
* \note Application records are not affected by this option and
* are currently always sent in separate datagrams.
*
*/
void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
unsigned allow_packing );
/**
* \brief Set retransmit timeout values for the DTLS handshake.
* (DTLS only, no effect on TLS.)
@ -2125,12 +2525,25 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
* \brief Set the maximum fragment length to emit and/or negotiate
* (Default: MBEDTLS_SSL_MAX_CONTENT_LEN, usually 2^14 bytes)
* (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and
* MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes)
* (Server: set maximum fragment length to emit,
* usually negotiated by the client during handshake
* (Client: set maximum fragment length to emit *and*
* negotiate with the server during handshake)
*
* \note With TLS, this currently only affects ApplicationData (sent
* with \c mbedtls_ssl_read()), not handshake messages.
* With DTLS, this affects both ApplicationData and handshake.
*
* \note This sets the maximum length for a record's payload,
* excluding record overhead that will be added to it, see
* \c mbedtls_ssl_get_record_expansion().
*
* \note For DTLS, it is also possible to set a limit for the total
* size of daragrams passed to the transport layer, including
* record overhead, see \c mbedtls_ssl_set_mtu().
*
* \param conf SSL configuration
* \param mfl_code Code for maximum fragment length (allowed values:
* MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024,
@ -2393,6 +2806,9 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl );
* \brief Return the (maximum) number of bytes added by the record
* layer: header + encryption/MAC overhead (inc. padding)
*
* \note This function is not available (always returns an error)
* when record compression is enabled.
*
* \param ssl SSL context
*
* \return Current maximum record expansion in bytes, or
@ -2407,12 +2823,8 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
* This is the value negotiated with peer if any,
* or the locally configured value.
*
* \note With DTLS, \c mbedtls_ssl_write() will return an error if
* called with a larger length value.
* With TLS, \c mbedtls_ssl_write() will fragment the input if
* necessary and return the number of bytes written; it is up
* to the caller to call \c mbedtls_ssl_write() again in
* order to send the remaining bytes if any.
* \sa mbedtls_ssl_conf_max_frag_len()
* \sa mbedtls_ssl_get_max_record_payload()
*
* \param ssl SSL context
*
@ -2421,6 +2833,34 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
/**
* \brief Return the current maximum outgoing record payload in bytes.
* This takes into account the config.h setting \c
* MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated
* max fragment length extension if used, and for DTLS the
* path MTU as configured and current record expansion.
*
* \note With DTLS, \c mbedtls_ssl_write() will return an error if
* called with a larger length value.
* With TLS, \c mbedtls_ssl_write() will fragment the input if
* necessary and return the number of bytes written; it is up
* to the caller to call \c mbedtls_ssl_write() again in
* order to send the remaining bytes if any.
*
* \note This function is not available (always returns an error)
* when record compression is enabled.
*
* \sa mbedtls_ssl_set_mtu()
* \sa mbedtls_ssl_get_max_frag_len()
* \sa mbedtls_ssl_get_record_expansion()
*
* \param ssl SSL context
*
* \return Current maximum payload for an outgoing record,
* or a negative error code.
*/
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Return the peer certificate from the current connection
@ -2444,7 +2884,6 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss
* \brief Save session in order to resume it later (client-side only)
* Session data is copied to presented session structure.
*
* \warning Currently, peer certificate is lost in the operation.
*
* \param ssl SSL context
* \param session session context
@ -2452,7 +2891,18 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss
* \return 0 if successful,
* MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
* arguments are otherwise invalid
* arguments are otherwise invalid.
*
* \note Only the server certificate is copied, and not the full chain,
* so you should not attempt to validate the certificate again
* by calling \c mbedtls_x509_crt_verify() on it.
* Instead, you should use the results from the verification
* in the original handshake by calling \c mbedtls_ssl_get_verify_result()
* after loading the session again into a new SSL context
* using \c mbedtls_ssl_set_session().
*
* \note Once the session object is not needed anymore, you should
* free it by calling \c mbedtls_ssl_session_free().
*
* \sa mbedtls_ssl_set_session()
*/
@ -2464,35 +2914,50 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session
*
* \param ssl SSL context
*
* \return 0 if successful, or
* MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or
* MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED (see below), or
* a specific SSL error code.
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
* if the handshake is incomplete and waiting for data to
* be available for reading from or writing to the underlying
* transport - in this case you must call this function again
* when the underlying transport is ready for the operation.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
* operation is in progress (see
* mbedtls_ssl_conf_async_private_cb()) - in this case you
* must call this function again when the operation is ready.
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
* and the client did not demonstrate reachability yet - in
* this case you must stop using the context (see below).
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
* If this function returns MBEDTLS_ERR_SSL_WANT_READ, the
* handshake is unfinished and no further data is available
* from the underlying transport. In this case, you must call
* the function again at some later stage.
* \warning If this function returns something other than
* \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
* connection must be closed.
*
* \note If DTLS is in use, then you may choose to handle
* #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
* purposes, as it is an expected return value rather than an
* actual error, but you still need to reset/free the context.
*
* \note Remarks regarding event-driven DTLS:
* If the function returns MBEDTLS_ERR_SSL_WANT_READ, no datagram
* If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
* from the underlying transport layer is currently being processed,
* and it is safe to idle until the timer or the underlying transport
* signal a new event. This is not true for a successful handshake,
* in which case the datagram of the underlying transport that is
* currently being processed might or might not contain further
* DTLS records.
*
* \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
* the SSL context for reading or writing, and either free it or
* call \c mbedtls_ssl_session_reset() on it before re-using it
* for a new connection; the current connection must be closed.
*
* \note If DTLS is in use, then you may choose to handle
* MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
* purposes, as it is an expected return value rather than an
* actual error, but you still need to reset/free the context.
*/
int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
@ -2500,20 +2965,21 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
* \brief Perform a single step of the SSL handshake
*
* \note The state of the context (ssl->state) will be at
* the next state after execution of this function. Do not
* the next state after this function returns \c 0. Do not
* call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
*
* \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
* the SSL context for reading or writing, and either free it or
* call \c mbedtls_ssl_session_reset() on it before re-using it
* for a new connection; the current connection must be closed.
*
* \param ssl SSL context
*
* \return 0 if successful, or
* MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, or
* a specific SSL error code.
* \return See mbedtls_ssl_handshake().
*
* \warning If this function returns something other than \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
* the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before
* re-using it for a new connection; the current connection
* must be closed.
*/
int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
@ -2528,13 +2994,18 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
* \param ssl SSL context
*
* \return 0 if successful, or any mbedtls_ssl_handshake() return
* value.
* value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't
* happen during a renegotiation.
*
* \warning If this function returns something other than \c 0,
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
* the SSL context for reading or writing, and either free it
* or call \c mbedtls_ssl_session_reset() on it before
* re-using it for a new connection; the current connection
* must be closed.
*
* \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
* the SSL context for reading or writing, and either free it or
* call \c mbedtls_ssl_session_reset() on it before re-using it
* for a new connection; the current connection must be closed.
*/
int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_RENEGOTIATION */
@ -2546,42 +3017,56 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
* \param buf buffer that will hold the data
* \param len maximum number of bytes to read
*
* \return One of the following:
* - 0 if the read end of the underlying transport was closed,
* - the (positive) number of bytes read, or
* - a negative error code on failure.
* \return The (positive) number of bytes read if successful.
* \return \c 0 if the read end of the underlying transport was closed
* - in this case you must stop using the context (see below).
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
* if the handshake is incomplete and waiting for data to
* be available for reading from or writing to the underlying
* transport - in this case you must call this function again
* when the underlying transport is ready for the operation.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
* operation is in progress (see
* mbedtls_ssl_conf_async_private_cb()) - in this case you
* must call this function again when the operation is ready.
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
* side of a DTLS connection and the client is initiating a
* new connection using the same source port. See below.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
* If MBEDTLS_ERR_SSL_WANT_READ is returned, no application data
* is available from the underlying transport. In this case,
* the function needs to be called again at some later stage.
* \warning If this function returns something other than
* a positive value,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
* connection must be closed.
*
* If MBEDTLS_ERR_SSL_WANT_WRITE is returned, a write is pending
* but the underlying transport isn't available for writing. In this
* case, the function needs to be called again at some later stage.
*
* When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
* \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT
* (which can only happen server-side), it means that a client
* is initiating a new connection using the same source port.
* You can either treat that as a connection close and wait
* for the client to resend a ClientHello, or directly
* continue with \c mbedtls_ssl_handshake() with the same
* context (as it has beeen reset internally). Either way, you
* should make sure this is seen by the application as a new
* context (as it has been reset internally). Either way, you
* must make sure this is seen by the application as a new
* connection: application state, if any, should be reset, and
* most importantly the identity of the client must be checked
* again. WARNING: not validating the identity of the client
* again, or not transmitting the new identity to the
* application layer, would allow authentication bypass!
*
* \note If this function returns something other than a positive value
* or MBEDTLS_ERR_SSL_WANT_READ/WRITE or MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset() on it
* before re-using it for a new connection; the current connection
* must be closed.
*
* \note Remarks regarding event-driven DTLS:
* - If the function returns MBEDTLS_ERR_SSL_WANT_READ, no datagram
* - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
* from the underlying transport layer is currently being processed,
* and it is safe to idle until the timer or the underlying transport
* signal a new event.
@ -2610,21 +3095,41 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* \param buf buffer holding the data
* \param len how many bytes must be written
*
* \return the number of bytes actually written (may be less than len),
* or MBEDTLS_ERR_SSL_WANT_WRITE or MBEDTLS_ERR_SSL_WANT_READ,
* or another negative error code.
* \return The (non-negative) number of bytes actually written if
* successful (may be less than \p len).
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
* if the handshake is incomplete and waiting for data to
* be available for reading from or writing to the underlying
* transport - in this case you must call this function again
* when the underlying transport is ready for the operation.
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
* operation is in progress (see
* mbedtls_ssl_conf_async_private_cb()) - in this case you
* must call this function again when the operation is ready.
* \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
* in this case you must call this function again to complete
* the handshake when you're done attending other tasks.
* \return Another SSL error code - in this case you must stop using
* the context (see below).
*
* \note If this function returns something other than a positive value
* or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
* the SSL context for reading or writing, and either free it or
* call \c mbedtls_ssl_session_reset() on it before re-using it
* for a new connection; the current connection must be closed.
* \warning If this function returns something other than
* a non-negative value,
* #MBEDTLS_ERR_SSL_WANT_READ,
* #MBEDTLS_ERR_SSL_WANT_WRITE,
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
* you must stop using the SSL context for reading or writing,
* and either free it or call \c mbedtls_ssl_session_reset()
* on it before re-using it for a new connection; the current
* connection must be closed.
*
* \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ,
* \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ,
* it must be called later with the *same* arguments,
* until it returns a positive value. When the function returns
* MBEDTLS_ERR_SSL_WANT_WRITE there may be some partial
* data in the output buffer, however this is not yet sent.
* until it returns a value greater that or equal to 0. When
* the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be
* some partial data in the output buffer, however this is not
* yet sent.
*
* \note If the requested length is greater than the maximum
* fragment length (either the built-in limit or the one set
@ -2633,6 +3138,9 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
* \c mbedtls_ssl_get_max_frag_len() may be used to query the
* active maximum fragment length.
*
* \note Attempting to write 0 bytes will result in an empty TLS
* application record being sent.
*/
int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len );
@ -2725,6 +3233,9 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session );
* \brief Free referenced items in an SSL session including the
* peer certificate and clear memory
*
* \note A session object can be freed even if the SSL context
* that was used to retrieve the session is still in use.
*
* \param session SSL session
*/
void mbedtls_ssl_session_free( mbedtls_ssl_session *session );

View file

@ -169,6 +169,45 @@ extern "C" {
#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */
#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */
#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */
#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */
#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */
#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */
#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */
#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */
@ -232,6 +271,15 @@ extern "C" {
#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */
/* RFC 7905 */
#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */
#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */
#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */
#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */
/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange.
* Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below
*/

View file

@ -50,7 +50,7 @@ extern "C" {
/**
* \brief Context for the default cookie functions.
*/
typedef struct
typedef struct mbedtls_ssl_cookie_ctx
{
mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */
#if !defined(MBEDTLS_HAVE_TIME)

View file

@ -93,6 +93,14 @@
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
/* Shorthand for restartable ECC */
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#define MBEDTLS_SSL__ECP_RESTARTABLE
#endif
#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0
#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */
#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */
@ -143,32 +151,76 @@
#define MBEDTLS_SSL_PADDING_ADD 0
#endif
#define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \
+ MBEDTLS_SSL_COMPRESSION_ADD \
+ MBEDTLS_MAX_IV_LENGTH \
+ MBEDTLS_SSL_MAC_ADD \
+ MBEDTLS_SSL_PADDING_ADD \
)
#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \
MBEDTLS_MAX_IV_LENGTH + \
MBEDTLS_SSL_MAC_ADD + \
MBEDTLS_SSL_PADDING_ADD \
)
#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
( MBEDTLS_SSL_IN_CONTENT_LEN ) )
#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
( MBEDTLS_SSL_OUT_CONTENT_LEN ) )
/* The maximum number of buffered handshake messages. */
#define MBEDTLS_SSL_MAX_BUFFERED_HS 4
/* Maximum length we can advertise as our max content length for
RFC 6066 max_fragment_length extension negotiation purposes
(the lesser of both sizes, if they are unequal.)
*/
#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \
(MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \
? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \
: ( MBEDTLS_SSL_IN_CONTENT_LEN ) \
)
/*
* Check that we obey the standard's message size bounds
*/
#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384
#error Bad configuration - record content too large.
#error "Bad configuration - record content too large."
#endif
#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048
#error Bad configuration - protected record payload too large.
#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
#endif
#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
#endif
#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
#error "Bad configuration - incoming protected record payload too large."
#endif
#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
#error "Bad configuration - outgoing protected record payload too large."
#endif
/* Calculate buffer sizes */
/* Note: Even though the TLS record header is only 5 bytes
long, we're internally using 8 bytes to store the
implicit sequence number. */
#define MBEDTLS_SSL_HEADER_LEN 13
#define MBEDTLS_SSL_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) )
#define MBEDTLS_SSL_IN_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) )
#define MBEDTLS_SSL_OUT_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) )
#ifdef MBEDTLS_ZLIB_SUPPORT
/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */
#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \
( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \
? MBEDTLS_SSL_IN_BUFFER_LEN \
: MBEDTLS_SSL_OUT_BUFFER_LEN \
)
#endif
/*
* TLS extension flags (for extensions with outgoing ServerHello content
@ -243,6 +295,18 @@ struct mbedtls_ssl_handshake_params
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
int ecrs_enabled; /*!< Handshake supports EC restart? */
mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */
enum { /* this complements ssl->state with info on intra-state operations */
ssl_ecrs_none = 0, /*!< nothing going on (yet) */
ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */
ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */
ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */
ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */
} ecrs_state; /*!< current (or last) operation */
size_t ecrs_n; /*!< place for saving a length */
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
@ -252,18 +316,45 @@ struct mbedtls_ssl_handshake_params
unsigned char verify_cookie_len; /*!< Cli: cookie length
Srv: flag for sending a cookie */
unsigned char *hs_msg; /*!< Reassembled handshake message */
uint32_t retransmit_timeout; /*!< Current value of timeout */
unsigned char retransmit_state; /*!< Retransmission state */
mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */
mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */
mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */
mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */
unsigned char *cur_msg_p; /*!< Position in current message */
unsigned int in_flight_start_seq; /*!< Minimum message sequence in the
flight being received */
mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for
resending messages */
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
for resending messages */
struct
{
size_t total_bytes_buffered; /*!< Cumulative size of heap allocated
* buffers used for message buffering. */
uint8_t seen_ccs; /*!< Indicates if a CCS message has
* been seen in the current flight. */
struct mbedtls_ssl_hs_buffer
{
unsigned is_valid : 1;
unsigned is_fragmented : 1;
unsigned is_complete : 1;
unsigned char *data;
size_t data_len;
} hs[MBEDTLS_SSL_MAX_BUFFERED_HS];
struct
{
unsigned char *data;
size_t len;
unsigned epoch;
} future_record;
} buffering;
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/*
@ -307,8 +398,23 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
int extended_ms; /*!< use Extended Master Secret? */
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/** Asynchronous operation context. This field is meant for use by the
* asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
* mbedtls_ssl_config::f_async_decrypt_start,
* mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel).
* The library does not use it internally. */
void *user_async_ctx;
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
};
typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer;
/*
* This structure contains a full set of runtime transform parameters
* either in negotiation or active.
@ -410,9 +516,9 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
* \brief Free referenced items in an SSL handshake context and clear
* memory
*
* \param handshake SSL handshake context
* \param ssl SSL context
*/
void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake );
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
@ -423,7 +529,6 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl );
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl );
int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl );
int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl );
int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl );
void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
@ -435,7 +540,10 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
* of the logic of (D)TLS from the implementation
* of the secure transport.
*
* \param ssl SSL context to use
* \param ssl The SSL context to use.
* \param update_hs_digest This indicates if the handshake digest
* should be automatically updated in case
* a handshake message is found.
*
* \return 0 or non-zero error code.
*
@ -501,10 +609,12 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
* following the above definition.
*
*/
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl );
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
unsigned update_hs_digest );
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl );
int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );
@ -613,6 +723,7 @@ static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl );
void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl );
int mbedtls_ssl_resend( mbedtls_ssl_context *ssl );
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
#endif
/* Visible for testing purposes only */
@ -630,7 +741,13 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t
volatile unsigned char diff = 0;
for( i = 0; i < n; i++ )
diff |= A[i] ^ B[i];
{
/* Read volatile data in order before computing diff.
* This avoids IAR compiler warning:
* 'the order of volatile accesses is undefined ..' */
unsigned char x = A[i], y = B[i];
diff |= x ^ y;
}
return( diff );
}
@ -646,9 +763,9 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *output,
unsigned char *data, size_t data_len,
mbedtls_md_type_t md_alg );
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */

View file

@ -44,7 +44,7 @@ extern "C" {
/**
* \brief Information for session ticket protection
*/
typedef struct
typedef struct mbedtls_ssl_ticket_key
{
unsigned char name[4]; /*!< random key identifier */
uint32_t generation_time; /*!< key generation timestamp (seconds) */
@ -55,7 +55,7 @@ mbedtls_ssl_ticket_key;
/**
* \brief Context for session ticket handling functions
*/
typedef struct
typedef struct mbedtls_ssl_ticket_context
{
mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */
unsigned char active; /*!< index of the currently active key */

View file

@ -42,7 +42,7 @@ extern "C" {
#if defined(MBEDTLS_THREADING_PTHREAD)
#include <pthread.h>
typedef struct
typedef struct mbedtls_threading_mutex_t
{
pthread_mutex_t mutex;
char is_valid;
@ -99,9 +99,17 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
#if defined(MBEDTLS_FS_IO)
extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
/* This mutex may or may not be used in the default definition of
* mbedtls_platform_gmtime_r(), but in order to determine that,
* we need to check POSIX features, hence modify _POSIX_C_SOURCE.
* With the current approach, this declaration is orphaned, lacking
* an accompanying definition, in case mbedtls_platform_gmtime_r()
* doesn't need it, but that's not a problem. */
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
#endif
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
#endif /* MBEDTLS_THREADING_C */
#ifdef __cplusplus

View file

@ -51,7 +51,7 @@ struct mbedtls_timing_hr_time
/**
* \brief Context for mbedtls_timing_set/get_delay()
*/
typedef struct
typedef struct mbedtls_timing_delay_context
{
struct mbedtls_timing_hr_time timer;
uint32_t int_ms;

View file

@ -39,17 +39,17 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 9
#define MBEDTLS_VERSION_PATCH 0
#define MBEDTLS_VERSION_MINOR 13
#define MBEDTLS_VERSION_PATCH 1
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x02090000
#define MBEDTLS_VERSION_STRING "2.9.0"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.9.0"
#define MBEDTLS_VERSION_NUMBER 0x020D0100
#define MBEDTLS_VERSION_STRING "2.13.1"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.13.1"
#if defined(MBEDTLS_VERSION_C)

View file

@ -105,7 +105,7 @@ mbedtls_x509_crt;
*
* All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG().
*/
typedef struct
typedef struct mbedtls_x509_crt_profile
{
uint32_t allowed_mds; /**< MDs for signatures */
uint32_t allowed_pks; /**< PK algs for signatures */
@ -143,6 +143,63 @@ typedef struct mbedtls_x509write_cert
}
mbedtls_x509write_cert;
/**
* Item in a verification chain: cert and flags for it
*/
typedef struct {
mbedtls_x509_crt *crt;
uint32_t flags;
} mbedtls_x509_crt_verify_chain_item;
/**
* Max size of verification chain: end-entity + intermediates + trusted root
*/
#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
/**
* Verification chain as built by \c mbedtls_crt_verify_chain()
*/
typedef struct
{
mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE];
unsigned len;
} mbedtls_x509_crt_verify_chain;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Context for resuming X.509 verify operations
*/
typedef struct
{
/* for check_signature() */
mbedtls_pk_restart_ctx pk;
/* for find_parent_in() */
mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */
mbedtls_x509_crt *fallback_parent;
int fallback_signature_is_good;
/* for find_parent() */
int parent_is_trusted; /* -1 if find_parent is not in progress */
/* for verify_chain() */
enum {
x509_crt_rs_none,
x509_crt_rs_find_parent,
} in_progress; /* none if no operation is in progress */
int self_cnt;
mbedtls_x509_crt_verify_chain ver_chain;
} mbedtls_x509_crt_restart_ctx;
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/* Now we can declare functions that take a pointer to that */
typedef void mbedtls_x509_crt_restart_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* Default security profile. Should provide a good balance between security
@ -353,6 +410,37 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy );
/**
* \brief Restartable version of \c mbedtls_crt_verify_with_profile()
*
* \note Performs the same job as \c mbedtls_crt_verify_with_profile()
* but can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \param crt a certificate (chain) to be verified
* \param trust_ca the list of trusted CAs
* \param ca_crl the list of CRLs for trusted CAs
* \param profile security profile for verification
* \param cn expected Common Name (can be set to
* NULL if the CN must not be verified)
* \param flags result of the verification
* \param f_vrfy verification function
* \param p_vrfy verification parameter
* \param rs_ctx restart context (NULL to disable restart)
*
* \return See \c mbedtls_crt_verify_with_profile(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx );
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
/**
* \brief Check usage of certificate against keyUsage extension.
@ -424,6 +512,18 @@ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
* \param crt Certificate chain to free
*/
void mbedtls_x509_crt_free( mbedtls_x509_crt *crt );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*/
void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*/
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
/* \} name */

View file

@ -50,7 +50,7 @@ extern "C" {
/**
* \brief XTEA context structure
*/
typedef struct
typedef struct mbedtls_xtea_context
{
uint32_t k[4]; /*!< key */
}

View file

@ -6,6 +6,7 @@ set(src_crypto
aes.c
aesni.c
arc4.c
aria.c
asn1parse.c
asn1write.c
base64.c
@ -13,6 +14,8 @@ set(src_crypto
blowfish.c
camellia.c
ccm.c
chacha20.c
chachapoly.c
cipher.c
cipher_wrap.c
cmac.c
@ -29,6 +32,7 @@ set(src_crypto
error.c
gcm.c
havege.c
hkdf.c
hmac_drbg.c
md.c
md2.c
@ -36,6 +40,7 @@ set(src_crypto
md5.c
md_wrap.c
memory_buffer_alloc.c
nist_kw.c
oid.c
padlock.c
pem.c
@ -47,6 +52,7 @@ set(src_crypto
pkwrite.c
platform.c
platform_util.c
poly1305.c
ripemd160.c
rsa.c
rsa_internal.c
@ -96,6 +102,17 @@ if(WIN32)
set(libs ${libs} ws2_32)
endif(WIN32)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
endif()
if(HAIKU)
set(libs ${libs} network)
endif(HAIKU)
if(USE_PKCS11_HELPER_LIBRARY)
set(libs ${libs} pkcs11-helper)
endif(USE_PKCS11_HELPER_LIBRARY)
@ -142,15 +159,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto})
set_target_properties(mbedcrypto PROPERTIES VERSION 2.9.0 SOVERSION 2)
set_target_properties(mbedcrypto PROPERTIES VERSION 2.13.1 SOVERSION 3)
target_link_libraries(mbedcrypto ${libs})
add_library(mbedx509 SHARED ${src_x509})
set_target_properties(mbedx509 PROPERTIES VERSION 2.9.0 SOVERSION 0)
set_target_properties(mbedx509 PROPERTIES VERSION 2.13.1 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls})
set_target_properties(mbedtls PROPERTIES VERSION 2.9.0 SOVERSION 10)
set_target_properties(mbedtls PROPERTIES VERSION 2.13.1 SOVERSION 12)
target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto

View file

@ -21,6 +21,10 @@ endif
# if were running on Windows build for Windows
ifdef WINDOWS
WINDOWS_BUILD=1
else ifeq ($(shell uname -s),Darwin)
ifeq ($(AR),ar)
APPLE_BUILD ?= 1
endif
endif
# To compile as a shared library:
@ -31,42 +35,56 @@ LOCAL_CFLAGS += -fPIC -fpic
endif
endif
SOEXT_TLS=so.10
SOEXT_TLS=so.12
SOEXT_X509=so.0
SOEXT_CRYPTO=so.2
# Set DLEXT=dylib to compile as a shared library for Mac OS X
DLEXT ?= so
SOEXT_CRYPTO=so.3
# Set AR_DASH= (empty string) to use an ar implentation that does not accept
# the - prefix for command line options (e.g. llvm-ar)
AR_DASH ?= -
# Windows shared library extension:
ARFLAGS = $(AR_DASH)src
ifdef APPLE_BUILD
ifneq ($(APPLE_BUILD),0)
ARFLAGS = $(AR_DASH)Src
RLFLAGS = -no_warning_for_no_symbols -c
RL ?= ranlib
endif
endif
DLEXT ?= so
ifdef WINDOWS_BUILD
DLEXT=dll
# Windows shared library extension:
DLEXT = dll
else ifdef APPLE_BUILD
ifneq ($(APPLE_BUILD),0)
# Mac OS X shared library extension:
DLEXT = dylib
endif
endif
OBJS_CRYPTO= aes.o aesni.o arc4.o \
asn1parse.o asn1write.o base64.o \
bignum.o blowfish.o camellia.o \
ccm.o cipher.o cipher_wrap.o \
aria.o asn1parse.o asn1write.o \
base64.o bignum.o blowfish.o \
camellia.o ccm.o chacha20.o \
chachapoly.o cipher.o cipher_wrap.o \
cmac.o ctr_drbg.o des.o \
dhm.o ecdh.o ecdsa.o \
ecjpake.o ecp.o \
ecp_curves.o entropy.o entropy_poll.o \
error.o gcm.o havege.o \
hkdf.o \
hmac_drbg.o md.o md2.o \
md4.o md5.o md_wrap.o \
memory_buffer_alloc.o oid.o \
padlock.o pem.o pk.o \
pk_wrap.o pkcs12.o pkcs5.o \
pkparse.o pkwrite.o platform.o \
platform_util.o ripemd160.o rsa_internal.o \
rsa.o sha1.o sha256.o \
sha512.o threading.o timing.o \
version.o version_features.o \
xtea.o
memory_buffer_alloc.o nist_kw.o \
oid.o padlock.o pem.o \
pk.o pk_wrap.o pkcs12.o \
pkcs5.o pkparse.o pkwrite.o \
platform.o platform_util.o poly1305.o \
ripemd160.o rsa_internal.o rsa.o \
sha1.o sha256.o sha512.o \
threading.o timing.o version.o \
version_features.o xtea.o
OBJS_X509= certs.o pkcs11.o x509.o \
x509_create.o x509_crl.o x509_crt.o \
@ -95,9 +113,13 @@ shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
# tls
libmbedtls.a: $(OBJS_TLS)
echo " AR $@"
$(AR) $(AR_DASH)rc $@ $(OBJS_TLS)
$(AR) $(ARFLAGS) $@ $(OBJS_TLS)
ifdef APPLE_BUILD
ifneq ($(APPLE_BUILD),0)
echo " RL $@"
$(AR) $(AR_DASH)s $@
$(RL) $(RLFLAGS) $@
endif
endif
libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so
echo " LD $@"
@ -118,9 +140,13 @@ libmbedtls.dll: $(OBJS_TLS) libmbedx509.dll
# x509
libmbedx509.a: $(OBJS_X509)
echo " AR $@"
$(AR) $(AR_DASH)rc $@ $(OBJS_X509)
$(AR) $(ARFLAGS) $@ $(OBJS_X509)
ifdef APPLE_BUILD
ifneq ($(APPLE_BUILD),0)
echo " RL $@"
$(AR) $(AR_DASH)s $@
$(RL) $(RLFLAGS) $@
endif
endif
libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
echo " LD $@"
@ -141,9 +167,13 @@ libmbedx509.dll: $(OBJS_X509) libmbedcrypto.dll
# crypto
libmbedcrypto.a: $(OBJS_CRYPTO)
echo " AR $@"
$(AR) $(AR_DASH)rc $@ $(OBJS_CRYPTO)
$(AR) $(ARFLAGS) $@ $(OBJS_CRYPTO)
ifdef APPLE_BUILD
ifneq ($(APPLE_BUILD),0)
echo " RL $@"
$(AR) $(AR_DASH)s $@
$(RL) $(RLFLAGS) $@
endif
endif
libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO)
echo " LD $@"

View file

@ -521,6 +521,20 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
}
#if defined(MBEDTLS_CIPHER_MODE_XTS)
void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
{
mbedtls_aes_init( &ctx->crypt );
mbedtls_aes_init( &ctx->tweak );
}
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
{
mbedtls_aes_free( &ctx->crypt );
mbedtls_aes_free( &ctx->tweak );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/*
* AES key schedule (encryption)
*/
@ -702,6 +716,78 @@ exit:
return( ret );
}
#if defined(MBEDTLS_CIPHER_MODE_XTS)
static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
unsigned int keybits,
const unsigned char **key1,
unsigned int *key1bits,
const unsigned char **key2,
unsigned int *key2bits )
{
const unsigned int half_keybits = keybits / 2;
const unsigned int half_keybytes = half_keybits / 8;
switch( keybits )
{
case 256: break;
case 512: break;
default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
}
*key1bits = half_keybits;
*key2bits = half_keybits;
*key1 = &key[0];
*key2 = &key[half_keybytes];
return 0;
}
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
int ret;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
&key2, &key2bits );
if( ret != 0 )
return( ret );
/* Set the tweak key. Always set tweak key for the encryption mode. */
ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
if( ret != 0 )
return( ret );
/* Set crypt key for encryption. */
return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
}
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
int ret;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
&key2, &key2bits );
if( ret != 0 )
return( ret );
/* Set the tweak key. Always set tweak key for encryption. */
ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
if( ret != 0 )
return( ret );
/* Set crypt key for decryption. */
return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
@ -983,6 +1069,165 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/* Endianess with 64 bits values */
#ifndef GET_UINT64_LE
#define GET_UINT64_LE(n,b,i) \
{ \
(n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
| ( (uint64_t) (b)[(i) + 6] << 48 ) \
| ( (uint64_t) (b)[(i) + 5] << 40 ) \
| ( (uint64_t) (b)[(i) + 4] << 32 ) \
| ( (uint64_t) (b)[(i) + 3] << 24 ) \
| ( (uint64_t) (b)[(i) + 2] << 16 ) \
| ( (uint64_t) (b)[(i) + 1] << 8 ) \
| ( (uint64_t) (b)[(i) ] ); \
}
#endif
#ifndef PUT_UINT64_LE
#define PUT_UINT64_LE(n,b,i) \
{ \
(b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) ] = (unsigned char) ( (n) ); \
}
#endif
typedef unsigned char mbedtls_be128[16];
/*
* GF(2^128) multiplication function
*
* This function multiplies a field element by x in the polynomial field
* representation. It uses 64-bit word operations to gain speed but compensates
* for machine endianess and hence works correctly on both big and little
* endian machines.
*/
static void mbedtls_gf128mul_x_ble( unsigned char r[16],
const unsigned char x[16] )
{
uint64_t a, b, ra, rb;
GET_UINT64_LE( a, x, 0 );
GET_UINT64_LE( b, x, 8 );
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
rb = ( a >> 63 ) | ( b << 1 );
PUT_UINT64_LE( ra, r, 0 );
PUT_UINT64_LE( rb, r, 8 );
}
/*
* AES-XTS buffer encryption/decryption
*/
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
const unsigned char data_unit[16],
const unsigned char *input,
unsigned char *output )
{
int ret;
size_t blocks = length / 16;
size_t leftover = length % 16;
unsigned char tweak[16];
unsigned char prev_tweak[16];
unsigned char tmp[16];
/* Sectors must be at least 16 bytes. */
if( length < 16 )
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
/* NIST SP 80-38E disallows data units larger than 2**20 blocks. */
if( length > ( 1 << 20 ) * 16 )
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
/* Compute the tweak. */
ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
data_unit, tweak );
if( ret != 0 )
return( ret );
while( blocks-- )
{
size_t i;
if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
{
/* We are on the last block in a decrypt operation that has
* leftover bytes, so we need to use the next tweak for this block,
* and this tweak for the lefover bytes. Save the current tweak for
* the leftovers and then update the current tweak for use on this,
* the last full block. */
memcpy( prev_tweak, tweak, sizeof( tweak ) );
mbedtls_gf128mul_x_ble( tweak, tweak );
}
for( i = 0; i < 16; i++ )
tmp[i] = input[i] ^ tweak[i];
ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
if( ret != 0 )
return( ret );
for( i = 0; i < 16; i++ )
output[i] = tmp[i] ^ tweak[i];
/* Update the tweak for the next block. */
mbedtls_gf128mul_x_ble( tweak, tweak );
output += 16;
input += 16;
}
if( leftover )
{
/* If we are on the leftover bytes in a decrypt operation, we need to
* use the previous tweak for these bytes (as saved in prev_tweak). */
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
/* We are now on the final part of the data unit, which doesn't divide
* evenly by 16. It's time for ciphertext stealing. */
size_t i;
unsigned char *prev_output = output - 16;
/* Copy ciphertext bytes from the previous block to our output for each
* byte of cyphertext we won't steal. At the same time, copy the
* remainder of the input for this final round (since the loop bounds
* are the same). */
for( i = 0; i < leftover; i++ )
{
output[i] = prev_output[i];
tmp[i] = input[i] ^ t[i];
}
/* Copy ciphertext bytes from the previous block for input in this
* round. */
for( ; i < 16; i++ )
tmp[i] = prev_output[i] ^ t[i];
ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
if( ret != 0 )
return ret;
/* Write the result back to the previous block, overriding the previous
* output we copied. */
for( i = 0; i < 16; i++ )
prev_output[i] = tmp[i] ^ t[i];
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/*
* AES-CFB128 buffer encryption/decryption
@ -1061,7 +1306,41 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
return( 0 );
}
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/*
* AES-OFB (Output Feedback Mode) buffer encryption/decryption
*/
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int ret = 0;
size_t n = *iv_off;
while( length-- )
{
if( n == 0 )
{
ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
if( ret != 0 )
goto exit;
}
*output++ = *input++ ^ iv[n];
n = ( n + 1 ) & 0x0F;
}
*iv_off = n;
exit:
return( ret );
}
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
@ -1078,6 +1357,9 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
int c, i;
size_t n = *nc_off;
if ( n > 0x0F )
return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
while( length-- )
{
if( n == 0 ) {
@ -1215,6 +1497,72 @@ static const unsigned char aes_test_cfb128_ct[3][64] =
};
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/*
* AES-OFB test vectors from:
*
* https://csrc.nist.gov/publications/detail/sp/800-38a/final
*/
static const unsigned char aes_test_ofb_key[3][32] =
{
{ 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
{ 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
{ 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
};
static const unsigned char aes_test_ofb_iv[16] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};
static const unsigned char aes_test_ofb_pt[64] =
{
0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
};
static const unsigned char aes_test_ofb_ct[3][64] =
{
{ 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
{ 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
{ 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
};
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* AES-CTR test vectors from:
@ -1278,6 +1626,74 @@ static const int aes_test_ctr_len[3] =
{ 16, 32, 36 };
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/*
* AES-XTS test vectors from:
*
* IEEE P1619/D16 Annex B
* https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
* (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
*/
static const unsigned char aes_test_xts_key[][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
{ 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
};
static const unsigned char aes_test_xts_pt32[][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
{ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
};
static const unsigned char aes_test_xts_ct32[][32] =
{
{ 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
{ 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
{ 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
};
static const unsigned char aes_test_xts_data_unit[][16] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
};
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/*
* Checkup routine
*/
@ -1294,11 +1710,14 @@ int mbedtls_aes_self_test( int verbose )
#if defined(MBEDTLS_CIPHER_MODE_CBC)
unsigned char prv[16];
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB)
#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
defined(MBEDTLS_CIPHER_MODE_OFB)
size_t offset;
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
int len;
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
unsigned char nonce_counter[16];
unsigned char stream_block[16];
#endif
@ -1506,6 +1925,69 @@ int mbedtls_aes_self_test( int verbose )
mbedtls_printf( "\n" );
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/*
* OFB mode
*/
for( i = 0; i < 6; i++ )
{
u = i >> 1;
keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 )
mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_ofb_iv, 16 );
memcpy( key, aes_test_ofb_key[u], keybits / 8 );
offset = 0;
ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy( buf, aes_test_ofb_ct[u], 64 );
aes_tests = aes_test_ofb_pt;
}
else
{
memcpy( buf, aes_test_ofb_pt, 64 );
aes_tests = aes_test_ofb_ct[u];
}
ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_tests, 64 ) != 0 )
{
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* CTR mode
@ -1558,6 +2040,73 @@ int mbedtls_aes_self_test( int verbose )
mbedtls_printf( "\n" );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
{
static const int num_tests =
sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
mbedtls_aes_xts_context ctx_xts;
/*
* XTS mode
*/
mbedtls_aes_xts_init( &ctx_xts );
for( i = 0; i < num_tests << 1; i++ )
{
const unsigned char *data_unit;
u = i >> 1;
mode = i & 1;
if( verbose != 0 )
mbedtls_printf( " AES-XTS-128 (%s): ",
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( key, 0, sizeof( key ) );
memcpy( key, aes_test_xts_key[u], 32 );
data_unit = aes_test_xts_data_unit[u];
len = sizeof( *aes_test_xts_ct32 );
if( mode == MBEDTLS_AES_DECRYPT )
{
ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
if( ret != 0)
goto exit;
memcpy( buf, aes_test_xts_ct32[u], len );
aes_tests = aes_test_xts_pt32[u];
}
else
{
ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
if( ret != 0)
goto exit;
memcpy( buf, aes_test_xts_pt32[u], len );
aes_tests = aes_test_xts_ct32[u];
}
ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_tests, len ) != 0 )
{
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
mbedtls_aes_xts_free( &ctx_xts );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
ret = 0;
exit:

1028
library/aria.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -83,7 +83,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 4 );
}
#if SIZE_MAX > 0xFFFFFFFF
if( len <= 0xFFFFFFFF )
#endif
{
if( *p - start < 5 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@ -96,7 +98,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 5 );
}
#if SIZE_MAX > 0xFFFFFFFF
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
#endif
}
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )

View file

@ -152,8 +152,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
* Check length requirements: SP800-38C A.1
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
* 'length' checked later (when writing it to the first block)
*
* Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
*/
if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
/* Also implies q is within bounds */
@ -302,7 +304,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
/*
* Authenticated encryption
*/
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
@ -312,10 +314,23 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
add, add_len, input, output, tag, tag_len ) );
}
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
if( tag_len == 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
add_len, input, output, tag, tag_len ) );
}
/*
* Authenticated decryption
*/
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
@ -346,6 +361,18 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
return( 0 );
}
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len )
{
if( tag_len == 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
add_len, input, output, tag, tag_len ) );
}
#endif /* !MBEDTLS_CCM_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
@ -354,7 +381,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
*/
#define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/*
* The data is the same for all tests, only the used length changes
*/
@ -374,7 +402,7 @@ static const unsigned char ad[] = {
0x10, 0x11, 0x12, 0x13
};
static const unsigned char msg[] = {
static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
@ -385,7 +413,7 @@ static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
static const unsigned char res[NB_TESTS][32] = {
static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
@ -399,7 +427,13 @@ static const unsigned char res[NB_TESTS][32] = {
int mbedtls_ccm_self_test( int verbose )
{
mbedtls_ccm_context ctx;
unsigned char out[32];
/*
* Some hardware accelerators require the input and output buffers
* would be in RAM, because the flash is not accessible.
* Use buffers on the stack to hold the test vectors data.
*/
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i;
int ret;
@ -418,27 +452,32 @@ int mbedtls_ccm_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 );
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
memcpy( plaintext, msg, msg_len[i] );
ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i],
msg, out,
out + msg_len[i], tag_len[i] );
iv, iv_len[i], ad, add_len[i],
plaintext, ciphertext,
ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
iv, iv_len[i], ad, add_len[i],
res[i], out,
res[i] + msg_len[i], tag_len[i] );
iv, iv_len[i], ad, add_len[i],
ciphertext, plaintext,
ciphertext + msg_len[i], tag_len[i] );
if( ret != 0 ||
memcmp( out, msg, msg_len[i] ) != 0 )
memcmp( plaintext, msg, msg_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );

570
library/chacha20.c Normal file
View file

@ -0,0 +1,570 @@
/**
* \file chacha20.c
*
* \brief ChaCha20 cipher.
*
* \author Daniel King <damaki.gh@gmail.com>
*
* Copyright (C) 2006-2016, 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)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#include "mbedtls/platform_util.h"
#include <stddef.h>
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_CHACHA20_ALT)
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define BYTES_TO_U32_LE( data, offset ) \
( (uint32_t) data[offset] \
| (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \
| (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \
| (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \
)
#define ROTL32( value, amount ) \
( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) )
#define CHACHA20_CTR_INDEX ( 12U )
#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
/**
* \brief ChaCha20 quarter round operation.
*
* The quarter round is defined as follows (from RFC 7539):
* 1. a += b; d ^= a; d <<<= 16;
* 2. c += d; b ^= c; b <<<= 12;
* 3. a += b; d ^= a; d <<<= 8;
* 4. c += d; b ^= c; b <<<= 7;
*
* \param state ChaCha20 state to modify.
* \param a The index of 'a' in the state.
* \param b The index of 'b' in the state.
* \param c The index of 'c' in the state.
* \param d The index of 'd' in the state.
*/
static inline void chacha20_quarter_round( uint32_t state[16],
size_t a,
size_t b,
size_t c,
size_t d )
{
/* a += b; d ^= a; d <<<= 16; */
state[a] += state[b];
state[d] ^= state[a];
state[d] = ROTL32( state[d], 16 );
/* c += d; b ^= c; b <<<= 12 */
state[c] += state[d];
state[b] ^= state[c];
state[b] = ROTL32( state[b], 12 );
/* a += b; d ^= a; d <<<= 8; */
state[a] += state[b];
state[d] ^= state[a];
state[d] = ROTL32( state[d], 8 );
/* c += d; b ^= c; b <<<= 7; */
state[c] += state[d];
state[b] ^= state[c];
state[b] = ROTL32( state[b], 7 );
}
/**
* \brief Perform the ChaCha20 inner block operation.
*
* This function performs two rounds: the column round and the
* diagonal round.
*
* \param state The ChaCha20 state to update.
*/
static void chacha20_inner_block( uint32_t state[16] )
{
chacha20_quarter_round( state, 0, 4, 8, 12 );
chacha20_quarter_round( state, 1, 5, 9, 13 );
chacha20_quarter_round( state, 2, 6, 10, 14 );
chacha20_quarter_round( state, 3, 7, 11, 15 );
chacha20_quarter_round( state, 0, 5, 10, 15 );
chacha20_quarter_round( state, 1, 6, 11, 12 );
chacha20_quarter_round( state, 2, 7, 8, 13 );
chacha20_quarter_round( state, 3, 4, 9, 14 );
}
/**
* \brief Generates a keystream block.
*
* \param initial_state The initial ChaCha20 state (key, nonce, counter).
* \param keystream Generated keystream bytes are written to this buffer.
*/
static void chacha20_block( const uint32_t initial_state[16],
unsigned char keystream[64] )
{
uint32_t working_state[16];
size_t i;
memcpy( working_state,
initial_state,
CHACHA20_BLOCK_SIZE_BYTES );
for( i = 0U; i < 10U; i++ )
chacha20_inner_block( working_state );
working_state[ 0] += initial_state[ 0];
working_state[ 1] += initial_state[ 1];
working_state[ 2] += initial_state[ 2];
working_state[ 3] += initial_state[ 3];
working_state[ 4] += initial_state[ 4];
working_state[ 5] += initial_state[ 5];
working_state[ 6] += initial_state[ 6];
working_state[ 7] += initial_state[ 7];
working_state[ 8] += initial_state[ 8];
working_state[ 9] += initial_state[ 9];
working_state[10] += initial_state[10];
working_state[11] += initial_state[11];
working_state[12] += initial_state[12];
working_state[13] += initial_state[13];
working_state[14] += initial_state[14];
working_state[15] += initial_state[15];
for( i = 0U; i < 16; i++ )
{
size_t offset = i * 4U;
keystream[offset ] = (unsigned char)( working_state[i] );
keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
}
mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
}
void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
{
if( ctx != NULL )
{
mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
/* Initially, there's no keystream bytes available */
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
}
}
void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
{
if( ctx != NULL )
{
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
}
}
int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
const unsigned char key[32] )
{
if( ( ctx == NULL ) || ( key == NULL ) )
{
return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
}
/* ChaCha20 constants - the string "expand 32-byte k" */
ctx->state[0] = 0x61707865;
ctx->state[1] = 0x3320646e;
ctx->state[2] = 0x79622d32;
ctx->state[3] = 0x6b206574;
/* Set key */
ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
return( 0 );
}
int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
const unsigned char nonce[12],
uint32_t counter )
{
if( ( ctx == NULL ) || ( nonce == NULL ) )
{
return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
}
/* Counter */
ctx->state[12] = counter;
/* Nonce */
ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
/* Initially, there's no keystream bytes available */
ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
return( 0 );
}
int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
size_t size,
const unsigned char *input,
unsigned char *output )
{
size_t offset = 0U;
size_t i;
if( ctx == NULL )
{
return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
}
else if( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
{
/* input and output pointers are allowed to be NULL only if size == 0 */
return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
}
/* Use leftover keystream bytes, if available */
while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
{
output[offset] = input[offset]
^ ctx->keystream8[ctx->keystream_bytes_used];
ctx->keystream_bytes_used++;
offset++;
size--;
}
/* Process full blocks */
while( size >= CHACHA20_BLOCK_SIZE_BYTES )
{
/* Generate new keystream block and increment counter */
chacha20_block( ctx->state, ctx->keystream8 );
ctx->state[CHACHA20_CTR_INDEX]++;
for( i = 0U; i < 64U; i += 8U )
{
output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ];
output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
}
offset += CHACHA20_BLOCK_SIZE_BYTES;
size -= CHACHA20_BLOCK_SIZE_BYTES;
}
/* Last (partial) block */
if( size > 0U )
{
/* Generate new keystream block and increment counter */
chacha20_block( ctx->state, ctx->keystream8 );
ctx->state[CHACHA20_CTR_INDEX]++;
for( i = 0U; i < size; i++)
{
output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
}
ctx->keystream_bytes_used = size;
}
return( 0 );
}
int mbedtls_chacha20_crypt( const unsigned char key[32],
const unsigned char nonce[12],
uint32_t counter,
size_t data_len,
const unsigned char* input,
unsigned char* output )
{
mbedtls_chacha20_context ctx;
int ret;
mbedtls_chacha20_init( &ctx );
ret = mbedtls_chacha20_setkey( &ctx, key );
if( ret != 0 )
goto cleanup;
ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
if( ret != 0 )
goto cleanup;
ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
cleanup:
mbedtls_chacha20_free( &ctx );
return( ret );
}
#endif /* !MBEDTLS_CHACHA20_ALT */
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char test_keys[2][32] =
{
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
}
};
static const unsigned char test_nonces[2][12] =
{
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02
}
};
static const uint32_t test_counters[2] =
{
0U,
1U
};
static const unsigned char test_input[2][375] =
{
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
}
};
static const unsigned char test_output[2][375] =
{
{
0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
},
{
0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
}
};
static const size_t test_lengths[2] =
{
64U,
375U
};
#define ASSERT( cond, args ) \
do \
{ \
if( ! ( cond ) ) \
{ \
if( verbose != 0 ) \
mbedtls_printf args; \
\
return( -1 ); \
} \
} \
while( 0 )
int mbedtls_chacha20_self_test( int verbose )
{
unsigned char output[381];
unsigned i;
int ret;
for( i = 0U; i < 2U; i++ )
{
if( verbose != 0 )
mbedtls_printf( " ChaCha20 test %u ", i );
ret = mbedtls_chacha20_crypt( test_keys[i],
test_nonces[i],
test_counters[i],
test_lengths[i],
test_input[i],
output );
ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
( "failed (output)\n" ) );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* !MBEDTLS_CHACHA20_C */

547
library/chachapoly.c Normal file
View file

@ -0,0 +1,547 @@
/**
* \file chachapoly.c
*
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
*
* Copyright (C) 2006-2016, 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)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#include "mbedtls/platform_util.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
#define CHACHAPOLY_STATE_INIT ( 0 )
#define CHACHAPOLY_STATE_AAD ( 1 )
#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
#define CHACHAPOLY_STATE_FINISHED ( 3 )
/**
* \brief Adds nul bytes to pad the AAD for Poly1305.
*
* \param ctx The ChaCha20-Poly1305 context.
*/
static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
{
uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
unsigned char zeroes[15];
if( partial_block_len == 0U )
return( 0 );
memset( zeroes, 0, sizeof( zeroes ) );
return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
zeroes,
16U - partial_block_len ) );
}
/**
* \brief Adds nul bytes to pad the ciphertext for Poly1305.
*
* \param ctx The ChaCha20-Poly1305 context.
*/
static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
{
uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
unsigned char zeroes[15];
if( partial_block_len == 0U )
return( 0 );
memset( zeroes, 0, sizeof( zeroes ) );
return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
zeroes,
16U - partial_block_len ) );
}
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
{
if( ctx != NULL )
{
mbedtls_chacha20_init( &ctx->chacha20_ctx );
mbedtls_poly1305_init( &ctx->poly1305_ctx );
ctx->aad_len = 0U;
ctx->ciphertext_len = 0U;
ctx->state = CHACHAPOLY_STATE_INIT;
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
}
}
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
{
if( ctx != NULL )
{
mbedtls_chacha20_free( &ctx->chacha20_ctx );
mbedtls_poly1305_free( &ctx->poly1305_ctx );
ctx->aad_len = 0U;
ctx->ciphertext_len = 0U;
ctx->state = CHACHAPOLY_STATE_INIT;
ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT;
}
}
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] )
{
int ret;
if( ( ctx == NULL ) || ( key == NULL ) )
{
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
return( ret );
}
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
const unsigned char nonce[12],
mbedtls_chachapoly_mode_t mode )
{
int ret;
unsigned char poly1305_key[64];
if( ( ctx == NULL ) || ( nonce == NULL ) )
{
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
/* Set counter = 0, will be update to 1 when generating Poly1305 key */
ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
if( ret != 0 )
goto cleanup;
/* Generate the Poly1305 key by getting the ChaCha20 keystream output with
* counter = 0. This is the same as encrypting a buffer of zeroes.
* Only the first 256-bits (32 bytes) of the key is used for Poly1305.
* The other 256 bits are discarded.
*/
memset( poly1305_key, 0, sizeof( poly1305_key ) );
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
poly1305_key, poly1305_key );
if( ret != 0 )
goto cleanup;
ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
if( ret == 0 )
{
ctx->aad_len = 0U;
ctx->ciphertext_len = 0U;
ctx->state = CHACHAPOLY_STATE_AAD;
ctx->mode = mode;
}
cleanup:
mbedtls_platform_zeroize( poly1305_key, 64U );
return( ret );
}
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
const unsigned char *aad,
size_t aad_len )
{
if( ctx == NULL )
{
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
else if( ( aad_len > 0U ) && ( aad == NULL ) )
{
/* aad pointer is allowed to be NULL if aad_len == 0 */
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
else if( ctx->state != CHACHAPOLY_STATE_AAD )
{
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
}
ctx->aad_len += aad_len;
return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
}
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
size_t len,
const unsigned char *input,
unsigned char *output )
{
int ret;
if( ctx == NULL )
{
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
else if( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) )
{
/* input and output pointers are allowed to be NULL if len == 0 */
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
else if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
{
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
}
if( ctx->state == CHACHAPOLY_STATE_AAD )
{
ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
ret = chachapoly_pad_aad( ctx );
if( ret != 0 )
return( ret );
}
ctx->ciphertext_len += len;
if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
{
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
if( ret != 0 )
return( ret );
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
if( ret != 0 )
return( ret );
}
else /* DECRYPT */
{
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
if( ret != 0 )
return( ret );
ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
if( ret != 0 )
return( ret );
}
return( 0 );
}
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
unsigned char mac[16] )
{
int ret;
unsigned char len_block[16];
if( ( ctx == NULL ) || ( mac == NULL ) )
{
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
}
else if( ctx->state == CHACHAPOLY_STATE_INIT )
{
return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
}
if( ctx->state == CHACHAPOLY_STATE_AAD )
{
ret = chachapoly_pad_aad( ctx );
if( ret != 0 )
return( ret );
}
else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
{
ret = chachapoly_pad_ciphertext( ctx );
if( ret != 0 )
return( ret );
}
ctx->state = CHACHAPOLY_STATE_FINISHED;
/* The lengths of the AAD and ciphertext are processed by
* Poly1305 as the final 128-bit block, encoded as little-endian integers.
*/
len_block[ 0] = (unsigned char)( ctx->aad_len );
len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 );
len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
len_block[ 8] = (unsigned char)( ctx->ciphertext_len );
len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 );
len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
if( ret != 0 )
return( ret );
ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
return( ret );
}
static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
mbedtls_chachapoly_mode_t mode,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char *input,
unsigned char *output,
unsigned char tag[16] )
{
int ret;
ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
if( ret != 0 )
goto cleanup;
ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
if( ret != 0 )
goto cleanup;
ret = mbedtls_chachapoly_update( ctx, length, input, output );
if( ret != 0 )
goto cleanup;
ret = mbedtls_chachapoly_finish( ctx, tag );
cleanup:
return( ret );
}
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char *input,
unsigned char *output,
unsigned char tag[16] )
{
return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
length, nonce, aad, aad_len,
input, output, tag ) );
}
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
size_t length,
const unsigned char nonce[12],
const unsigned char *aad,
size_t aad_len,
const unsigned char tag[16],
const unsigned char *input,
unsigned char *output )
{
int ret;
unsigned char check_tag[16];
size_t i;
int diff;
if( tag == NULL )
return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA );
if( ( ret = chachapoly_crypt_and_tag( ctx,
MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
aad, aad_len, input, output, check_tag ) ) != 0 )
{
return( ret );
}
/* Check tag in "constant-time" */
for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
diff |= tag[i] ^ check_tag[i];
if( diff != 0 )
{
mbedtls_platform_zeroize( output, length );
return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
}
return( 0 );
}
#endif /* MBEDTLS_CHACHAPOLY_ALT */
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char test_key[1][32] =
{
{
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
}
};
static const unsigned char test_nonce[1][12] =
{
{
0x07, 0x00, 0x00, 0x00, /* 32-bit common part */
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */
}
};
static const unsigned char test_aad[1][12] =
{
{
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7
}
};
static const size_t test_aad_len[1] =
{
12U
};
static const unsigned char test_input[1][114] =
{
{
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
0x74, 0x2e
}
};
static const unsigned char test_output[1][114] =
{
{
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
0x61, 0x16
}
};
static const size_t test_input_len[1] =
{
114U
};
static const unsigned char test_mac[1][16] =
{
{
0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
}
};
#define ASSERT( cond, args ) \
do \
{ \
if( ! ( cond ) ) \
{ \
if( verbose != 0 ) \
mbedtls_printf args; \
\
return( -1 ); \
} \
} \
while( 0 )
int mbedtls_chachapoly_self_test( int verbose )
{
mbedtls_chachapoly_context ctx;
unsigned i;
int ret;
unsigned char output[200];
unsigned char mac[16];
for( i = 0U; i < 1U; i++ )
{
if( verbose != 0 )
mbedtls_printf( " ChaCha20-Poly1305 test %u ", i );
mbedtls_chachapoly_init( &ctx );
ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
test_input_len[i],
test_nonce[i],
test_aad[i],
test_aad_len[i],
test_input[i],
output,
mac );
ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
( "failure (wrong output)\n" ) );
ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
( "failure (wrong MAC)\n" ) );
mbedtls_chachapoly_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_CHACHAPOLY_C */

View file

@ -38,6 +38,10 @@
#include <stdlib.h>
#include <string.h>
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#endif
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
@ -46,6 +50,10 @@
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#endif
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#endif
@ -57,9 +65,25 @@
#define mbedtls_free free
#endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/* Compare the contents of two buffers in constant time.
* Returns 0 if the contents are bitwise identical, otherwise returns
* a non-zero value.
* This is currently only used by GCM and ChaCha20+Poly1305.
*/
static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
{
const unsigned char *p1 = (const unsigned char*) v1;
const unsigned char *p2 = (const unsigned char*) v2;
size_t i;
unsigned char diff;
for( diff = 0, i = 0; i < len; i++ )
diff |= p1[i] ^ p2[i];
return (int)diff;
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
static int supported_init = 0;
@ -191,10 +215,11 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k
ctx->operation = operation;
/*
* For CFB and CTR mode always use the encryption key schedule
* For OFB, CFB and CTR mode always use the encryption key schedule
*/
if( MBEDTLS_ENCRYPT == operation ||
MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
{
return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
@ -212,9 +237,13 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len )
{
size_t actual_iv_size;
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
else if( NULL == iv && iv_len != 0 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( NULL == iv && iv_len == 0 )
ctx->iv_size = 0;
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@ -231,8 +260,23 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
memcpy( ctx->iv, iv, actual_iv_size );
ctx->iv_size = actual_iv_size;
#if defined(MBEDTLS_CHACHA20_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
{
if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
iv,
0U ) ) /* Initial counter value */
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
}
#endif
if ( actual_iv_size != 0 )
{
memcpy( ctx->iv, iv, actual_iv_size );
ctx->iv_size = actual_iv_size;
}
return( 0 );
}
@ -247,22 +291,45 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
return( 0 );
}
#if defined(MBEDTLS_GCM_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
ctx->iv, ctx->iv_size, ad, ad_len );
}
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
int result;
mbedtls_chachapoly_mode_t mode;
mode = ( ctx->operation == MBEDTLS_ENCRYPT )
? MBEDTLS_CHACHAPOLY_ENCRYPT
: MBEDTLS_CHACHAPOLY_DECRYPT;
result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
ctx->iv,
mode );
if ( result != 0 )
return( result );
return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
ad, ad_len );
}
#endif
return( 0 );
}
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen )
@ -303,6 +370,15 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
{
*olen = ilen;
return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
ilen, input, output );
}
#endif
if ( 0 == block_size )
{
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
@ -424,6 +500,21 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
{
if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
{
return( ret );
}
*olen = ilen;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
{
@ -440,6 +531,27 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
}
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
{
if( ctx->unprocessed_len > 0 ) {
/* We can only process an entire data unit at a time. */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
ctx->operation, ilen, ctx->iv, input, output );
if( ret != 0 )
{
return( ret );
}
*olen = ilen;
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
{
@ -639,13 +751,21 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
*olen = 0;
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
{
return( 0 );
}
if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) ||
( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
{
return( 0 );
}
if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
{
if( ctx->unprocessed_len != 0 )
@ -757,7 +877,7 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_ciph
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
#if defined(MBEDTLS_GCM_C)
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len )
{
@ -767,8 +887,22 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
if( MBEDTLS_ENCRYPT != ctx->operation )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len );
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* Don't allow truncated MAC for Poly1305 */
if ( tag_len != 16U )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
tag );
}
#endif
return( 0 );
}
@ -776,6 +910,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len )
{
unsigned char check_tag[16];
int ret;
if( NULL == ctx || NULL == ctx->cipher_info ||
@ -784,12 +919,9 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
unsigned char check_tag[16];
size_t i;
int diff;
if( tag_len > sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@ -800,18 +932,38 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
}
/* Check the tag in "constant-time" */
for( diff = 0, i = 0; i < tag_len; i++ )
diff |= tag[i] ^ check_tag[i];
if( diff != 0 )
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
return( 0 );
}
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* Don't allow truncated MAC for Poly1305 */
if ( tag_len != sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
check_tag );
if ( ret != 0 )
{
return( ret );
}
/* Check the tag in "constant-time" */
if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
return( 0 );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( 0 );
}
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/*
* Packet-oriented wrapper for non-AEAD modes
@ -870,6 +1022,21 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
tag, tag_len ) );
}
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
( tag_len != 16U ) )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
*olen = ilen;
return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
ilen, iv, ad, ad_len, input, output, tag ) );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
@ -916,6 +1083,28 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
return( ret );
}
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
int ret;
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
( tag_len != 16U ) )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
*olen = ilen;
ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
iv, ad, ad_len, tag, input, output );
if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
return( ret );
}
#endif /* MBEDTLS_CHACHAPOLY_C */
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}

File diff suppressed because it is too large Load diff

View file

@ -828,6 +828,7 @@ static int cmac_test_subkeys( int verbose,
mbedtls_cipher_free( &ctx );
}
ret = 0;
goto exit;
cleanup:
@ -883,6 +884,7 @@ static int cmac_test_wth_cipher( int verbose,
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
ret = 0;
exit:
return( ret );

View file

@ -66,6 +66,18 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
* Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
* NIST tests to succeed (which require known length fixed entropy)
*/
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
* custom, len, entropy_len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* custom[:len] = nonce || personalization_string
* where entropy_input comes from f_entropy for entropy_len bytes
* and with outputs
* ctx = initial_working_state
*/
int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
@ -256,6 +268,14 @@ exit:
return( ret );
}
/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
* ctr_drbg_update_internal(ctx, provided_data)
* implements
* CTR_DRBG_Update(provided_data, Key, V)
* with inputs and outputs
* ctx->aes_ctx = Key
* ctx->counter = V
*/
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
{
@ -301,6 +321,18 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
return( 0 );
}
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_update(ctx, additional, add_len)
* implements
* CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
* security_strength) -> initial_working_state
* with inputs
* ctx->counter = all-bits-0
* ctx->aes_ctx = context from all-bits-0 key
* additional[:add_len] = entropy_input || nonce || personalization_string
* and with outputs
* ctx = initial_working_state
*/
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len )
{
@ -318,6 +350,18 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
}
}
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
* mbedtls_ctr_drbg_reseed(ctx, additional, len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
* -> new_working_state
* with inputs
* ctx contains working_state
* additional[:len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
* and with output
* ctx contains new_working_state
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len )
{
@ -371,6 +415,25 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
return( 0 );
}
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
* -> working_state_after_reseed
* if required, then
* CTR_DRBG_Generate(working_state_after_reseed,
* requested_number_of_bits, additional_input)
* -> status, returned_bits, new_working_state
* with inputs
* ctx contains working_state
* requested_number_of_bits = 8 * output_len
* additional[:add_len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
* and with outputs
* status = SUCCESS (this function does the reseed internally)
* returned_bits = output[:output_len]
* ctx contains new_working_state
*/
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len )

View file

@ -40,13 +40,41 @@
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/*
* Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
* Generate public key (restartable version)
*
* Note: this internal function relies on its caller preserving the value of
* the output parameter 'd' across continuation calls. This would not be
* acceptable for a public function but is OK here as we control call sites.
*/
static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret;
/* If multiplication is in progress, we already generated a privkey */
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
#endif
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
f_rng, p_rng, rs_ctx ) );
cleanup:
return( ret );
}
/*
* Generate public key
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
}
#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
@ -54,22 +82,20 @@ int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
/*
* Compute shared secret (SEC1 3.3.1)
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret;
mbedtls_ecp_point P;
mbedtls_ecp_point_init( &P );
/*
* Make sure Q is a valid pubkey before using it
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q,
f_rng, p_rng, rs_ctx ) );
if( mbedtls_ecp_is_zero( &P ) )
{
@ -86,12 +112,37 @@ cleanup:
}
#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
/*
* Compute shared secret (SEC1 3.3.1)
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( ecdh_compute_shared_restartable( grp, z, Q, d,
f_rng, p_rng, NULL ) );
}
/*
* Initialize context
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
mbedtls_ecp_group_init( &ctx->grp );
mbedtls_mpi_init( &ctx->d );
mbedtls_ecp_point_init( &ctx->Q );
mbedtls_ecp_point_init( &ctx->Qp );
mbedtls_mpi_init( &ctx->z );
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
mbedtls_ecp_point_init( &ctx->Vi );
mbedtls_ecp_point_init( &ctx->Vf );
mbedtls_mpi_init( &ctx->_d );
#if defined(MBEDTLS_ECP_RESTARTABLE)
ctx->restart_enabled = 0;
mbedtls_ecp_restart_init( &ctx->rs );
#endif
}
/*
@ -103,15 +154,29 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
return;
mbedtls_ecp_group_free( &ctx->grp );
mbedtls_mpi_free( &ctx->d );
mbedtls_ecp_point_free( &ctx->Q );
mbedtls_ecp_point_free( &ctx->Qp );
mbedtls_mpi_free( &ctx->z );
mbedtls_ecp_point_free( &ctx->Vi );
mbedtls_ecp_point_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->d );
mbedtls_mpi_free( &ctx->z );
mbedtls_mpi_free( &ctx->_d );
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_free( &ctx->rs );
#endif
}
#if defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Enable restartable operations for context
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
{
ctx->restart_enabled = 1;
}
#endif
/*
* Setup and write the ServerKeyExhange parameters (RFC 4492)
* struct {
@ -126,12 +191,18 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
{
int ret;
size_t grp_len, pt_len;
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( ctx->restart_enabled )
rs_ctx = &ctx->rs;
#endif
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
f_rng, p_rng, rs_ctx ) ) != 0 )
return( ret );
if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
@ -142,7 +213,7 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
blen -= grp_len;
if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
&pt_len, buf, blen ) ) != 0 )
&pt_len, buf, blen ) ) != 0 )
return( ret );
*olen = grp_len + pt_len;
@ -206,12 +277,18 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng )
{
int ret;
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( ctx->restart_enabled )
rs_ctx = &ctx->rs;
#endif
if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
f_rng, p_rng, rs_ctx ) ) != 0 )
return( ret );
return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
@ -248,12 +325,18 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
void *p_rng )
{
int ret;
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
if( ctx == NULL )
if( ctx == NULL || ctx->grp.pbits == 0 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
f_rng, p_rng ) ) != 0 )
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( ctx->restart_enabled )
rs_ctx = &ctx->rs;
#endif
if( ( ret = ecdh_compute_shared_restartable( &ctx->grp,
&ctx->z, &ctx->Qp, &ctx->d, f_rng, p_rng, rs_ctx ) ) != 0 )
{
return( ret );
}

View file

@ -42,6 +42,178 @@
#include "mbedtls/hmac_drbg.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Sub-context for ecdsa_verify()
*/
struct mbedtls_ecdsa_restart_ver
{
mbedtls_mpi u1, u2; /* intermediate values */
enum { /* what to do next? */
ecdsa_ver_init = 0, /* getting started */
ecdsa_ver_muladd, /* muladd step */
} state;
};
/*
* Init verify restart sub-context
*/
static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx )
{
mbedtls_mpi_init( &ctx->u1 );
mbedtls_mpi_init( &ctx->u2 );
ctx->state = ecdsa_ver_init;
}
/*
* Free the components of a verify restart sub-context
*/
static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx )
{
if( ctx == NULL )
return;
mbedtls_mpi_free( &ctx->u1 );
mbedtls_mpi_free( &ctx->u2 );
ecdsa_restart_ver_init( ctx );
}
/*
* Sub-context for ecdsa_sign()
*/
struct mbedtls_ecdsa_restart_sig
{
int sign_tries;
int key_tries;
mbedtls_mpi k; /* per-signature random */
mbedtls_mpi r; /* r value */
enum { /* what to do next? */
ecdsa_sig_init = 0, /* getting started */
ecdsa_sig_mul, /* doing ecp_mul() */
ecdsa_sig_modn, /* mod N computations */
} state;
};
/*
* Init verify sign sub-context
*/
static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx )
{
ctx->sign_tries = 0;
ctx->key_tries = 0;
mbedtls_mpi_init( &ctx->k );
mbedtls_mpi_init( &ctx->r );
ctx->state = ecdsa_sig_init;
}
/*
* Free the components of a sign restart sub-context
*/
static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx )
{
if( ctx == NULL )
return;
mbedtls_mpi_free( &ctx->k );
mbedtls_mpi_free( &ctx->r );
}
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/*
* Sub-context for ecdsa_sign_det()
*/
struct mbedtls_ecdsa_restart_det
{
mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */
enum { /* what to do next? */
ecdsa_det_init = 0, /* getting started */
ecdsa_det_sign, /* make signature */
} state;
};
/*
* Init verify sign_det sub-context
*/
static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx )
{
mbedtls_hmac_drbg_init( &ctx->rng_ctx );
ctx->state = ecdsa_det_init;
}
/*
* Free the components of a sign_det restart sub-context
*/
static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
{
if( ctx == NULL )
return;
mbedtls_hmac_drbg_free( &ctx->rng_ctx );
ecdsa_restart_det_init( ctx );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#define ECDSA_RS_ECP &rs_ctx->ecp
/* Utility macro for checking and updating ops budget */
#define ECDSA_BUDGET( ops ) \
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
/* Call this when entering a function that needs its own sub-context */
#define ECDSA_RS_ENTER( SUB ) do { \
/* reset ops count for this call if top-level */ \
if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 ) \
rs_ctx->ecp.ops_done = 0; \
\
/* set up our own sub-context if needed */ \
if( mbedtls_ecp_restart_is_enabled() && \
rs_ctx != NULL && rs_ctx->SUB == NULL ) \
{ \
rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) ); \
if( rs_ctx->SUB == NULL ) \
return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); \
\
ecdsa_restart_## SUB ##_init( rs_ctx->SUB ); \
} \
} while( 0 )
/* Call this when leaving a function that needs its own sub-context */
#define ECDSA_RS_LEAVE( SUB ) do { \
/* clear our sub-context when not in progress (done or error) */ \
if( rs_ctx != NULL && rs_ctx->SUB != NULL && \
ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) \
{ \
ecdsa_restart_## SUB ##_free( rs_ctx->SUB ); \
mbedtls_free( rs_ctx->SUB ); \
rs_ctx->SUB = NULL; \
} \
\
if( rs_ctx != NULL ) \
rs_ctx->ecp.depth--; \
} while( 0 )
#else /* MBEDTLS_ECP_RESTARTABLE */
#define ECDSA_RS_ECP NULL
#define ECDSA_BUDGET( ops ) /* no-op; for compatibility */
#define ECDSA_RS_ENTER( SUB ) (void) rs_ctx
#define ECDSA_RS_LEAVE( SUB ) (void) rs_ctx
#endif /* MBEDTLS_ECP_RESTARTABLE */
/*
* Derive a suitable integer for group grp from a buffer of length len
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
@ -70,13 +242,17 @@ cleanup:
* Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret, key_tries, sign_tries, blind_tries;
int ret, key_tries, sign_tries;
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
mbedtls_ecp_point R;
mbedtls_mpi k, e, t;
mbedtls_mpi *pk = &k, *pr = r;
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
if( grp->N.p == NULL )
@ -89,26 +265,72 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
sign_tries = 0;
ECDSA_RS_ENTER( sig );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->sig != NULL )
{
/* redirect to our context */
p_sign_tries = &rs_ctx->sig->sign_tries;
p_key_tries = &rs_ctx->sig->key_tries;
pk = &rs_ctx->sig->k;
pr = &rs_ctx->sig->r;
/* jump to current step */
if( rs_ctx->sig->state == ecdsa_sig_mul )
goto mul;
if( rs_ctx->sig->state == ecdsa_sig_modn )
goto modn;
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
*p_sign_tries = 0;
do
{
if( *p_sign_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
/*
* Steps 1-3: generate a suitable ephemeral keypair
* and set r = xR mod n
*/
key_tries = 0;
*p_key_tries = 0;
do
{
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
if( key_tries++ > 10 )
if( *p_key_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->sig != NULL )
rs_ctx->sig->state = ecdsa_sig_mul;
mul:
#endif
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
f_rng, p_rng, ECDSA_RS_ECP ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
}
while( mbedtls_mpi_cmp_int( r, 0 ) == 0 );
while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->sig != NULL )
rs_ctx->sig->state = ecdsa_sig_modn;
modn:
#endif
/*
* Accounting for everything up to the end of the loop
* (step 6, but checking now avoids saving e and t)
*/
ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 );
/*
* Step 5: derive MPI from hashed message
@ -119,57 +341,60 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
* Generate a random value to blind inv_mod in next step,
* avoiding a potential timing leak.
*/
blind_tries = 0;
do
{
size_t n_size = ( grp->nbits + 7 ) / 8;
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t, n_size, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t, 8 * n_size - grp->nbits ) );
/* See mbedtls_ecp_gen_keypair() */
if( ++blind_tries > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
}
while( mbedtls_mpi_cmp_int( &t, 1 ) < 0 ||
mbedtls_mpi_cmp_mpi( &t, &grp->N ) >= 0 );
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng, p_rng ) );
/*
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
if( sign_tries++ > 10 )
{
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
goto cleanup;
}
}
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->sig != NULL )
mbedtls_mpi_copy( r, pr );
#endif
cleanup:
mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
ECDSA_RS_LEAVE( sig );
return( ret );
}
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
/*
* Compute ECDSA signature of a hashed message
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
f_rng, p_rng, NULL ) );
}
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/*
* Deterministic signature wrapper
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
mbedtls_md_type_t md_alg,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
mbedtls_hmac_drbg_context rng_ctx;
mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
size_t grp_len = ( grp->nbits + 7 ) / 8;
const mbedtls_md_info_t *md_info;
@ -181,21 +406,53 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
mbedtls_mpi_init( &h );
mbedtls_hmac_drbg_init( &rng_ctx );
ECDSA_RS_ENTER( det );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->det != NULL )
{
/* redirect to our context */
p_rng = &rs_ctx->det->rng_ctx;
/* jump to current step */
if( rs_ctx->det->state == ecdsa_det_sign )
goto sign;
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len );
mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len );
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, &rng_ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->det != NULL )
rs_ctx->det->state = ecdsa_det_sign;
sign:
#endif
ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng, rs_ctx );
cleanup:
mbedtls_hmac_drbg_free( &rng_ctx );
mbedtls_mpi_free( &h );
ECDSA_RS_LEAVE( det );
return( ret );
}
/*
* Deterministic signature wrapper
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
{
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
@ -203,21 +460,40 @@ cleanup:
* Verify ECDSA signature of hashed message (SEC1 4.1.4)
* Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r, const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
mbedtls_mpi e, s_inv, u1, u2;
mbedtls_ecp_point R;
mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv );
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
if( grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
ECDSA_RS_ENTER( ver );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->ver != NULL )
{
/* redirect to our context */
pu1 = &rs_ctx->ver->u1;
pu2 = &rs_ctx->ver->u2;
/* jump to current step */
if( rs_ctx->ver->state == ecdsa_ver_muladd )
goto muladd;
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
/*
* Step 1: make sure r and s are in range 1..n-1
*/
@ -228,11 +504,6 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
goto cleanup;
}
/*
* Additional precaution: make sure Q is valid
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
/*
* Step 3: derive MPI from hashed message
*/
@ -241,21 +512,27 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
/*
* Step 4: u1 = e / s mod n, u2 = r / s mod n
*/
ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) );
#if defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && rs_ctx->ver != NULL )
rs_ctx->ver->state = ecdsa_ver_muladd;
muladd:
#endif
/*
* Step 5: R = u1 G + u2 Q
*
* Since we're not using any secret data, no need to pass a RNG to
* mbedtls_ecp_mul() for countermesures.
*/
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp,
&R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) );
if( mbedtls_ecp_is_zero( &R ) )
{
@ -280,12 +557,25 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
cleanup:
mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv );
mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
ECDSA_RS_LEAVE( ver );
return( ret );
}
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
/*
* Verify ECDSA signature of hashed message
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
{
return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
}
/*
* Convert a signature (given by context) to ASN.1
*/
@ -313,11 +603,13 @@ static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
/*
* Compute and write signature
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
mbedtls_mpi r, s;
@ -329,13 +621,13 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
(void) f_rng;
(void) p_rng;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, md_alg ) );
MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, md_alg, rs_ctx ) );
#else
(void) md_alg;
MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
hash, hlen, f_rng, p_rng, rs_ctx ) );
#endif
MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
@ -347,6 +639,19 @@ cleanup:
return( ret );
}
/*
* Compute and write signature
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( mbedtls_ecdsa_write_signature_restartable(
ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
}
#if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \
defined(MBEDTLS_ECDSA_DETERMINISTIC)
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
@ -365,6 +670,18 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen )
{
return( mbedtls_ecdsa_read_signature_restartable(
ctx, hash, hlen, sig, slen, NULL ) );
}
/*
* Restartable read and check signature
*/
int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
int ret;
unsigned char *p = (unsigned char *) sig;
@ -396,8 +713,8 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
goto cleanup;
}
if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
&ctx->Q, &r, &s ) ) != 0 )
if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
&ctx->Q, &r, &s, rs_ctx ) ) != 0 )
goto cleanup;
/* At this point we know that the buffer starts with a valid signature.
@ -458,4 +775,42 @@ void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
mbedtls_ecp_keypair_free( ctx );
}
#if defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Initialize a restart context
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
{
mbedtls_ecp_restart_init( &ctx->ecp );
ctx->ver = NULL;
ctx->sig = NULL;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
ctx->det = NULL;
#endif
}
/*
* Free the components of a restart context
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
{
mbedtls_ecp_restart_free( &ctx->ecp );
ecdsa_restart_ver_free( ctx->ver );
mbedtls_free( ctx->ver );
ctx->ver = NULL;
ecdsa_restart_sig_free( ctx->sig );
mbedtls_free( ctx->sig );
ctx->sig = NULL;
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
ecdsa_restart_det_free( ctx->det );
mbedtls_free( ctx->det );
ctx->det = NULL;
#endif
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDSA_C */

File diff suppressed because it is too large Load diff

View file

@ -19,19 +19,25 @@
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if defined(__linux__)
/* Ensure that syscall() is available even when compiling with -std=c99 */
#define _GNU_SOURCE
#endif
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <string.h>
#if defined(MBEDTLS_ENTROPY_C)
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#if defined(MBEDTLS_TIMING_C)
#include <string.h>
#include "mbedtls/timing.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
@ -44,7 +50,8 @@
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__)
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
!defined(__HAIKU__)
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
#endif

View file

@ -49,6 +49,10 @@
#include "mbedtls/arc4.h"
#endif
#if defined(MBEDTLS_ARIA_C)
#include "mbedtls/aria.h"
#endif
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#endif
@ -69,6 +73,14 @@
#include "mbedtls/ccm.h"
#endif
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#endif
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#endif
@ -101,6 +113,10 @@
#include "mbedtls/gcm.h"
#endif
#if defined(MBEDTLS_HKDF_C)
#include "mbedtls/hkdf.h"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#endif
@ -149,6 +165,14 @@
#include "mbedtls/pkcs5.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#endif
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#endif
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#endif
@ -269,6 +293,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
@ -493,6 +519,12 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) )
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
@ -572,6 +604,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
@ -583,6 +617,17 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH) )
mbedtls_snprintf( buf, buflen, "ARIA - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
@ -653,6 +698,22 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" );
if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" );
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) )
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" );
if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
@ -698,6 +759,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
@ -765,6 +831,20 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_PLATFORM_C)
if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" );
#endif /* MBEDTLS_PLATFORM_C */
#if defined(MBEDTLS_POLY1305_C)
if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" );
if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" );
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );

192
library/hkdf.c Normal file
View file

@ -0,0 +1,192 @@
/*
* HKDF implementation -- RFC 5869
*
* Copyright (C) 2016-2018, 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)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HKDF_C)
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/platform_util.h"
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len )
{
int ret;
unsigned char prk[MBEDTLS_MD_MAX_SIZE];
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
if( ret == 0 )
{
ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
info, info_len, okm, okm_len );
}
mbedtls_platform_zeroize( prk, sizeof( prk ) );
return( ret );
}
int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
const unsigned char *salt, size_t salt_len,
const unsigned char *ikm, size_t ikm_len,
unsigned char *prk )
{
unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
if( salt == NULL )
{
size_t hash_len;
if( salt_len != 0 )
{
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
}
hash_len = mbedtls_md_get_size( md );
if( hash_len == 0 )
{
return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
}
salt = null_salt;
salt_len = hash_len;
}
return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
}
int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
size_t prk_len, const unsigned char *info,
size_t info_len, unsigned char *okm, size_t okm_len )
{
size_t hash_len;
size_t where = 0;
size_t n;
size_t t_len = 0;
size_t i;
int ret = 0;
mbedtls_md_context_t ctx;
unsigned char t[MBEDTLS_MD_MAX_SIZE];
if( okm == NULL )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}
hash_len = mbedtls_md_get_size( md );
if( prk_len < hash_len || hash_len == 0 )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}
if( info == NULL )
{
info = (const unsigned char *) "";
info_len = 0;
}
n = okm_len / hash_len;
if( (okm_len % hash_len) != 0 )
{
n++;
}
/*
* Per RFC 5869 Section 2.3, okm_len must not exceed
* 255 times the hash length
*/
if( n > 255 )
{
return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
}
mbedtls_md_init( &ctx );
if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
{
goto exit;
}
/*
* Compute T = T(1) | T(2) | T(3) | ... | T(N)
* Where T(N) is defined in RFC 5869 Section 2.3
*/
for( i = 1; i <= n; i++ )
{
size_t num_to_copy;
unsigned char c = i & 0xff;
ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
if( ret != 0 )
{
goto exit;
}
ret = mbedtls_md_hmac_update( &ctx, t, t_len );
if( ret != 0 )
{
goto exit;
}
ret = mbedtls_md_hmac_update( &ctx, info, info_len );
if( ret != 0 )
{
goto exit;
}
/* The constant concatenated to the end of each T(n) is a single octet.
* */
ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
if( ret != 0 )
{
goto exit;
}
ret = mbedtls_md_hmac_finish( &ctx, t );
if( ret != 0 )
{
goto exit;
}
num_to_copy = i != n ? hash_len : okm_len - where;
memcpy( okm + where, t, num_to_copy );
where += hash_len;
t_len = hash_len;
}
exit:
mbedtls_md_free( &ctx );
mbedtls_platform_zeroize( t, sizeof( t ) );
return( ret );
}
#endif /* MBEDTLS_HKDF_C */

View file

@ -309,14 +309,6 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx,
}
#endif
static const unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD5 final digest
*/
@ -324,26 +316,48 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] )
{
int ret;
uint32_t last, padn;
uint32_t used;
uint32_t high, low;
unsigned char msglen[8];
/*
* Add padding: 0x80 then 0x00 until 8 bytes remain for the length
*/
used = ctx->total[0] & 0x3F;
ctx->buffer[used++] = 0x80;
if( used <= 56 )
{
/* Enough room for padding + length in current block */
memset( ctx->buffer + used, 0, 56 - used );
}
else
{
/* We'll need an extra block */
memset( ctx->buffer + used, 0, 64 - used );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
memset( ctx->buffer, 0, 56 );
}
/*
* Add message length
*/
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
PUT_UINT32_LE( low, ctx->buffer, 56 );
PUT_UINT32_LE( high, ctx->buffer, 60 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 )
return( ret );
if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 )
return( ret );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
/*
* Output final state
*/
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );

View file

@ -518,7 +518,9 @@ void mbedtls_memory_buffer_alloc_status( void )
heap.alloc_count, heap.free_count );
if( heap.first->next == NULL )
{
mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
}
else
{
mbedtls_fprintf( stderr, "Memory currently allocated:\n" );

View file

@ -19,6 +19,11 @@
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
* be set before config.h, which pulls in glibc's features.h indirectly.
* Harmless on other platforms. */
#define _POSIX_C_SOURCE 200112L
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
@ -28,7 +33,8 @@
#if defined(MBEDTLS_NET_C)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__)
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
!defined(__HAIKU__)
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
#endif
@ -47,11 +53,12 @@
#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
#ifdef _WIN32_WINNT
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
#undef _WIN32_WINNT
#endif
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
#endif
#include <ws2tcpip.h>
#include <winsock2.h>

755
library/nist_kw.c Normal file
View file

@ -0,0 +1,755 @@
/*
* Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes
* only
*
* Copyright (C) 2018, Arm Limited (or its affiliates), 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)
*/
/*
* Definition of Key Wrapping:
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
* RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm"
* RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm"
*
* Note: RFC 3394 defines different methodology for intermediate operations for
* the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h"
#include "mbedtls/platform_util.h"
#include <stdint.h>
#include <string.h>
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#if !defined(MBEDTLS_NIST_KW_ALT)
#define KW_SEMIBLOCK_LENGTH 8
#define MIN_SEMIBLOCKS_COUNT 3
/* constant-time buffer comparison */
static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
{
size_t i;
volatile const unsigned char *A = (volatile const unsigned char *) a;
volatile const unsigned char *B = (volatile const unsigned char *) b;
volatile unsigned char diff = 0;
for( i = 0; i < n; i++ )
{
/* Read volatile data in order before computing diff.
* This avoids IAR compiler warning:
* 'the order of volatile accesses is undefined ..' */
unsigned char x = A[i], y = B[i];
diff |= x ^ y;
}
return( diff );
}
/*! The 64-bit default integrity check value (ICV) for KW mode. */
static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
/*! The 32-bit default integrity check value (ICV) for KWP mode. */
static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
do { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
} while( 0 )
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
do { \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
} while( 0 )
#endif
/*
* Initialize context
*/
void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) );
}
int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits,
const int is_wrap )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher,
keybits,
MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( cipher_info->block_size != 16 )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
/*
* SP 800-38F currently defines AES cipher as the only block cipher allowed:
* "For KW and KWP, the underlying block cipher shall be approved, and the
* block size shall be 128 bits. Currently, the AES block cipher, with key
* lengths of 128, 192, or 256 bits, is the only block cipher that fits
* this profile."
* Currently we don't support other 128 bit block ciphers for key wrapping,
* such as Camellia and Aria.
*/
if( cipher != MBEDTLS_CIPHER_ID_AES )
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
mbedtls_cipher_free( &ctx->cipher_ctx );
if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
is_wrap ? MBEDTLS_ENCRYPT :
MBEDTLS_DECRYPT )
) != 0 )
{
return( ret );
}
return( 0 );
}
/*
* Free context
*/
void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx )
{
mbedtls_cipher_free( &ctx->cipher_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) );
}
/*
* Helper function for Xoring the uint64_t "t" with the encrypted A.
* Defined in NIST SP 800-38F section 6.1
*/
static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t )
{
size_t i = 0;
for( i = 0; i < sizeof( t ); i++ )
{
A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff;
}
}
/*
* KW-AE as defined in SP 800-38F section 6.2
* KWP-AE as defined in SP 800-38F section 6.3
*/
int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t *out_len, size_t out_size )
{
int ret = 0;
size_t semiblocks = 0;
size_t s;
size_t olen, padlen = 0;
uint64_t t = 0;
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
unsigned char *A = output;
*out_len = 0;
/*
* Generate the String to work on
*/
if( mode == MBEDTLS_KW_MODE_KW )
{
if( out_size < in_len + KW_SEMIBLOCK_LENGTH )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
/*
* According to SP 800-38F Table 1, the plaintext length for KW
* must be between 2 to 2^54-1 semiblocks inclusive.
*/
if( in_len < 16 ||
#if SIZE_MAX > 0x1FFFFFFFFFFFFF8
in_len > 0x1FFFFFFFFFFFFF8 ||
#endif
in_len % KW_SEMIBLOCK_LENGTH != 0 )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH );
memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len );
}
else
{
if( in_len % 8 != 0 )
{
padlen = ( 8 - ( in_len % 8 ) );
}
if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
/*
* According to SP 800-38F Table 1, the plaintext length for KWP
* must be between 1 and 2^32-1 octets inclusive.
*/
if( in_len < 1
#if SIZE_MAX > 0xFFFFFFFF
|| in_len > 0xFFFFFFFF
#endif
)
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
KW_SEMIBLOCK_LENGTH / 2 );
memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen );
}
semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1;
s = 6 * ( semiblocks - 1 );
if( mode == MBEDTLS_KW_MODE_KWP
&& in_len <= KW_SEMIBLOCK_LENGTH )
{
memcpy( inbuff, output, 16 );
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
inbuff, 16, output, &olen );
if( ret != 0 )
goto cleanup;
}
else
{
/*
* Do the wrapping function W, as defined in RFC 3394 section 2.2.1
*/
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
{
ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
goto cleanup;
}
/* Calculate intermediate values */
for( t = 1; t <= s; t++ )
{
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH );
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
inbuff, 16, outbuff, &olen );
if( ret != 0 )
goto cleanup;
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
calc_a_xor_t( A, t );
memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
R2 += KW_SEMIBLOCK_LENGTH;
if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) )
R2 = output + KW_SEMIBLOCK_LENGTH;
}
}
*out_len = semiblocks * KW_SEMIBLOCK_LENGTH;
cleanup:
if( ret != 0)
{
memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH );
}
mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 );
mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 );
mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
return( ret );
}
/*
* W-1 function as defined in RFC 3394 section 2.2.2
* This function assumes the following:
* 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH.
* 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH.
* 3. Minimal number of semiblocks is 3.
* 4. A is a buffer to hold the first semiblock of the input buffer.
*/
static int unwrap( mbedtls_nist_kw_context *ctx,
const unsigned char *input, size_t semiblocks,
unsigned char A[KW_SEMIBLOCK_LENGTH],
unsigned char *output, size_t* out_len )
{
int ret = 0;
const size_t s = 6 * ( semiblocks - 1 );
size_t olen;
uint64_t t = 0;
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
*out_len = 0;
if( semiblocks < MIN_SEMIBLOCKS_COUNT )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
memcpy( A, input, KW_SEMIBLOCK_LENGTH );
memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
/* Calculate intermediate values */
for( t = s; t >= 1; t-- )
{
calc_a_xor_t( A, t );
memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH );
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
inbuff, 16, outbuff, &olen );
if( ret != 0 )
goto cleanup;
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
/* Set R as LSB64 of outbuff */
memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
if( R == output )
R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
else
R -= KW_SEMIBLOCK_LENGTH;
}
*out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH;
cleanup:
if( ret != 0)
memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) );
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
return( ret );
}
/*
* KW-AD as defined in SP 800-38F section 6.2
* KWP-AD as defined in SP 800-38F section 6.3
*/
int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
mbedtls_nist_kw_mode_t mode,
const unsigned char *input, size_t in_len,
unsigned char *output, size_t *out_len, size_t out_size )
{
int ret = 0;
size_t i, olen;
unsigned char A[KW_SEMIBLOCK_LENGTH];
unsigned char diff, bad_padding = 0;
*out_len = 0;
if( out_size < in_len - KW_SEMIBLOCK_LENGTH )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
if( mode == MBEDTLS_KW_MODE_KW )
{
/*
* According to SP 800-38F Table 1, the ciphertext length for KW
* must be between 3 to 2^54 semiblocks inclusive.
*/
if( in_len < 24 ||
#if SIZE_MAX > 0x200000000000000
in_len > 0x200000000000000 ||
#endif
in_len % KW_SEMIBLOCK_LENGTH != 0 )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
A, output, out_len );
if( ret != 0 )
goto cleanup;
/* Check ICV in "constant-time" */
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
if( diff != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
goto cleanup;
}
}
else if( mode == MBEDTLS_KW_MODE_KWP )
{
size_t padlen = 0;
uint32_t Plen;
/*
* According to SP 800-38F Table 1, the ciphertext length for KWP
* must be between 2 to 2^29 semiblocks inclusive.
*/
if( in_len < KW_SEMIBLOCK_LENGTH * 2 ||
#if SIZE_MAX > 0x100000000
in_len > 0x100000000 ||
#endif
in_len % KW_SEMIBLOCK_LENGTH != 0 )
{
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
if( in_len == KW_SEMIBLOCK_LENGTH * 2 )
{
unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
ret = mbedtls_cipher_update( &ctx->cipher_ctx,
input, 16, outbuff, &olen );
if( ret != 0 )
goto cleanup;
memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
*out_len = KW_SEMIBLOCK_LENGTH;
}
else
{
/* in_len >= KW_SEMIBLOCK_LENGTH * 3 */
ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
A, output, out_len );
if( ret != 0 )
goto cleanup;
}
/* Check ICV in "constant-time" */
diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
if( diff != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
/*
* Plen is the length of the plaintext, when the input is valid.
* If Plen is larger than the plaintext and padding, padlen will be
* larger than 8, because of the type wrap around.
*/
padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
if ( padlen > 7 )
{
padlen &= 7;
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
/* Check padding in "constant-time" */
for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ )
{
if( i >= KW_SEMIBLOCK_LENGTH - padlen )
diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
else
bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
}
if( diff != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
if( ret != 0 )
{
goto cleanup;
}
memset( output + Plen, 0, padlen );
*out_len = Plen;
}
else
{
ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
goto cleanup;
}
cleanup:
if( ret != 0 )
{
memset( output, 0, *out_len );
*out_len = 0;
}
mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) );
mbedtls_platform_zeroize( &diff, sizeof( diff ) );
mbedtls_platform_zeroize( A, sizeof( A ) );
mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen );
return( ret );
}
#endif /* !MBEDTLS_NIST_KW_ALT */
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#define KW_TESTS 3
/*
* Test vectors taken from NIST
* https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW
*/
static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 };
static const unsigned char kw_key[KW_TESTS][32] = {
{ 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2,
0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 },
{ 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b,
0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d,
0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 },
{ 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25,
0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33,
0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d,
0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 }
};
static const unsigned char kw_msg[KW_TESTS][40] = {
{ 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea,
0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f },
{ 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb,
0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d,
0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45,
0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d,
0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c },
{ 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7,
0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8,
0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 }
};
static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 };
static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 };
static const unsigned char kw_res[KW_TESTS][48] = {
{ 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d,
0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3,
0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb },
{ 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91,
0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec,
0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d,
0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8,
0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19,
0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d },
{ 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d,
0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87,
0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9,
0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 }
};
static const unsigned char kwp_key[KW_TESTS][32] = {
{ 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a,
0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 },
{ 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98,
0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7,
0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 },
{ 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5,
0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f,
0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae,
0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a }
};
static const unsigned char kwp_msg[KW_TESTS][31] = {
{ 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8,
0x96 },
{ 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb,
0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19,
0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66,
0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f },
{ 0xd1 }
};
static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 };
static const unsigned char kwp_res[KW_TESTS][48] = {
{ 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e,
0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7,
0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 },
{ 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13,
0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88,
0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63,
0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90,
0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 },
{ 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd,
0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 }
};
static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 };
int mbedtls_nist_kw_self_test( int verbose )
{
mbedtls_nist_kw_context ctx;
unsigned char out[48];
size_t olen;
int i;
int ret = 0;
mbedtls_nist_kw_init( &ctx );
for( i = 0; i < KW_TESTS; i++ )
{
if( verbose != 0 )
mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 );
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 1 );
if( ret != 0 )
{
if( verbose != 0 )
mbedtls_printf( " KW: setup failed " );
goto end;
}
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i],
kw_msg_len[i], out, &olen, sizeof( out ) );
if( ret != 0 || kw_out_len[i] != olen ||
memcmp( out, kw_res[i], kw_out_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed. ");
ret = 1;
goto end;
}
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
kw_key[i], key_len[i] * 8, 0 ) )
!= 0 )
{
if( verbose != 0 )
mbedtls_printf( " KW: setup failed ");
goto end;
}
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW,
out, olen, out, &olen, sizeof( out ) );
if( ret != 0 || olen != kw_msg_len[i] ||
memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto end;
}
if( verbose != 0 )
mbedtls_printf( " passed\n" );
}
for( i = 0; i < KW_TESTS; i++ )
{
olen = sizeof( out );
if( verbose != 0 )
mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 );
ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i],
key_len[i] * 8, 1 );
if( ret != 0 )
{
if( verbose != 0 )
mbedtls_printf( " KWP: setup failed " );
goto end;
}
ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i],
kwp_msg_len[i], out, &olen, sizeof( out ) );
if( ret != 0 || kwp_out_len[i] != olen ||
memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed. ");
ret = 1;
goto end;
}
if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
kwp_key[i], key_len[i] * 8, 0 ) )
!= 0 )
{
if( verbose != 0 )
mbedtls_printf( " KWP: setup failed ");
goto end;
}
ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out,
olen, out, &olen, sizeof( out ) );
if( ret != 0 || olen != kwp_msg_len[i] ||
memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed. ");
ret = 1;
goto end;
}
if( verbose != 0 )
mbedtls_printf( " passed\n" );
}
end:
mbedtls_nist_kw_free( &ctx );
if( verbose != 0 )
mbedtls_printf( "\n" );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#endif /* MBEDTLS_NIST_KW_C */

View file

@ -69,6 +69,34 @@ void mbedtls_pk_free( mbedtls_pk_context *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
}
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Initialize a restart context
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
{
ctx->pk_info = NULL;
ctx->rs_ctx = NULL;
}
/*
* Free the components of a restart context
*/
void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL ||
ctx->pk_info->rs_free_func == NULL )
{
return;
}
ctx->pk_info->rs_free_func( ctx->rs_ctx );
ctx->pk_info = NULL;
ctx->rs_ctx = NULL;
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/*
* Get pk_info structure from type
*/
@ -171,6 +199,73 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len
return( 0 );
}
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/*
* Helper to set up a restart context if needed
*/
static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
const mbedtls_pk_info_t *info )
{
/* Don't do anything if already set up or invalid */
if( ctx == NULL || ctx->pk_info != NULL )
return( 0 );
/* Should never happen when we're called */
if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
ctx->pk_info = info;
return( 0 );
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
/*
* Verify a signature (restartable)
*/
int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
mbedtls_pk_restart_ctx *rs_ctx )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* optimization: use non-restartable version if restart disabled */
if( rs_ctx != NULL &&
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->verify_rs_func != NULL )
{
int ret;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_pk_restart_free( rs_ctx );
return( ret );
}
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
(void) rs_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
if( ctx->pk_info->verify_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len ) );
}
/*
* Verify a signature
*/
@ -178,15 +273,8 @@ int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->verify_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len ) );
return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
sig, sig_len, NULL ) );
}
/*
@ -247,6 +335,50 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}
/*
* Make a signature (restartable)
*/
int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* optimization: use non-restartable version if restart disabled */
if( rs_ctx != NULL &&
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->sign_rs_func != NULL )
{
int ret;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_pk_restart_free( rs_ctx );
return( ret );
}
#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
(void) rs_ctx;
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
if( ctx->pk_info->sign_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng ) );
}
/*
* Make a signature
*/
@ -255,15 +387,8 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->sign_func == NULL )
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng ) );
return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng, NULL ) );
}
/*

View file

@ -190,11 +190,19 @@ const mbedtls_pk_info_t mbedtls_rsa_info = {
rsa_can_do,
rsa_verify_wrap,
rsa_sign_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_decrypt_wrap,
rsa_encrypt_wrap,
rsa_check_pair_wrap,
rsa_alloc_wrap,
rsa_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_debug,
};
#endif /* MBEDTLS_RSA_C */
@ -262,6 +270,110 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
return( ret );
}
#if defined(MBEDTLS_ECP_RESTARTABLE)
/* Forward declarations */
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx );
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx );
/*
* Restart context for ECDSA operations with ECKEY context
*
* We need to store an actual ECDSA context, as we need to pass the same to
* the underlying ecdsa function, so we can't create it on the fly every time.
*/
typedef struct
{
mbedtls_ecdsa_restart_ctx ecdsa_rs;
mbedtls_ecdsa_context ecdsa_ctx;
} eckey_restart_ctx;
static void *eckey_rs_alloc( void )
{
eckey_restart_ctx *rs_ctx;
void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
if( ctx != NULL )
{
rs_ctx = ctx;
mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
}
return( ctx );
}
static void eckey_rs_free( void *ctx )
{
eckey_restart_ctx *rs_ctx;
if( ctx == NULL)
return;
rs_ctx = ctx;
mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
mbedtls_free( ctx );
}
static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
int ret;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
if( rs == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* set up our own sub-context if needed (that is, on first run) */
if( rs->ecdsa_ctx.grp.pbits == 0 )
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
md_alg, hash, hash_len,
sig, sig_len, &rs->ecdsa_rs ) );
cleanup:
return( ret );
}
static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
int ret;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
if( rs == NULL )
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* set up our own sub-context if needed (that is, on first run) */
if( rs->ecdsa_ctx.grp.pbits == 0 )
MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
hash, hash_len, sig, sig_len,
f_rng, p_rng, &rs->ecdsa_rs ) );
cleanup:
return( ret );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDSA_C */
static int eckey_check_pair( const void *pub, const void *prv )
@ -301,15 +413,23 @@ const mbedtls_pk_info_t mbedtls_eckey_info = {
#if defined(MBEDTLS_ECDSA_C)
eckey_verify_wrap,
eckey_sign_wrap,
#else
NULL,
NULL,
#if defined(MBEDTLS_ECP_RESTARTABLE)
eckey_verify_rs_wrap,
eckey_sign_rs_wrap,
#endif
#else /* MBEDTLS_ECDSA_C */
NULL,
NULL,
#endif /* MBEDTLS_ECDSA_C */
NULL,
NULL,
eckey_check_pair,
eckey_alloc_wrap,
eckey_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
eckey_rs_alloc,
eckey_rs_free,
#endif
eckey_debug,
};
@ -329,11 +449,19 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = {
eckeydh_can_do,
NULL,
NULL,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
NULL,
NULL,
eckey_check_pair,
eckey_alloc_wrap, /* Same underlying key structure */
eckey_free_wrap, /* Same underlying key structure */
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
eckey_debug, /* Same underlying key structure */
};
#endif /* MBEDTLS_ECP_C */
@ -369,6 +497,40 @@ static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
}
#if defined(MBEDTLS_ECP_RESTARTABLE)
static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
int ret;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature_restartable(
(mbedtls_ecdsa_context *) ctx,
hash, hash_len, sig, sig_len,
(mbedtls_ecdsa_restart_ctx *) rs_ctx );
if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
return( ret );
}
static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
return( mbedtls_ecdsa_write_signature_restartable(
(mbedtls_ecdsa_context *) ctx,
md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
(mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
static void *ecdsa_alloc_wrap( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
@ -385,6 +547,24 @@ static void ecdsa_free_wrap( void *ctx )
mbedtls_free( ctx );
}
#if defined(MBEDTLS_ECP_RESTARTABLE)
static void *ecdsa_rs_alloc( void )
{
void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
if( ctx != NULL )
mbedtls_ecdsa_restart_init( ctx );
return( ctx );
}
static void ecdsa_rs_free( void *ctx )
{
mbedtls_ecdsa_restart_free( ctx );
mbedtls_free( ctx );
}
#endif /* MBEDTLS_ECP_RESTARTABLE */
const mbedtls_pk_info_t mbedtls_ecdsa_info = {
MBEDTLS_PK_ECDSA,
"ECDSA",
@ -392,11 +572,19 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = {
ecdsa_can_do,
ecdsa_verify_wrap,
ecdsa_sign_wrap,
#if defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_verify_rs_wrap,
ecdsa_sign_rs_wrap,
#endif
NULL,
NULL,
eckey_check_pair, /* Compatible key structures */
ecdsa_alloc_wrap,
ecdsa_free_wrap,
#if defined(MBEDTLS_ECP_RESTARTABLE)
ecdsa_rs_alloc,
ecdsa_rs_free,
#endif
eckey_debug, /* Compatible key structures */
};
#endif /* MBEDTLS_ECDSA_C */
@ -506,6 +694,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
rsa_alt_can_do,
NULL,
rsa_alt_sign_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
rsa_alt_decrypt_wrap,
NULL,
#if defined(MBEDTLS_RSA_C)
@ -515,6 +707,10 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
#endif
rsa_alt_alloc_wrap,
rsa_alt_free_wrap,
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
NULL,
NULL,
#endif
NULL,
};

View file

@ -249,8 +249,10 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
memset( counter, 0, 4 );
counter[3] = 1;
#if UINT_MAX > 0xFFFFFFFF
if( iteration_count > 0xFFFFFFFF )
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
#endif
while( key_length )
{

View file

@ -1261,7 +1261,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( ret );
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
#else
((void) ret);
((void) pwd);
((void) pwdlen);
#endif /* MBEDTLS_PEM_PARSE_C */

View file

@ -51,14 +51,24 @@ static void platform_free_uninit( void *ptr )
#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit
#endif /* !MBEDTLS_PLATFORM_STD_FREE */
void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
void * mbedtls_calloc( size_t nmemb, size_t size )
{
return (*mbedtls_calloc_func)( nmemb, size );
}
void mbedtls_free( void * ptr )
{
(*mbedtls_free_func)( ptr );
}
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) )
{
mbedtls_calloc = calloc_func;
mbedtls_free = free_func;
mbedtls_calloc_func = calloc_func;
mbedtls_free_func = free_func;
return( 0 );
}
#endif /* MBEDTLS_PLATFORM_MEMORY */

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