Merge mbed-crypto into mbedtls: the merge commit

Merge `unremove-non-crypto` into `mbedtls/development`. The branch
`unremove-non-crypto` was obtained by starting from `mbed-crypto/development`,
then reverting many commits that removed X.509 and TLS functionality when Mbed
Crypto forked from Mbed TLS (the “unremoval”), then make a few tweaks to
facilitate the merge.

The unremoval step restored old versions of some tls files. If a file doesn't
exist in mbed-crypto, check out the mbedtls version, regardless of what
happened during the unremoval of tls files in the crypto tree. Also
unconditionally take the mbedtls version of a few files where the
modifications are completely project-specific and are not relevant in
mbed-crypto:

* `.github/issue_template.md`: completely different. We may want to reconcile
  them independently as a follow-up.
* `.travis.yml`: would only be reverted to an earlier tls version.
* `README.md`: completely different. We may want to reconcile them
  independently as a follow-up.
* `doxygen/input/doc_mainpage.h`: the changes in crypto were minimal and not
  relevant except as a stopgap as mbed-crypto did not have its own product
  versioning in the Doxygen documentation.
* `tests/.jenkins/Jenkinsfile`: completely different.
* `tests/data_files/Makefile`: there were no changes in mbed-crypto,
  but the unremoval step restored an old version.

Shell script for everything to do after the merge apart from the conflict
resolution:
```
tls_files=($(comm -23 <(git ls-tree -r --name-only HEAD) <(git ls-tree -r --name-only $(git merge-base upstream-crypto/development MERGE_HEAD))))
tls_files+=($tls_files .github/issue_template.md .travis.yml README.md doxygen/input/doc_mainpage.h tests/.jenkins/Jenkinsfile tests/data_files/Makefile)
git checkout --theirs HEAD -- $tls_files
git add -- $tls_files
```

Resolve the remaining conflicts:

* `library/CMakeLists.txt`:
    * Keep the TLS definition of `src_crypto`
    * `USE_SHARED_MBEDTLS_LIBRARY`: keep all three libraries, with both
      `include` and `crypto/include` in `target_include_directories`, all with
      version `2.21.0`.
* `programs/Makefile`:
    * Reconcile the APPS lists (add/add from a differently-formatted common
      ancestor): insert the `psa/*` from crypto into the tls list.
    * Keep the `fuzz` target defined only in tls version.
    * Keep the recipe (only in tls version) cleaning `ssl_pthread_server`
      stuff for the `clean` target.
* `scripts/config.py`:
    * `include_in_full`: add/add conflict. Keep both.
* `tests/scripts/all.sh`:
    * `component_test_no_use_psa_crypto_full_cmake_asan`: partially old
      version in crypto. Take the tls version.
    * `component_test_malloc_0_null` and more: take
      `component_test_malloc_0_null` from crypto (with `config.py` rather than
      `config.pl`, and with `$ASAN_FLAGS` rather than an explicit list), but
      add the call to `ssl-opt.sh` from tls. Take the other components from
      crypto.

With this commit, building and running the unit tests with both `make ` and
`cmake` work in the default configuration on Linux. Other platforms, build
systems and configurations are likely not to work, and there is some
regression in test coverage.

There is some loss of functionality because the unremoval step restored older
versions of tls content. This commit contains the latest tls version of
tls-only files, but some changes from the tls side in files that existed on
both sides have regressed. Most problematic changes are hunks that remove some
tls-specific feature and contain either a C preprocessor symbol identifying a
tls-specific module or option, or the name of a tls-specific file. Hunks
that remove a tls-specific preprocessor symbol can be identified with the
regular expression `^-.*MBEDTLS_(ERR_)?(PKCS11|X509|NET|SSL)_`.

Subsequent commits will revert a few parts of the patch from this merge commit
in order to restore the tls functionality that it removes, ensure that the
test coverage includes what was covered in either branch, and fix test
failures.
This commit is contained in:
Gilles Peskine 2020-03-19 15:38:54 +01:00
commit b99bd39b4e
397 changed files with 168444 additions and 995 deletions

1
3rdparty/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/Makefile

11
3rdparty/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,11 @@
list (APPEND thirdparty_src)
list (APPEND thirdparty_lib)
list (APPEND thirdparty_inc)
list (APPEND thirdparty_def)
add_subdirectory(everest)
set(thirdparty_src ${thirdparty_src} PARENT_SCOPE)
set(thirdparty_lib ${thirdparty_lib} PARENT_SCOPE)
set(thirdparty_inc ${thirdparty_inc} PARENT_SCOPE)
set(thirdparty_def ${thirdparty_def} PARENT_SCOPE)

5
3rdparty/Makefile.inc vendored Normal file
View File

@ -0,0 +1,5 @@
ifeq ($(INCLUDING_FROM_MBEDTLS), 1)
include ../crypto/3rdparty/everest/Makefile.inc
else
include ../3rdparty/everest/Makefile.inc
endif

2
3rdparty/everest/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
Makefile

31
3rdparty/everest/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,31 @@
list (APPEND everest_src)
list (APPEND everest_inc)
list (APPEND everest_def)
set(everest_src
${CMAKE_CURRENT_SOURCE_DIR}/library/everest.c
${CMAKE_CURRENT_SOURCE_DIR}/library/x25519.c
${CMAKE_CURRENT_SOURCE_DIR}/library/Hacl_Curve25519_joined.c
)
list(APPEND everest_inc ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include/everest ${CMAKE_CURRENT_SOURCE_DIR}/include/everest/kremlib)
execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/config.py -f ${CMAKE_CURRENT_SOURCE_DIR}/../../include/mbedtls/config.h get MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED RESULT_VARIABLE result)
if(${result} EQUAL 0)
if(INSTALL_MBEDTLS_HEADERS)
install(DIRECTORY include/everest
DESTINATION include
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
FILES_MATCHING PATTERN "*.h")
endif(INSTALL_MBEDTLS_HEADERS)
endif()
set(thirdparty_src ${thirdparty_src} ${everest_src} PARENT_SCOPE)
set(thirdparty_inc ${thirdparty_inc} ${everest_inc} PARENT_SCOPE)
set(thirdparty_def ${thirdparty_def} ${everest_def} PARENT_SCOPE)

6
3rdparty/everest/Makefile.inc vendored Normal file
View File

@ -0,0 +1,6 @@
THIRDPARTY_INCLUDES+=-I../3rdparty/everest/include -I../3rdparty/everest/include/everest -I../3rdparty/everest/include/everest/kremlib
THIRDPARTY_CRYPTO_OBJECTS+= \
../3rdparty/everest/library/everest.o \
../3rdparty/everest/library/x25519.o \
../3rdparty/everest/library/Hacl_Curve25519_joined.o

5
3rdparty/everest/README.md vendored Normal file
View File

@ -0,0 +1,5 @@
The files in this directory stem from [Project Everest](https://project-everest.github.io/) and are distributed under the Apache 2.0 license.
This is a formally verified implementation of Curve25519-based handshakes. The C code is automatically derived from the (verified) [original implementation](https://github.com/project-everest/hacl-star/tree/master/code/curve25519) in the [F* language](https://github.com/fstarlang/fstar) by [KreMLin](https://github.com/fstarlang/kremlin). In addition to the improved safety and security of the implementation, it is also significantly faster than the default implementation of Curve25519 in mbedTLS.
The caveat is that not all platforms are supported, although the version in `everest/library/legacy` should work on most systems. The main issue is that some platforms do not provide a 128-bit integer type and KreMLin therefore has to use additional (also verified) code to simulate them, resulting in less of a performance gain overall. Explictly supported platforms are currently `x86` and `x86_64` using gcc or clang, and Visual C (2010 and later).

View File

@ -0,0 +1,21 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fbuiltin-uint128 -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#ifndef __Hacl_Curve25519_H
#define __Hacl_Curve25519_H
#include "kremlib.h"
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint);
#define __Hacl_Curve25519_H_DEFINED
#endif

View File

@ -0,0 +1,234 @@
/*
* Interface to code from Project Everest
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org).
*/
#ifndef MBEDTLS_EVEREST_H
#define MBEDTLS_EVEREST_H
#include "everest/x25519.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Defines the source of the imported EC key.
*/
typedef enum
{
MBEDTLS_EVEREST_ECDH_OURS, /**< Our key. */
MBEDTLS_EVEREST_ECDH_THEIRS, /**< The key of the peer. */
} mbedtls_everest_ecdh_side;
typedef struct {
mbedtls_x25519_context ctx;
} mbedtls_ecdh_context_everest;
/**
* \brief This function sets up the ECDH context with the information
* given.
*
* This function should be called after mbedtls_ecdh_init() but
* before mbedtls_ecdh_make_params(). There is no need to call
* this function before mbedtls_ecdh_read_params().
*
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context to set up.
* \param grp_id The group id of the group to set up the context for.
*
* \return \c 0 on success.
*/
int mbedtls_everest_setup( mbedtls_ecdh_context_everest *ctx, int grp_id );
/**
* \brief This function frees a context.
*
* \param ctx The context to free.
*/
void mbedtls_everest_free( mbedtls_ecdh_context_everest *ctx );
/**
* \brief This function generates a public key and a TLS
* ServerKeyExchange payload.
*
* This is the second function used by a TLS server for ECDHE
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
*
* \note This function assumes that the ECP group (grp) of the
* \p ctx context has already been properly set,
* for example, using mbedtls_ecp_group_load().
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param olen The number of characters written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_everest_make_params( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng );
/**
* \brief This function parses and processes a TLS ServerKeyExhange
* payload.
*
* This is the first function used by a TLS client for ECDHE
* ciphersuites.
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param buf The pointer to the start of the input buffer.
* \param end The address for one Byte past the end of the buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
const unsigned char **buf, const unsigned char *end );
/**
* \brief This function parses and processes a TLS ServerKeyExhange
* payload.
*
* This is the first function used by a TLS client for ECDHE
* ciphersuites.
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param buf The pointer to the start of the input buffer.
* \param end The address for one Byte past the end of the buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
const unsigned char **buf, const unsigned char *end );
/**
* \brief This function sets up an ECDH context from an EC key.
*
* It is used by clients and servers in place of the
* ServerKeyEchange for static ECDH, and imports ECDH
* parameters from the EC key information of a certificate.
*
* \see ecp.h
*
* \param ctx The ECDH context to set up.
* \param key The EC key to use.
* \param side Defines the source of the key: 1: Our key, or
* 0: The key of the peer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_everest_get_params( mbedtls_ecdh_context_everest *ctx, const mbedtls_ecp_keypair *key,
mbedtls_everest_ecdh_side side );
/**
* \brief This function generates a public key and a TLS
* ClientKeyExchange payload.
*
* This is the second function used by a TLS client for ECDH(E)
* ciphersuites.
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The size of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_everest_make_public( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng );
/**
* \brief This function parses and processes a TLS ClientKeyExchange
* payload.
*
* This is the third function used by a TLS server for ECDH(E)
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
* mbedtls_ecdh_make_params().)
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param buf The start of the input buffer.
* \param blen The length of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_everest_read_public( mbedtls_ecdh_context_everest *ctx,
const unsigned char *buf, size_t blen );
/**
* \brief This function derives and exports the shared secret.
*
* This is the last function used by both TLS client
* and servers.
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \see ecp.h
*
* \param ctx The ECDH context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_everest_calc_secret( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_EVEREST_H */

View File

@ -0,0 +1,29 @@
/*
* Copyright 2016-2018 INRIA and Microsoft Corporation
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org) and
* originated from Project Everest (https://project-everest.github.io/)
*/
#ifndef __KREMLIB_H
#define __KREMLIB_H
#include "kremlin/internal/target.h"
#include "kremlin/internal/types.h"
#include "kremlin/c_endianness.h"
#endif /* __KREMLIB_H */

View File

@ -0,0 +1,124 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/uint128 -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/types.h" -bundle FStar.UInt128=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#ifndef __FStar_UInt128_H
#define __FStar_UInt128_H
#include <inttypes.h>
#include <stdbool.h>
#include "kremlin/internal/types.h"
uint64_t FStar_UInt128___proj__Mkuint128__item__low(FStar_UInt128_uint128 projectee);
uint64_t FStar_UInt128___proj__Mkuint128__item__high(FStar_UInt128_uint128 projectee);
typedef FStar_UInt128_uint128 FStar_UInt128_t;
FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128
FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128
FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a);
FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s);
FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s);
bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b);
FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a);
uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Question_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Question_Hat)(
FStar_UInt128_uint128 x0,
FStar_UInt128_uint128 x1
);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Amp_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Hat_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Bar_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Less_Less_Hat)(FStar_UInt128_uint128 x0, uint32_t x1);
extern FStar_UInt128_uint128
(*FStar_UInt128_op_Greater_Greater_Hat)(FStar_UInt128_uint128 x0, uint32_t x1);
extern bool (*FStar_UInt128_op_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern bool
(*FStar_UInt128_op_Greater_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern bool (*FStar_UInt128_op_Less_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern bool
(*FStar_UInt128_op_Greater_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern bool
(*FStar_UInt128_op_Less_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y);
FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y);
#define __FStar_UInt128_H_DEFINED
#endif

View File

@ -0,0 +1,280 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/minimal -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/compat.h" -add-include "kremlin/internal/types.h" -bundle FStar.UInt64+FStar.UInt32+FStar.UInt16+FStar.UInt8=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#ifndef __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H
#define __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H
#include <inttypes.h>
#include <stdbool.h>
#include "kremlin/internal/compat.h"
#include "kremlin/internal/types.h"
extern Prims_int FStar_UInt64_n;
extern Prims_int FStar_UInt64_v(uint64_t x0);
extern uint64_t FStar_UInt64_uint_to_t(Prims_int x0);
extern uint64_t FStar_UInt64_add(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_add_underspec(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_add_mod(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_sub(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_sub_underspec(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_sub_mod(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_mul(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_mul_underspec(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_mul_mod(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_mul_div(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_div(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_rem(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_logand(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_logxor(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_logor(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_lognot(uint64_t x0);
extern uint64_t FStar_UInt64_shift_right(uint64_t x0, uint32_t x1);
extern uint64_t FStar_UInt64_shift_left(uint64_t x0, uint32_t x1);
extern bool FStar_UInt64_eq(uint64_t x0, uint64_t x1);
extern bool FStar_UInt64_gt(uint64_t x0, uint64_t x1);
extern bool FStar_UInt64_gte(uint64_t x0, uint64_t x1);
extern bool FStar_UInt64_lt(uint64_t x0, uint64_t x1);
extern bool FStar_UInt64_lte(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_minus(uint64_t x0);
extern uint32_t FStar_UInt64_n_minus_one;
uint64_t FStar_UInt64_eq_mask(uint64_t a, uint64_t b);
uint64_t FStar_UInt64_gte_mask(uint64_t a, uint64_t b);
extern Prims_string FStar_UInt64_to_string(uint64_t x0);
extern uint64_t FStar_UInt64_of_string(Prims_string x0);
extern Prims_int FStar_UInt32_n;
extern Prims_int FStar_UInt32_v(uint32_t x0);
extern uint32_t FStar_UInt32_uint_to_t(Prims_int x0);
extern uint32_t FStar_UInt32_add(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_add_underspec(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_add_mod(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_sub(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_sub_underspec(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_sub_mod(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_mul(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_mul_underspec(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_mul_mod(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_mul_div(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_div(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_rem(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_logand(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_logxor(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_logor(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_lognot(uint32_t x0);
extern uint32_t FStar_UInt32_shift_right(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_shift_left(uint32_t x0, uint32_t x1);
extern bool FStar_UInt32_eq(uint32_t x0, uint32_t x1);
extern bool FStar_UInt32_gt(uint32_t x0, uint32_t x1);
extern bool FStar_UInt32_gte(uint32_t x0, uint32_t x1);
extern bool FStar_UInt32_lt(uint32_t x0, uint32_t x1);
extern bool FStar_UInt32_lte(uint32_t x0, uint32_t x1);
extern uint32_t FStar_UInt32_minus(uint32_t x0);
extern uint32_t FStar_UInt32_n_minus_one;
uint32_t FStar_UInt32_eq_mask(uint32_t a, uint32_t b);
uint32_t FStar_UInt32_gte_mask(uint32_t a, uint32_t b);
extern Prims_string FStar_UInt32_to_string(uint32_t x0);
extern uint32_t FStar_UInt32_of_string(Prims_string x0);
extern Prims_int FStar_UInt16_n;
extern Prims_int FStar_UInt16_v(uint16_t x0);
extern uint16_t FStar_UInt16_uint_to_t(Prims_int x0);
extern uint16_t FStar_UInt16_add(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_add_underspec(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_add_mod(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_sub(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_sub_underspec(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_sub_mod(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_mul(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_mul_underspec(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_mul_mod(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_mul_div(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_div(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_rem(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_logand(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_logxor(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_logor(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_lognot(uint16_t x0);
extern uint16_t FStar_UInt16_shift_right(uint16_t x0, uint32_t x1);
extern uint16_t FStar_UInt16_shift_left(uint16_t x0, uint32_t x1);
extern bool FStar_UInt16_eq(uint16_t x0, uint16_t x1);
extern bool FStar_UInt16_gt(uint16_t x0, uint16_t x1);
extern bool FStar_UInt16_gte(uint16_t x0, uint16_t x1);
extern bool FStar_UInt16_lt(uint16_t x0, uint16_t x1);
extern bool FStar_UInt16_lte(uint16_t x0, uint16_t x1);
extern uint16_t FStar_UInt16_minus(uint16_t x0);
extern uint32_t FStar_UInt16_n_minus_one;
uint16_t FStar_UInt16_eq_mask(uint16_t a, uint16_t b);
uint16_t FStar_UInt16_gte_mask(uint16_t a, uint16_t b);
extern Prims_string FStar_UInt16_to_string(uint16_t x0);
extern uint16_t FStar_UInt16_of_string(Prims_string x0);
extern Prims_int FStar_UInt8_n;
extern Prims_int FStar_UInt8_v(uint8_t x0);
extern uint8_t FStar_UInt8_uint_to_t(Prims_int x0);
extern uint8_t FStar_UInt8_add(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_add_underspec(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_add_mod(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_sub(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_sub_underspec(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_sub_mod(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_mul(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_mul_underspec(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_mul_mod(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_mul_div(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_div(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_rem(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_logand(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_logxor(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_logor(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_lognot(uint8_t x0);
extern uint8_t FStar_UInt8_shift_right(uint8_t x0, uint32_t x1);
extern uint8_t FStar_UInt8_shift_left(uint8_t x0, uint32_t x1);
extern bool FStar_UInt8_eq(uint8_t x0, uint8_t x1);
extern bool FStar_UInt8_gt(uint8_t x0, uint8_t x1);
extern bool FStar_UInt8_gte(uint8_t x0, uint8_t x1);
extern bool FStar_UInt8_lt(uint8_t x0, uint8_t x1);
extern bool FStar_UInt8_lte(uint8_t x0, uint8_t x1);
extern uint8_t FStar_UInt8_minus(uint8_t x0);
extern uint32_t FStar_UInt8_n_minus_one;
uint8_t FStar_UInt8_eq_mask(uint8_t a, uint8_t b);
uint8_t FStar_UInt8_gte_mask(uint8_t a, uint8_t b);
extern Prims_string FStar_UInt8_to_string(uint8_t x0);
extern uint8_t FStar_UInt8_of_string(Prims_string x0);
typedef uint8_t FStar_UInt8_byte;
#define __FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8_H_DEFINED
#endif

View File

@ -0,0 +1,204 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef __KREMLIN_ENDIAN_H
#define __KREMLIN_ENDIAN_H
#include <string.h>
#include <inttypes.h>
/******************************************************************************/
/* Implementing C.fst (part 2: endian-ness macros) */
/******************************************************************************/
/* ... for Linux */
#if defined(__linux__) || defined(__CYGWIN__)
# include <endian.h>
/* ... for OSX */
#elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define htole64(x) OSSwapHostToLittleInt64(x)
# define le64toh(x) OSSwapLittleToHostInt64(x)
# define htobe64(x) OSSwapHostToBigInt64(x)
# define be64toh(x) OSSwapBigToHostInt64(x)
# define htole16(x) OSSwapHostToLittleInt16(x)
# define le16toh(x) OSSwapLittleToHostInt16(x)
# define htobe16(x) OSSwapHostToBigInt16(x)
# define be16toh(x) OSSwapBigToHostInt16(x)
# define htole32(x) OSSwapHostToLittleInt32(x)
# define le32toh(x) OSSwapLittleToHostInt32(x)
# define htobe32(x) OSSwapHostToBigInt32(x)
# define be32toh(x) OSSwapBigToHostInt32(x)
/* ... for Solaris */
#elif defined(__sun__)
# include <sys/byteorder.h>
# define htole64(x) LE_64(x)
# define le64toh(x) LE_64(x)
# define htobe64(x) BE_64(x)
# define be64toh(x) BE_64(x)
# define htole16(x) LE_16(x)
# define le16toh(x) LE_16(x)
# define htobe16(x) BE_16(x)
# define be16toh(x) BE_16(x)
# define htole32(x) LE_32(x)
# define le32toh(x) LE_32(x)
# define htobe32(x) BE_32(x)
# define be32toh(x) BE_32(x)
/* ... for the BSDs */
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
# include <sys/endian.h>
#elif defined(__OpenBSD__)
# include <endian.h>
/* ... for Windows (MSVC)... not targeting XBOX 360! */
#elif defined(_MSC_VER)
# include <stdlib.h>
# define htobe16(x) _byteswap_ushort(x)
# define htole16(x) (x)
# define be16toh(x) _byteswap_ushort(x)
# define le16toh(x) (x)
# define htobe32(x) _byteswap_ulong(x)
# define htole32(x) (x)
# define be32toh(x) _byteswap_ulong(x)
# define le32toh(x) (x)
# define htobe64(x) _byteswap_uint64(x)
# define htole64(x) (x)
# define be64toh(x) _byteswap_uint64(x)
# define le64toh(x) (x)
/* ... for Windows (GCC-like, e.g. mingw or clang) */
#elif (defined(_WIN32) || defined(_WIN64)) && \
(defined(__GNUC__) || defined(__clang__))
# define htobe16(x) __builtin_bswap16(x)
# define htole16(x) (x)
# define be16toh(x) __builtin_bswap16(x)
# define le16toh(x) (x)
# define htobe32(x) __builtin_bswap32(x)
# define htole32(x) (x)
# define be32toh(x) __builtin_bswap32(x)
# define le32toh(x) (x)
# define htobe64(x) __builtin_bswap64(x)
# define htole64(x) (x)
# define be64toh(x) __builtin_bswap64(x)
# define le64toh(x) (x)
/* ... generic big-endian fallback code */
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
/* byte swapping code inspired by:
* https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h
* */
# define htobe32(x) (x)
# define be32toh(x) (x)
# define htole32(x) \
(__extension__({ \
uint32_t _temp = (x); \
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
}))
# define le32toh(x) (htole32((x)))
# define htobe64(x) (x)
# define be64toh(x) (x)
# define htole64(x) \
(__extension__({ \
uint64_t __temp = (x); \
uint32_t __low = htobe32((uint32_t)__temp); \
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
(((uint64_t)__low) << 32) | __high; \
}))
# define le64toh(x) (htole64((x)))
/* ... generic little-endian fallback code */
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define htole32(x) (x)
# define le32toh(x) (x)
# define htobe32(x) \
(__extension__({ \
uint32_t _temp = (x); \
((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \
((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
}))
# define be32toh(x) (htobe32((x)))
# define htole64(x) (x)
# define le64toh(x) (x)
# define htobe64(x) \
(__extension__({ \
uint64_t __temp = (x); \
uint32_t __low = htobe32((uint32_t)__temp); \
uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
(((uint64_t)__low) << 32) | __high; \
}))
# define be64toh(x) (htobe64((x)))
/* ... couldn't determine endian-ness of the target platform */
#else
# error "Please define __BYTE_ORDER__!"
#endif /* defined(__linux__) || ... */
/* Loads and stores. These avoid undefined behavior due to unaligned memory
* accesses, via memcpy. */
inline static uint16_t load16(uint8_t *b) {
uint16_t x;
memcpy(&x, b, 2);
return x;
}
inline static uint32_t load32(uint8_t *b) {
uint32_t x;
memcpy(&x, b, 4);
return x;
}
inline static uint64_t load64(uint8_t *b) {
uint64_t x;
memcpy(&x, b, 8);
return x;
}
inline static void store16(uint8_t *b, uint16_t i) {
memcpy(b, &i, 2);
}
inline static void store32(uint8_t *b, uint32_t i) {
memcpy(b, &i, 4);
}
inline static void store64(uint8_t *b, uint64_t i) {
memcpy(b, &i, 8);
}
#define load16_le(b) (le16toh(load16(b)))
#define store16_le(b, i) (store16(b, htole16(i)))
#define load16_be(b) (be16toh(load16(b)))
#define store16_be(b, i) (store16(b, htobe16(i)))
#define load32_le(b) (le32toh(load32(b)))
#define store32_le(b, i) (store32(b, htole32(i)))
#define load32_be(b) (be32toh(load32(b)))
#define store32_be(b, i) (store32(b, htobe32(i)))
#define load64_le(b) (le64toh(load64(b)))
#define store64_le(b, i) (store64(b, htole64(i)))
#define load64_be(b) (be64toh(load64(b)))
#define store64_be(b, i) (store64(b, htobe64(i)))
#endif

View File

@ -0,0 +1,16 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef __KREMLIN_BUILTIN_H
#define __KREMLIN_BUILTIN_H
/* For alloca, when using KreMLin's -falloca */
#if (defined(_WIN32) || defined(_WIN64))
# include <malloc.h>
#endif
/* If some globals need to be initialized before the main, then kremlin will
* generate and try to link last a function with this type: */
void kremlinit_globals(void);
#endif

View File

@ -0,0 +1,46 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef __KREMLIN_CALLCONV_H
#define __KREMLIN_CALLCONV_H
/******************************************************************************/
/* Some macros to ease compatibility */
/******************************************************************************/
/* We want to generate __cdecl safely without worrying about it being undefined.
* When using MSVC, these are always defined. When using MinGW, these are
* defined too. They have no meaning for other platforms, so we define them to
* be empty macros in other situations. */
#ifndef _MSC_VER
#ifndef __cdecl
#define __cdecl
#endif
#ifndef __stdcall
#define __stdcall
#endif
#ifndef __fastcall
#define __fastcall
#endif
#endif
/* Since KreMLin emits the inline keyword unconditionally, we follow the
* guidelines at https://gcc.gnu.org/onlinedocs/gcc/Inline.html and make this
* __inline__ to ensure the code compiles with -std=c90 and earlier. */
#ifdef __GNUC__
# define inline __inline__
#endif
/* GCC-specific attribute syntax; everyone else gets the standard C inline
* attribute. */
#ifdef __GNU_C__
# ifndef __clang__
# define force_inline inline __attribute__((always_inline))
# else
# define force_inline inline
# endif
#else
# define force_inline inline
#endif
#endif

View File

@ -0,0 +1,34 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef KRML_COMPAT_H
#define KRML_COMPAT_H
#include <inttypes.h>
/* A series of macros that define C implementations of types that are not Low*,
* to facilitate porting programs to Low*. */
typedef const char *Prims_string;
typedef struct {
uint32_t length;
const char *data;
} FStar_Bytes_bytes;
typedef int32_t Prims_pos, Prims_nat, Prims_nonzero, Prims_int,
krml_checked_int_t;
#define RETURN_OR(x) \
do { \
int64_t __ret = x; \
if (__ret < INT32_MIN || INT32_MAX < __ret) { \
KRML_HOST_PRINTF( \
"Prims.{int,nat,pos} integer overflow at %s:%d\n", __FILE__, \
__LINE__); \
KRML_HOST_EXIT(252); \
} \
return (int32_t)__ret; \
} while (0)
#endif

View File

@ -0,0 +1,57 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef __KREMLIN_DEBUG_H
#define __KREMLIN_DEBUG_H
#include <inttypes.h>
#include "kremlin/internal/target.h"
/******************************************************************************/
/* Debugging helpers - intended only for KreMLin developers */
/******************************************************************************/
/* In support of "-wasm -d force-c": we might need this function to be
* forward-declared, because the dependency on WasmSupport appears very late,
* after SimplifyWasm, and sadly, after the topological order has been done. */
void WasmSupport_check_buffer_size(uint32_t s);
/* A series of GCC atrocities to trace function calls (kremlin's [-d c-calls]
* option). Useful when trying to debug, say, Wasm, to compare traces. */
/* clang-format off */
#ifdef __GNUC__
#define KRML_FORMAT(X) _Generic((X), \
uint8_t : "0x%08" PRIx8, \
uint16_t: "0x%08" PRIx16, \
uint32_t: "0x%08" PRIx32, \
uint64_t: "0x%08" PRIx64, \
int8_t : "0x%08" PRIx8, \
int16_t : "0x%08" PRIx16, \
int32_t : "0x%08" PRIx32, \
int64_t : "0x%08" PRIx64, \
default : "%s")
#define KRML_FORMAT_ARG(X) _Generic((X), \
uint8_t : X, \
uint16_t: X, \
uint32_t: X, \
uint64_t: X, \
int8_t : X, \
int16_t : X, \
int32_t : X, \
int64_t : X, \
default : "unknown")
/* clang-format on */
# define KRML_DEBUG_RETURN(X) \
({ \
__auto_type _ret = (X); \
KRML_HOST_PRINTF("returning: "); \
KRML_HOST_PRINTF(KRML_FORMAT(_ret), KRML_FORMAT_ARG(_ret)); \
KRML_HOST_PRINTF(" \n"); \
_ret; \
})
#endif
#endif

View File

@ -0,0 +1,102 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef __KREMLIN_TARGET_H
#define __KREMLIN_TARGET_H
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
#include <limits.h>
#include "kremlin/internal/callconv.h"
/******************************************************************************/
/* Macros that KreMLin will generate. */
/******************************************************************************/
/* For "bare" targets that do not have a C stdlib, the user might want to use
* [-add-early-include '"mydefinitions.h"'] and override these. */
#ifndef KRML_HOST_PRINTF
# define KRML_HOST_PRINTF printf
#endif
#if ( \
(defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
(!(defined KRML_HOST_EPRINTF)))
# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__)
#endif
#ifndef KRML_HOST_EXIT
# define KRML_HOST_EXIT exit
#endif
#ifndef KRML_HOST_MALLOC
# define KRML_HOST_MALLOC malloc
#endif
#ifndef KRML_HOST_CALLOC
# define KRML_HOST_CALLOC calloc
#endif
#ifndef KRML_HOST_FREE
# define KRML_HOST_FREE free
#endif
#ifndef KRML_HOST_TIME
# include <time.h>
/* Prims_nat not yet in scope */
inline static int32_t krml_time() {
return (int32_t)time(NULL);
}
# define KRML_HOST_TIME krml_time
#endif
/* In statement position, exiting is easy. */
#define KRML_EXIT \
do { \
KRML_HOST_PRINTF("Unimplemented function at %s:%d\n", __FILE__, __LINE__); \
KRML_HOST_EXIT(254); \
} while (0)
/* In expression position, use the comma-operator and a malloc to return an
* expression of the right size. KreMLin passes t as the parameter to the macro.
*/
#define KRML_EABORT(t, msg) \
(KRML_HOST_PRINTF("KreMLin abort at %s:%d\n%s\n", __FILE__, __LINE__, msg), \
KRML_HOST_EXIT(255), *((t *)KRML_HOST_MALLOC(sizeof(t))))
/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of
* *elements*. Do an ugly, run-time check (some of which KreMLin can eliminate).
*/
#ifdef __GNUC__
# define _KRML_CHECK_SIZE_PRAGMA \
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
#else
# define _KRML_CHECK_SIZE_PRAGMA
#endif
#define KRML_CHECK_SIZE(size_elt, sz) \
do { \
_KRML_CHECK_SIZE_PRAGMA \
if (((size_t)(sz)) > ((size_t)(SIZE_MAX / (size_elt)))) { \
KRML_HOST_PRINTF( \
"Maximum allocatable size exceeded, aborting before overflow at " \
"%s:%d\n", \
__FILE__, __LINE__); \
KRML_HOST_EXIT(253); \
} \
} while (0)
#if defined(_MSC_VER) && _MSC_VER < 1900
# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) _snprintf_s(buf, sz, _TRUNCATE, fmt, arg)
#else
# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) snprintf(buf, sz, fmt, arg)
#endif
#endif

View File

@ -0,0 +1,61 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
#ifndef KRML_TYPES_H
#define KRML_TYPES_H
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
/* Types which are either abstract, meaning that have to be implemented in C, or
* which are models, meaning that they are swapped out at compile-time for
* hand-written C types (in which case they're marked as noextract). */
typedef uint64_t FStar_UInt64_t, FStar_UInt64_t_;
typedef int64_t FStar_Int64_t, FStar_Int64_t_;
typedef uint32_t FStar_UInt32_t, FStar_UInt32_t_;
typedef int32_t FStar_Int32_t, FStar_Int32_t_;
typedef uint16_t FStar_UInt16_t, FStar_UInt16_t_;
typedef int16_t FStar_Int16_t, FStar_Int16_t_;
typedef uint8_t FStar_UInt8_t, FStar_UInt8_t_;
typedef int8_t FStar_Int8_t, FStar_Int8_t_;
/* Only useful when building Kremlib, because it's in the dependency graph of
* FStar.Int.Cast. */
typedef uint64_t FStar_UInt63_t, FStar_UInt63_t_;
typedef int64_t FStar_Int63_t, FStar_Int63_t_;
typedef double FStar_Float_float;
typedef uint32_t FStar_Char_char;
typedef FILE *FStar_IO_fd_read, *FStar_IO_fd_write;
typedef void *FStar_Dyn_dyn;
typedef const char *C_String_t, *C_String_t_;
typedef int exit_code;
typedef FILE *channel;
typedef unsigned long long TestLib_cycles;
typedef uint64_t FStar_Date_dateTime, FStar_Date_timeSpan;
/* The uint128 type is a special case since we offer several implementations of
* it, depending on the compiler and whether the user wants the verified
* implementation or not. */
#if !defined(KRML_VERIFIED_UINT128) && defined(_MSC_VER) && defined(_M_X64)
# include <emmintrin.h>
typedef __m128i FStar_UInt128_uint128;
#elif !defined(KRML_VERIFIED_UINT128) && !defined(_MSC_VER)
typedef unsigned __int128 FStar_UInt128_uint128;
#else
typedef struct FStar_UInt128_uint128_s {
uint64_t low;
uint64_t high;
} FStar_UInt128_uint128;
#endif
typedef FStar_UInt128_uint128 FStar_UInt128_t, FStar_UInt128_t_, uint128_t;
#endif

View File

@ -0,0 +1,5 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file is automatically included when compiling with -wasm -d force-c */
#define WasmSupport_check_buffer_size(X)

View File

@ -0,0 +1,21 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#ifndef __Hacl_Curve25519_H
#define __Hacl_Curve25519_H
#include "kremlib.h"
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint);
#define __Hacl_Curve25519_H_DEFINED
#endif

View File

@ -0,0 +1,36 @@
/*
* Custom inttypes.h for VS2010 KreMLin requires these definitions,
* but VS2010 doesn't provide them.
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef _INTTYPES_H_VS2010
#define _INTTYPES_H_VS2010
#include <stdint.h>
#ifdef _MSC_VER
#define inline __inline
#endif
/* VS2010 unsigned long == 8 bytes */
#define PRIu64 "I64u"
#endif

View File

@ -0,0 +1,31 @@
/*
* Custom stdbool.h for VS2010 KreMLin requires these definitions,
* but VS2010 doesn't provide them.
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef _STDBOOL_H_VS2010
#define _STDBOOL_H_VS2010
typedef int bool;
static bool true = 1;
static bool false = 0;
#endif

View File

@ -0,0 +1,190 @@
/*
* ECDH with curve-optimized implementation multiplexing
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_X25519_H
#define MBEDTLS_X25519_H
#ifdef __cplusplus
extern "C" {
#endif
#define MBEDTLS_ECP_TLS_CURVE25519 0x1d
#define MBEDTLS_X25519_KEY_SIZE_BYTES 32
/**
* Defines the source of the imported EC key.
*/
typedef enum
{
MBEDTLS_X25519_ECDH_OURS, /**< Our key. */
MBEDTLS_X25519_ECDH_THEIRS, /**< The key of the peer. */
} mbedtls_x25519_ecdh_side;
/**
* \brief The x25519 context structure.
*/
typedef struct
{
unsigned char our_secret[MBEDTLS_X25519_KEY_SIZE_BYTES];
unsigned char peer_point[MBEDTLS_X25519_KEY_SIZE_BYTES];
} mbedtls_x25519_context;
/**
* \brief This function initializes an x25519 context.
*
* \param ctx The x25519 context to initialize.
*/
void mbedtls_x25519_init( mbedtls_x25519_context *ctx );
/**
* \brief This function frees a context.
*
* \param ctx The context to free.
*/
void mbedtls_x25519_free( mbedtls_x25519_context *ctx );
/**
* \brief This function generates a public key and a TLS
* ServerKeyExchange payload.
*
* This is the first function used by a TLS server for x25519.
*
*
* \param ctx The x25519 context.
* \param olen The number of characters written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses and processes a TLS ServerKeyExchange
* payload.
*
*
* \param ctx The x25519 context.
* \param buf The pointer to the start of the input buffer.
* \param end The address for one Byte past the end of the buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
const unsigned char **buf, const unsigned char *end );
/**
* \brief This function sets up an x25519 context from an EC key.
*
* It is used by clients and servers in place of the
* ServerKeyEchange for static ECDH, and imports ECDH
* parameters from the EC key information of a certificate.
*
* \see ecp.h
*
* \param ctx The x25519 context to set up.
* \param key The EC key to use.
* \param side Defines the source of the key: 1: Our key, or
* 0: The key of the peer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_x25519_ecdh_side side );
/**
* \brief This function derives and exports the shared secret.
*
* This is the last function used by both TLS client
* and servers.
*
*
* \param ctx The x25519 context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The length of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function generates a public key and a TLS
* ClientKeyExchange payload.
*
* This is the second function used by a TLS client for x25519.
*
* \see ecp.h
*
* \param ctx The x25519 context.
* \param olen The number of Bytes written.
* \param buf The destination buffer.
* \param blen The size of the destination buffer.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses and processes a TLS ClientKeyExchange
* payload.
*
* This is the second function used by a TLS server for x25519.
*
* \see ecp.h
*
* \param ctx The x25519 context.
* \param buf The start of the input buffer.
* \param blen The length of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
const unsigned char *buf, size_t blen );
#ifdef __cplusplus
}
#endif
#endif /* x25519.h */

View File

@ -0,0 +1,760 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fbuiltin-uint128 -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#include "Hacl_Curve25519.h"
extern uint64_t FStar_UInt64_eq_mask(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_gte_mask(uint64_t x0, uint64_t x1);
extern uint128_t FStar_UInt128_add(uint128_t x0, uint128_t x1);
extern uint128_t FStar_UInt128_add_mod(uint128_t x0, uint128_t x1);
extern uint128_t FStar_UInt128_logand(uint128_t x0, uint128_t x1);
extern uint128_t FStar_UInt128_shift_right(uint128_t x0, uint32_t x1);
extern uint128_t FStar_UInt128_uint64_to_uint128(uint64_t x0);
extern uint64_t FStar_UInt128_uint128_to_uint64(uint128_t x0);
extern uint128_t FStar_UInt128_mul_wide(uint64_t x0, uint64_t x1);
static void Hacl_Bignum_Modulo_carry_top(uint64_t *b)
{
uint64_t b4 = b[4U];
uint64_t b0 = b[0U];
uint64_t b4_ = b4 & (uint64_t)0x7ffffffffffffU;
uint64_t b0_ = b0 + (uint64_t)19U * (b4 >> (uint32_t)51U);
b[4U] = b4_;
b[0U] = b0_;
}
inline static void Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, uint128_t *input)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint128_t xi = input[i];
output[i] = (uint64_t)xi;
}
}
inline static void
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(uint128_t *output, uint64_t *input, uint64_t s)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint128_t xi = output[i];
uint64_t yi = input[i];
output[i] = xi + (uint128_t)yi * s;
}
}
inline static void Hacl_Bignum_Fproduct_carry_wide_(uint128_t *tmp)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
{
uint32_t ctr = i;
uint128_t tctr = tmp[ctr];
uint128_t tctrp1 = tmp[ctr + (uint32_t)1U];
uint64_t r0 = (uint64_t)tctr & (uint64_t)0x7ffffffffffffU;
uint128_t c = tctr >> (uint32_t)51U;
tmp[ctr] = (uint128_t)r0;
tmp[ctr + (uint32_t)1U] = tctrp1 + c;
}
}
inline static void Hacl_Bignum_Fmul_shift_reduce(uint64_t *output)
{
uint64_t tmp = output[4U];
uint64_t b0;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
{
uint32_t ctr = (uint32_t)5U - i - (uint32_t)1U;
uint64_t z = output[ctr - (uint32_t)1U];
output[ctr] = z;
}
}
output[0U] = tmp;
b0 = output[0U];
output[0U] = (uint64_t)19U * b0;
}
static void
Hacl_Bignum_Fmul_mul_shift_reduce_(uint128_t *output, uint64_t *input, uint64_t *input2)
{
uint32_t i;
uint64_t input2i;
{
uint32_t i0;
for (i0 = (uint32_t)0U; i0 < (uint32_t)4U; i0 = i0 + (uint32_t)1U)
{
uint64_t input2i0 = input2[i0];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i0);
Hacl_Bignum_Fmul_shift_reduce(input);
}
}
i = (uint32_t)4U;
input2i = input2[i];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
}
inline static void Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2)
{
uint64_t tmp[5U] = { 0U };
memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]);
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
{
uint128_t t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = (uint128_t)(uint64_t)0U;
}
{
uint128_t b4;
uint128_t b0;
uint128_t b4_;
uint128_t b0_;
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
Hacl_Bignum_Fproduct_carry_wide_(t);
b4 = t[4U];
b0 = t[0U];
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
t[4U] = b4_;
t[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
i0 = output[0U];
i1 = output[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
output[0U] = i0_;
output[1U] = i1_;
}
}
}
inline static void Hacl_Bignum_Fsquare_fsquare__(uint128_t *tmp, uint64_t *output)
{
uint64_t r0 = output[0U];
uint64_t r1 = output[1U];
uint64_t r2 = output[2U];
uint64_t r3 = output[3U];
uint64_t r4 = output[4U];
uint64_t d0 = r0 * (uint64_t)2U;
uint64_t d1 = r1 * (uint64_t)2U;
uint64_t d2 = r2 * (uint64_t)2U * (uint64_t)19U;
uint64_t d419 = r4 * (uint64_t)19U;
uint64_t d4 = d419 * (uint64_t)2U;
uint128_t s0 = (uint128_t)r0 * r0 + (uint128_t)d4 * r1 + (uint128_t)d2 * r3;
uint128_t s1 = (uint128_t)d0 * r1 + (uint128_t)d4 * r2 + (uint128_t)(r3 * (uint64_t)19U) * r3;
uint128_t s2 = (uint128_t)d0 * r2 + (uint128_t)r1 * r1 + (uint128_t)d4 * r3;
uint128_t s3 = (uint128_t)d0 * r3 + (uint128_t)d1 * r2 + (uint128_t)r4 * d419;
uint128_t s4 = (uint128_t)d0 * r4 + (uint128_t)d1 * r3 + (uint128_t)r2 * r2;
tmp[0U] = s0;
tmp[1U] = s1;
tmp[2U] = s2;
tmp[3U] = s3;
tmp[4U] = s4;
}
inline static void Hacl_Bignum_Fsquare_fsquare_(uint128_t *tmp, uint64_t *output)
{
uint128_t b4;
uint128_t b0;
uint128_t b4_;
uint128_t b0_;
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_Bignum_Fsquare_fsquare__(tmp, output);
Hacl_Bignum_Fproduct_carry_wide_(tmp);
b4 = tmp[4U];
b0 = tmp[0U];
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
tmp[4U] = b4_;
tmp[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
i0 = output[0U];
i1 = output[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
output[0U] = i0_;
output[1U] = i1_;
}
static void
Hacl_Bignum_Fsquare_fsquare_times_(uint64_t *input, uint128_t *tmp, uint32_t count1)
{
uint32_t i;
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
for (i = (uint32_t)1U; i < count1; i = i + (uint32_t)1U)
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
}
inline static void
Hacl_Bignum_Fsquare_fsquare_times(uint64_t *output, uint64_t *input, uint32_t count1)
{
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
{
uint128_t t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = (uint128_t)(uint64_t)0U;
}
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
}
}
inline static void Hacl_Bignum_Fsquare_fsquare_times_inplace(uint64_t *output, uint32_t count1)
{
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
{
uint128_t t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = (uint128_t)(uint64_t)0U;
}
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
}
}
inline static void Hacl_Bignum_Crecip_crecip(uint64_t *out, uint64_t *z)
{
uint64_t buf[20U] = { 0U };
uint64_t *a0 = buf;
uint64_t *t00 = buf + (uint32_t)5U;
uint64_t *b0 = buf + (uint32_t)10U;
uint64_t *t01;
uint64_t *b1;
uint64_t *c0;
uint64_t *a;
uint64_t *t0;
uint64_t *b;
uint64_t *c;
Hacl_Bignum_Fsquare_fsquare_times(a0, z, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)2U);
Hacl_Bignum_Fmul_fmul(b0, t00, z);
Hacl_Bignum_Fmul_fmul(a0, b0, a0);
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)1U);
Hacl_Bignum_Fmul_fmul(b0, t00, b0);
Hacl_Bignum_Fsquare_fsquare_times(t00, b0, (uint32_t)5U);
t01 = buf + (uint32_t)5U;
b1 = buf + (uint32_t)10U;
c0 = buf + (uint32_t)15U;
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)10U);
Hacl_Bignum_Fmul_fmul(c0, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, c0, (uint32_t)20U);
Hacl_Bignum_Fmul_fmul(t01, t01, c0);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t01, (uint32_t)10U);
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)50U);
a = buf;
t0 = buf + (uint32_t)5U;
b = buf + (uint32_t)10U;
c = buf + (uint32_t)15U;
Hacl_Bignum_Fmul_fmul(c, t0, b);
Hacl_Bignum_Fsquare_fsquare_times(t0, c, (uint32_t)100U);
Hacl_Bignum_Fmul_fmul(t0, t0, c);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)50U);
Hacl_Bignum_Fmul_fmul(t0, t0, b);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)5U);
Hacl_Bignum_Fmul_fmul(out, t0, a);
}
inline static void Hacl_Bignum_fsum(uint64_t *a, uint64_t *b)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = a[i];
uint64_t yi = b[i];
a[i] = xi + yi;
}
}
inline static void Hacl_Bignum_fdifference(uint64_t *a, uint64_t *b)
{
uint64_t tmp[5U] = { 0U };
uint64_t b0;
uint64_t b1;
uint64_t b2;
uint64_t b3;
uint64_t b4;
memcpy(tmp, b, (uint32_t)5U * sizeof b[0U]);
b0 = tmp[0U];
b1 = tmp[1U];
b2 = tmp[2U];
b3 = tmp[3U];
b4 = tmp[4U];
tmp[0U] = b0 + (uint64_t)0x3fffffffffff68U;
tmp[1U] = b1 + (uint64_t)0x3ffffffffffff8U;
tmp[2U] = b2 + (uint64_t)0x3ffffffffffff8U;
tmp[3U] = b3 + (uint64_t)0x3ffffffffffff8U;
tmp[4U] = b4 + (uint64_t)0x3ffffffffffff8U;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = a[i];
uint64_t yi = tmp[i];
a[i] = yi - xi;
}
}
}
inline static void Hacl_Bignum_fscalar(uint64_t *output, uint64_t *b, uint64_t s)
{
KRML_CHECK_SIZE(sizeof (uint128_t), (uint32_t)5U);
{
uint128_t tmp[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
tmp[_i] = (uint128_t)(uint64_t)0U;
}
{
uint128_t b4;
uint128_t b0;
uint128_t b4_;
uint128_t b0_;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = b[i];
tmp[i] = (uint128_t)xi * s;
}
}
Hacl_Bignum_Fproduct_carry_wide_(tmp);
b4 = tmp[4U];
b0 = tmp[0U];
b4_ = b4 & (uint128_t)(uint64_t)0x7ffffffffffffU;
b0_ = b0 + (uint128_t)(uint64_t)19U * (uint64_t)(b4 >> (uint32_t)51U);
tmp[4U] = b4_;
tmp[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
}
}
}
inline static void Hacl_Bignum_fmul(uint64_t *output, uint64_t *a, uint64_t *b)
{
Hacl_Bignum_Fmul_fmul(output, a, b);
}
inline static void Hacl_Bignum_crecip(uint64_t *output, uint64_t *input)
{
Hacl_Bignum_Crecip_crecip(output, input);
}
static void
Hacl_EC_Point_swap_conditional_step(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
{
uint32_t i = ctr - (uint32_t)1U;
uint64_t ai = a[i];
uint64_t bi = b[i];
uint64_t x = swap1 & (ai ^ bi);
uint64_t ai1 = ai ^ x;
uint64_t bi1 = bi ^ x;
a[i] = ai1;
b[i] = bi1;
}
static void
Hacl_EC_Point_swap_conditional_(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
{
if (!(ctr == (uint32_t)0U))
{
uint32_t i;
Hacl_EC_Point_swap_conditional_step(a, b, swap1, ctr);
i = ctr - (uint32_t)1U;
Hacl_EC_Point_swap_conditional_(a, b, swap1, i);
}
}
static void Hacl_EC_Point_swap_conditional(uint64_t *a, uint64_t *b, uint64_t iswap)
{
uint64_t swap1 = (uint64_t)0U - iswap;
Hacl_EC_Point_swap_conditional_(a, b, swap1, (uint32_t)5U);
Hacl_EC_Point_swap_conditional_(a + (uint32_t)5U, b + (uint32_t)5U, swap1, (uint32_t)5U);
}
static void Hacl_EC_Point_copy(uint64_t *output, uint64_t *input)
{
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
memcpy(output + (uint32_t)5U,
input + (uint32_t)5U,
(uint32_t)5U * sizeof (input + (uint32_t)5U)[0U]);
}
static void Hacl_EC_Format_fexpand(uint64_t *output, uint8_t *input)
{
uint64_t i0 = load64_le(input);
uint8_t *x00 = input + (uint32_t)6U;
uint64_t i1 = load64_le(x00);
uint8_t *x01 = input + (uint32_t)12U;
uint64_t i2 = load64_le(x01);
uint8_t *x02 = input + (uint32_t)19U;
uint64_t i3 = load64_le(x02);
uint8_t *x0 = input + (uint32_t)24U;
uint64_t i4 = load64_le(x0);
uint64_t output0 = i0 & (uint64_t)0x7ffffffffffffU;
uint64_t output1 = i1 >> (uint32_t)3U & (uint64_t)0x7ffffffffffffU;
uint64_t output2 = i2 >> (uint32_t)6U & (uint64_t)0x7ffffffffffffU;
uint64_t output3 = i3 >> (uint32_t)1U & (uint64_t)0x7ffffffffffffU;
uint64_t output4 = i4 >> (uint32_t)12U & (uint64_t)0x7ffffffffffffU;
output[0U] = output0;
output[1U] = output1;
output[2U] = output2;
output[3U] = output3;
output[4U] = output4;
}
static void Hacl_EC_Format_fcontract_first_carry_pass(uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
input[0U] = t0_;
input[1U] = t1__;
input[2U] = t2__;
input[3U] = t3__;
input[4U] = t4_;
}
static void Hacl_EC_Format_fcontract_first_carry_full(uint64_t *input)
{
Hacl_EC_Format_fcontract_first_carry_pass(input);
Hacl_Bignum_Modulo_carry_top(input);
}
static void Hacl_EC_Format_fcontract_second_carry_pass(uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
input[0U] = t0_;
input[1U] = t1__;
input[2U] = t2__;
input[3U] = t3__;
input[4U] = t4_;
}
static void Hacl_EC_Format_fcontract_second_carry_full(uint64_t *input)
{
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_EC_Format_fcontract_second_carry_pass(input);
Hacl_Bignum_Modulo_carry_top(input);
i0 = input[0U];
i1 = input[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
input[0U] = i0_;
input[1U] = i1_;
}
static void Hacl_EC_Format_fcontract_trim(uint64_t *input)
{
uint64_t a0 = input[0U];
uint64_t a1 = input[1U];
uint64_t a2 = input[2U];
uint64_t a3 = input[3U];
uint64_t a4 = input[4U];
uint64_t mask0 = FStar_UInt64_gte_mask(a0, (uint64_t)0x7ffffffffffedU);
uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0x7ffffffffffffU);
uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x7ffffffffffffU);
uint64_t mask3 = FStar_UInt64_eq_mask(a3, (uint64_t)0x7ffffffffffffU);
uint64_t mask4 = FStar_UInt64_eq_mask(a4, (uint64_t)0x7ffffffffffffU);
uint64_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4;
uint64_t a0_ = a0 - ((uint64_t)0x7ffffffffffedU & mask);
uint64_t a1_ = a1 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a2_ = a2 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a3_ = a3 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a4_ = a4 - ((uint64_t)0x7ffffffffffffU & mask);
input[0U] = a0_;
input[1U] = a1_;
input[2U] = a2_;
input[3U] = a3_;
input[4U] = a4_;
}
static void Hacl_EC_Format_fcontract_store(uint8_t *output, uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t o0 = t1 << (uint32_t)51U | t0;
uint64_t o1 = t2 << (uint32_t)38U | t1 >> (uint32_t)13U;
uint64_t o2 = t3 << (uint32_t)25U | t2 >> (uint32_t)26U;
uint64_t o3 = t4 << (uint32_t)12U | t3 >> (uint32_t)39U;
uint8_t *b0 = output;
uint8_t *b1 = output + (uint32_t)8U;
uint8_t *b2 = output + (uint32_t)16U;
uint8_t *b3 = output + (uint32_t)24U;
store64_le(b0, o0);
store64_le(b1, o1);
store64_le(b2, o2);
store64_le(b3, o3);
}
static void Hacl_EC_Format_fcontract(uint8_t *output, uint64_t *input)
{
Hacl_EC_Format_fcontract_first_carry_full(input);
Hacl_EC_Format_fcontract_second_carry_full(input);
Hacl_EC_Format_fcontract_trim(input);
Hacl_EC_Format_fcontract_store(output, input);
}
static void Hacl_EC_Format_scalar_of_point(uint8_t *scalar, uint64_t *point)
{
uint64_t *x = point;
uint64_t *z = point + (uint32_t)5U;
uint64_t buf[10U] = { 0U };
uint64_t *zmone = buf;
uint64_t *sc = buf + (uint32_t)5U;
Hacl_Bignum_crecip(zmone, z);
Hacl_Bignum_fmul(sc, x, zmone);
Hacl_EC_Format_fcontract(scalar, sc);
}
static void
Hacl_EC_AddAndDouble_fmonty(
uint64_t *pp,
uint64_t *ppq,
uint64_t *p,
uint64_t *pq,
uint64_t *qmqp
)
{
uint64_t *qx = qmqp;
uint64_t *x2 = pp;
uint64_t *z2 = pp + (uint32_t)5U;
uint64_t *x3 = ppq;
uint64_t *z3 = ppq + (uint32_t)5U;
uint64_t *x = p;
uint64_t *z = p + (uint32_t)5U;
uint64_t *xprime = pq;
uint64_t *zprime = pq + (uint32_t)5U;
uint64_t buf[40U] = { 0U };
uint64_t *origx = buf;
uint64_t *origxprime0 = buf + (uint32_t)5U;
uint64_t *xxprime0 = buf + (uint32_t)25U;
uint64_t *zzprime0 = buf + (uint32_t)30U;
uint64_t *origxprime;
uint64_t *xx0;
uint64_t *zz0;
uint64_t *xxprime;
uint64_t *zzprime;
uint64_t *zzzprime;
uint64_t *zzz;
uint64_t *xx;
uint64_t *zz;
uint64_t scalar;
memcpy(origx, x, (uint32_t)5U * sizeof x[0U]);
Hacl_Bignum_fsum(x, z);
Hacl_Bignum_fdifference(z, origx);
memcpy(origxprime0, xprime, (uint32_t)5U * sizeof xprime[0U]);
Hacl_Bignum_fsum(xprime, zprime);
Hacl_Bignum_fdifference(zprime, origxprime0);
Hacl_Bignum_fmul(xxprime0, xprime, z);
Hacl_Bignum_fmul(zzprime0, x, zprime);
origxprime = buf + (uint32_t)5U;
xx0 = buf + (uint32_t)15U;
zz0 = buf + (uint32_t)20U;
xxprime = buf + (uint32_t)25U;
zzprime = buf + (uint32_t)30U;
zzzprime = buf + (uint32_t)35U;
memcpy(origxprime, xxprime, (uint32_t)5U * sizeof xxprime[0U]);
Hacl_Bignum_fsum(xxprime, zzprime);
Hacl_Bignum_fdifference(zzprime, origxprime);
Hacl_Bignum_Fsquare_fsquare_times(x3, xxprime, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(zzzprime, zzprime, (uint32_t)1U);
Hacl_Bignum_fmul(z3, zzzprime, qx);
Hacl_Bignum_Fsquare_fsquare_times(xx0, x, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(zz0, z, (uint32_t)1U);
zzz = buf + (uint32_t)10U;
xx = buf + (uint32_t)15U;
zz = buf + (uint32_t)20U;
Hacl_Bignum_fmul(x2, xx, zz);
Hacl_Bignum_fdifference(zz, xx);
scalar = (uint64_t)121665U;
Hacl_Bignum_fscalar(zzz, zz, scalar);
Hacl_Bignum_fsum(zzz, xx);
Hacl_Bignum_fmul(z2, zzz, zz);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt
)
{
uint64_t bit0 = (uint64_t)(byt >> (uint32_t)7U);
uint64_t bit;
Hacl_EC_Point_swap_conditional(nq, nqpq, bit0);
Hacl_EC_AddAndDouble_fmonty(nq2, nqpq2, nq, nqpq, q);
bit = (uint64_t)(byt >> (uint32_t)7U);
Hacl_EC_Point_swap_conditional(nq2, nqpq2, bit);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt
)
{
uint8_t byt1;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt);
byt1 = byt << (uint32_t)1U;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt,
uint32_t i
)
{
if (!(i == (uint32_t)0U))
{
uint32_t i_ = i - (uint32_t)1U;
uint8_t byt_;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt);
byt_ = byt << (uint32_t)2U;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byt_, i_);
}
}
static void
Hacl_EC_Ladder_BigLoop_cmult_big_loop(
uint8_t *n1,
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint32_t i
)
{
if (!(i == (uint32_t)0U))
{
uint32_t i1 = i - (uint32_t)1U;
uint8_t byte = n1[i1];
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, (uint32_t)4U);
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, i1);
}
}
static void Hacl_EC_Ladder_cmult(uint64_t *result, uint8_t *n1, uint64_t *q)
{
uint64_t point_buf[40U] = { 0U };
uint64_t *nq = point_buf;
uint64_t *nqpq = point_buf + (uint32_t)10U;
uint64_t *nq2 = point_buf + (uint32_t)20U;
uint64_t *nqpq2 = point_buf + (uint32_t)30U;
Hacl_EC_Point_copy(nqpq, q);
nq[0U] = (uint64_t)1U;
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, (uint32_t)32U);
Hacl_EC_Point_copy(result, nq);
}
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint)
{
uint64_t buf0[10U] = { 0U };
uint64_t *x0 = buf0;
uint64_t *z = buf0 + (uint32_t)5U;
uint64_t *q;
Hacl_EC_Format_fexpand(x0, basepoint);
z[0U] = (uint64_t)1U;
q = buf0;
{
uint8_t e[32U] = { 0U };
uint8_t e0;
uint8_t e31;
uint8_t e01;
uint8_t e311;
uint8_t e312;
uint8_t *scalar;
memcpy(e, secret, (uint32_t)32U * sizeof secret[0U]);
e0 = e[0U];
e31 = e[31U];
e01 = e0 & (uint8_t)248U;
e311 = e31 & (uint8_t)127U;
e312 = e311 | (uint8_t)64U;
e[0U] = e01;
e[31U] = e312;
scalar = e;
{
uint64_t buf[15U] = { 0U };
uint64_t *nq = buf;
uint64_t *x = nq;
x[0U] = (uint64_t)1U;
Hacl_EC_Ladder_cmult(nq, scalar, q);
Hacl_EC_Format_scalar_of_point(mypublic, nq);
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Interface to code from Project Everest
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
#if defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16)
#define MBEDTLS_HAVE_INT128
#endif
#if defined(MBEDTLS_HAVE_INT128)
#include "Hacl_Curve25519.c"
#else
#define KRML_VERIFIED_UINT128
#include "kremlib/FStar_UInt128_extracted.c"
#include "legacy/Hacl_Curve25519.c"
#endif
#include "kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.c"
#endif /* defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) */

111
3rdparty/everest/library/everest.c vendored Normal file
View File

@ -0,0 +1,111 @@
/*
* Interface to code from Project Everest
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of Mbed TLS (https://tls.mbed.org).
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <string.h>
#include "mbedtls/ecdh.h"
#include "everest/x25519.h"
#include "everest/everest.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
int mbedtls_everest_setup( mbedtls_ecdh_context_everest *ctx, int grp_id )
{
if( grp_id != MBEDTLS_ECP_DP_CURVE25519 )
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
mbedtls_x25519_init( &ctx->ctx );
return 0;
}
void mbedtls_everest_free( mbedtls_ecdh_context_everest *ctx )
{
mbedtls_x25519_free( &ctx->ctx );
}
int mbedtls_everest_make_params( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
return mbedtls_x25519_make_params( x25519_ctx, olen, buf, blen, f_rng, p_rng );
}
int mbedtls_everest_read_params( mbedtls_ecdh_context_everest *ctx,
const unsigned char **buf,
const unsigned char *end )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
return mbedtls_x25519_read_params( x25519_ctx, buf, end );
}
int mbedtls_everest_get_params( mbedtls_ecdh_context_everest *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_everest_ecdh_side side )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
mbedtls_x25519_ecdh_side s = side == MBEDTLS_EVEREST_ECDH_OURS ?
MBEDTLS_X25519_ECDH_OURS :
MBEDTLS_X25519_ECDH_THEIRS;
return mbedtls_x25519_get_params( x25519_ctx, key, s );
}
int mbedtls_everest_make_public( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
return mbedtls_x25519_make_public( x25519_ctx, olen, buf, blen, f_rng, p_rng );
}
int mbedtls_everest_read_public( mbedtls_ecdh_context_everest *ctx,
const unsigned char *buf, size_t blen )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
return mbedtls_x25519_read_public ( x25519_ctx, buf, blen );
}
int mbedtls_everest_calc_secret( mbedtls_ecdh_context_everest *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )( void *, unsigned char *, size_t ),
void *p_rng )
{
mbedtls_x25519_context *x25519_ctx = &ctx->ctx;
return mbedtls_x25519_calc_secret( x25519_ctx, olen, buf, blen, f_rng, p_rng );
}
#endif /* MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */

View File

@ -0,0 +1,413 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir extracted -warn-error +9+11 -skip-compilation -extract-uints -add-include <inttypes.h> -add-include "kremlib.h" -add-include "kremlin/internal/compat.h" extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#include "FStar_UInt128.h"
#include "kremlin/c_endianness.h"
#include "FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h"
uint64_t FStar_UInt128___proj__Mkuint128__item__low(FStar_UInt128_uint128 projectee)
{
return projectee.low;
}
uint64_t FStar_UInt128___proj__Mkuint128__item__high(FStar_UInt128_uint128 projectee)
{
return projectee.high;
}
static uint64_t FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b)
{
return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U;
}
static uint64_t FStar_UInt128_carry(uint64_t a, uint64_t b)
{
return FStar_UInt128_constant_time_carry(a, b);
}
FStar_UInt128_uint128 FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
return flat;
}
FStar_UInt128_uint128
FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low + b.low, a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low) };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
return flat;
}
FStar_UInt128_uint128
FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
return flat;
}
static FStar_UInt128_uint128
FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat = { a.low - b.low, a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low) };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return FStar_UInt128_sub_mod_impl(a, b);
}
FStar_UInt128_uint128 FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128 flat = { a.low & b.low, a.high & b.high };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128 flat = { a.low ^ b.low, a.high ^ b.high };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128 flat = { a.low | b.low, a.high | b.high };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a)
{
FStar_UInt128_uint128 flat = { ~a.low, ~a.high };
return flat;
}
static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U;
static uint64_t FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s)
{
return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s));
}
static uint64_t FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s)
{
return FStar_UInt128_add_u64_shift_left(hi, lo, s);
}
static FStar_UInt128_uint128
FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s)
{
if (s == (uint32_t)0U)
{
return a;
}
else
{
FStar_UInt128_uint128
flat = { a.low << s, FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s) };
return flat;
}
}
static FStar_UInt128_uint128
FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s)
{
FStar_UInt128_uint128 flat = { (uint64_t)0U, a.low << (s - FStar_UInt128_u32_64) };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s)
{
if (s < FStar_UInt128_u32_64)
{
return FStar_UInt128_shift_left_small(a, s);
}
else
{
return FStar_UInt128_shift_left_large(a, s);
}
}
static uint64_t FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s)
{
return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s));
}
static uint64_t FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s)
{
return FStar_UInt128_add_u64_shift_right(hi, lo, s);
}
static FStar_UInt128_uint128
FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s)
{
if (s == (uint32_t)0U)
{
return a;
}
else
{
FStar_UInt128_uint128
flat = { FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s), a.high >> s };
return flat;
}
}
static FStar_UInt128_uint128
FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s)
{
FStar_UInt128_uint128 flat = { a.high >> (s - FStar_UInt128_u32_64), (uint64_t)0U };
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s)
{
if (s < FStar_UInt128_u32_64)
{
return FStar_UInt128_shift_right_small(a, s);
}
else
{
return FStar_UInt128_shift_right_large(a, s);
}
}
bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return a.low == b.low && a.high == b.high;
}
bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return a.high > b.high || (a.high == b.high && a.low > b.low);
}
bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return a.high < b.high || (a.high == b.high && a.low < b.low);
}
bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return a.high > b.high || (a.high == b.high && a.low >= b.low);
}
bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
return a.high < b.high || (a.high == b.high && a.low <= b.low);
}
FStar_UInt128_uint128 FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat =
{
FStar_UInt64_eq_mask(a.low,
b.low)
& FStar_UInt64_eq_mask(a.high, b.high),
FStar_UInt64_eq_mask(a.low,
b.low)
& FStar_UInt64_eq_mask(a.high, b.high)
};
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b)
{
FStar_UInt128_uint128
flat =
{
(FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
| (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)),
(FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high))
| (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low))
};
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a)
{
FStar_UInt128_uint128 flat = { a, (uint64_t)0U };
return flat;
}
uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a)
{
return a.low;
}
FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_add;
FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Question_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_add_underspec;
FStar_UInt128_uint128
(*FStar_UInt128_op_Plus_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_add_mod;
FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_sub;
FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Question_Hat)(
FStar_UInt128_uint128 x0,
FStar_UInt128_uint128 x1
) = FStar_UInt128_sub_underspec;
FStar_UInt128_uint128
(*FStar_UInt128_op_Subtraction_Percent_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_sub_mod;
FStar_UInt128_uint128
(*FStar_UInt128_op_Amp_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_logand;
FStar_UInt128_uint128
(*FStar_UInt128_op_Hat_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_logxor;
FStar_UInt128_uint128
(*FStar_UInt128_op_Bar_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_logor;
FStar_UInt128_uint128
(*FStar_UInt128_op_Less_Less_Hat)(FStar_UInt128_uint128 x0, uint32_t x1) =
FStar_UInt128_shift_left;
FStar_UInt128_uint128
(*FStar_UInt128_op_Greater_Greater_Hat)(FStar_UInt128_uint128 x0, uint32_t x1) =
FStar_UInt128_shift_right;
bool
(*FStar_UInt128_op_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_eq;
bool
(*FStar_UInt128_op_Greater_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_gt;
bool
(*FStar_UInt128_op_Less_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_lt;
bool
(*FStar_UInt128_op_Greater_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_gte;
bool
(*FStar_UInt128_op_Less_Equals_Hat)(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1) =
FStar_UInt128_lte;
static uint64_t FStar_UInt128_u64_mod_32(uint64_t a)
{
return a & (uint64_t)0xffffffffU;
}
static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U;
static uint64_t FStar_UInt128_u32_combine(uint64_t hi, uint64_t lo)
{
return lo + (hi << FStar_UInt128_u32_32);
}
FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y)
{
FStar_UInt128_uint128
flat =
{
FStar_UInt128_u32_combine((x >> FStar_UInt128_u32_32)
* (uint64_t)y
+ (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32),
FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * (uint64_t)y)),
((x >> FStar_UInt128_u32_32)
* (uint64_t)y
+ (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32))
>> FStar_UInt128_u32_32
};
return flat;
}
typedef struct K___uint64_t_uint64_t_uint64_t_uint64_t_s
{
uint64_t fst;
uint64_t snd;
uint64_t thd;
uint64_t f3;
}
K___uint64_t_uint64_t_uint64_t_uint64_t;
static K___uint64_t_uint64_t_uint64_t_uint64_t
FStar_UInt128_mul_wide_impl_t_(uint64_t x, uint64_t y)
{
K___uint64_t_uint64_t_uint64_t_uint64_t
flat =
{
FStar_UInt128_u64_mod_32(x),
FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y)),
x
>> FStar_UInt128_u32_32,
(x >> FStar_UInt128_u32_32)
* FStar_UInt128_u64_mod_32(y)
+ (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)
};
return flat;
}
static uint64_t FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo)
{
return lo + (hi << FStar_UInt128_u32_32);
}
static FStar_UInt128_uint128 FStar_UInt128_mul_wide_impl(uint64_t x, uint64_t y)
{
K___uint64_t_uint64_t_uint64_t_uint64_t scrut = FStar_UInt128_mul_wide_impl_t_(x, y);
uint64_t u1 = scrut.fst;
uint64_t w3 = scrut.snd;
uint64_t x_ = scrut.thd;
uint64_t t_ = scrut.f3;
FStar_UInt128_uint128
flat =
{
FStar_UInt128_u32_combine_(u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_),
w3),
x_
* (y >> FStar_UInt128_u32_32)
+ (t_ >> FStar_UInt128_u32_32)
+ ((u1 * (y >> FStar_UInt128_u32_32) + FStar_UInt128_u64_mod_32(t_)) >> FStar_UInt128_u32_32)
};
return flat;
}
FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y)
{
return FStar_UInt128_mul_wide_impl(x, y);
}

View File

@ -0,0 +1,100 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: ../krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrB9w -minimal -fparentheses -fcurly-braces -fno-shadow -header copyright-header.txt -minimal -tmpdir dist/minimal -skip-compilation -extract-uints -add-include <inttypes.h> -add-include <stdbool.h> -add-include "kremlin/internal/compat.h" -add-include "kremlin/internal/types.h" -bundle FStar.UInt64+FStar.UInt32+FStar.UInt16+FStar.UInt8=* extracted/prims.krml extracted/FStar_Pervasives_Native.krml extracted/FStar_Pervasives.krml extracted/FStar_Mul.krml extracted/FStar_Squash.krml extracted/FStar_Classical.krml extracted/FStar_StrongExcludedMiddle.krml extracted/FStar_FunctionalExtensionality.krml extracted/FStar_List_Tot_Base.krml extracted/FStar_List_Tot_Properties.krml extracted/FStar_List_Tot.krml extracted/FStar_Seq_Base.krml extracted/FStar_Seq_Properties.krml extracted/FStar_Seq.krml extracted/FStar_Math_Lib.krml extracted/FStar_Math_Lemmas.krml extracted/FStar_BitVector.krml extracted/FStar_UInt.krml extracted/FStar_UInt32.krml extracted/FStar_Int.krml extracted/FStar_Int16.krml extracted/FStar_Preorder.krml extracted/FStar_Ghost.krml extracted/FStar_ErasedLogic.krml extracted/FStar_UInt64.krml extracted/FStar_Set.krml extracted/FStar_PropositionalExtensionality.krml extracted/FStar_PredicateExtensionality.krml extracted/FStar_TSet.krml extracted/FStar_Monotonic_Heap.krml extracted/FStar_Heap.krml extracted/FStar_Map.krml extracted/FStar_Monotonic_HyperHeap.krml extracted/FStar_Monotonic_HyperStack.krml extracted/FStar_HyperStack.krml extracted/FStar_Monotonic_Witnessed.krml extracted/FStar_HyperStack_ST.krml extracted/FStar_HyperStack_All.krml extracted/FStar_Date.krml extracted/FStar_Universe.krml extracted/FStar_GSet.krml extracted/FStar_ModifiesGen.krml extracted/LowStar_Monotonic_Buffer.krml extracted/LowStar_Buffer.krml extracted/Spec_Loops.krml extracted/LowStar_BufferOps.krml extracted/C_Loops.krml extracted/FStar_UInt8.krml extracted/FStar_Kremlin_Endianness.krml extracted/FStar_UInt63.krml extracted/FStar_Exn.krml extracted/FStar_ST.krml extracted/FStar_All.krml extracted/FStar_Dyn.krml extracted/FStar_Int63.krml extracted/FStar_Int64.krml extracted/FStar_Int32.krml extracted/FStar_Int8.krml extracted/FStar_UInt16.krml extracted/FStar_Int_Cast.krml extracted/FStar_UInt128.krml extracted/C_Endianness.krml extracted/FStar_List.krml extracted/FStar_Float.krml extracted/FStar_IO.krml extracted/C.krml extracted/FStar_Char.krml extracted/FStar_String.krml extracted/LowStar_Modifies.krml extracted/C_String.krml extracted/FStar_Bytes.krml extracted/FStar_HyperStack_IO.krml extracted/C_Failure.krml extracted/TestLib.krml extracted/FStar_Int_Cast_Full.krml
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#include "FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h"
uint64_t FStar_UInt64_eq_mask(uint64_t a, uint64_t b)
{
uint64_t x = a ^ b;
uint64_t minus_x = ~x + (uint64_t)1U;
uint64_t x_or_minus_x = x | minus_x;
uint64_t xnx = x_or_minus_x >> (uint32_t)63U;
return xnx - (uint64_t)1U;
}
uint64_t FStar_UInt64_gte_mask(uint64_t a, uint64_t b)
{
uint64_t x = a;
uint64_t y = b;
uint64_t x_xor_y = x ^ y;
uint64_t x_sub_y = x - y;
uint64_t x_sub_y_xor_y = x_sub_y ^ y;
uint64_t q = x_xor_y | x_sub_y_xor_y;
uint64_t x_xor_q = x ^ q;
uint64_t x_xor_q_ = x_xor_q >> (uint32_t)63U;
return x_xor_q_ - (uint64_t)1U;
}
uint32_t FStar_UInt32_eq_mask(uint32_t a, uint32_t b)
{
uint32_t x = a ^ b;
uint32_t minus_x = ~x + (uint32_t)1U;
uint32_t x_or_minus_x = x | minus_x;
uint32_t xnx = x_or_minus_x >> (uint32_t)31U;
return xnx - (uint32_t)1U;
}
uint32_t FStar_UInt32_gte_mask(uint32_t a, uint32_t b)
{
uint32_t x = a;
uint32_t y = b;
uint32_t x_xor_y = x ^ y;
uint32_t x_sub_y = x - y;
uint32_t x_sub_y_xor_y = x_sub_y ^ y;
uint32_t q = x_xor_y | x_sub_y_xor_y;
uint32_t x_xor_q = x ^ q;
uint32_t x_xor_q_ = x_xor_q >> (uint32_t)31U;
return x_xor_q_ - (uint32_t)1U;
}
uint16_t FStar_UInt16_eq_mask(uint16_t a, uint16_t b)
{
uint16_t x = a ^ b;
uint16_t minus_x = ~x + (uint16_t)1U;
uint16_t x_or_minus_x = x | minus_x;
uint16_t xnx = x_or_minus_x >> (uint32_t)15U;
return xnx - (uint16_t)1U;
}
uint16_t FStar_UInt16_gte_mask(uint16_t a, uint16_t b)
{
uint16_t x = a;
uint16_t y = b;
uint16_t x_xor_y = x ^ y;
uint16_t x_sub_y = x - y;
uint16_t x_sub_y_xor_y = x_sub_y ^ y;
uint16_t q = x_xor_y | x_sub_y_xor_y;
uint16_t x_xor_q = x ^ q;
uint16_t x_xor_q_ = x_xor_q >> (uint32_t)15U;
return x_xor_q_ - (uint16_t)1U;
}
uint8_t FStar_UInt8_eq_mask(uint8_t a, uint8_t b)
{
uint8_t x = a ^ b;
uint8_t minus_x = ~x + (uint8_t)1U;
uint8_t x_or_minus_x = x | minus_x;
uint8_t xnx = x_or_minus_x >> (uint32_t)7U;
return xnx - (uint8_t)1U;
}
uint8_t FStar_UInt8_gte_mask(uint8_t a, uint8_t b)
{
uint8_t x = a;
uint8_t y = b;
uint8_t x_xor_y = x ^ y;
uint8_t x_sub_y = x - y;
uint8_t x_sub_y_xor_y = x_sub_y ^ y;
uint8_t q = x_xor_y | x_sub_y_xor_y;
uint8_t x_xor_q = x ^ q;
uint8_t x_xor_q_ = x_xor_q >> (uint32_t)7U;
return x_xor_q_ - (uint8_t)1U;
}

View File

@ -0,0 +1,805 @@
/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
Licensed under the Apache 2.0 License. */
/* This file was generated by KreMLin <https://github.com/FStarLang/kremlin>
* KreMLin invocation: /mnt/e/everest/verify/kremlin/krml -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -fc89 -fparentheses -fno-shadow -header /mnt/e/everest/verify/hdrcLh -minimal -I /mnt/e/everest/verify/hacl-star/code/lib/kremlin -I /mnt/e/everest/verify/kremlin/kremlib/compat -I /mnt/e/everest/verify/hacl-star/specs -I /mnt/e/everest/verify/hacl-star/specs/old -I . -ccopt -march=native -verbose -ldopt -flto -tmpdir x25519-c -I ../bignum -bundle Hacl.Curve25519=* -minimal -add-include "kremlib.h" -skip-compilation x25519-c/out.krml -o x25519-c/Hacl_Curve25519.c
* F* version: 059db0c8
* KreMLin version: 916c37ac
*/
#include "Hacl_Curve25519.h"
extern uint64_t FStar_UInt64_eq_mask(uint64_t x0, uint64_t x1);
extern uint64_t FStar_UInt64_gte_mask(uint64_t x0, uint64_t x1);
extern FStar_UInt128_uint128
FStar_UInt128_add(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
FStar_UInt128_add_mod(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128
FStar_UInt128_logand(FStar_UInt128_uint128 x0, FStar_UInt128_uint128 x1);
extern FStar_UInt128_uint128 FStar_UInt128_shift_right(FStar_UInt128_uint128 x0, uint32_t x1);
extern FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t x0);
extern uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 x0);
extern FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x0, uint64_t x1);
static void Hacl_Bignum_Modulo_carry_top(uint64_t *b)
{
uint64_t b4 = b[4U];
uint64_t b0 = b[0U];
uint64_t b4_ = b4 & (uint64_t)0x7ffffffffffffU;
uint64_t b0_ = b0 + (uint64_t)19U * (b4 >> (uint32_t)51U);
b[4U] = b4_;
b[0U] = b0_;
}
inline static void
Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, FStar_UInt128_uint128 *input)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
FStar_UInt128_uint128 xi = input[i];
output[i] = FStar_UInt128_uint128_to_uint64(xi);
}
}
inline static void
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(
FStar_UInt128_uint128 *output,
uint64_t *input,
uint64_t s
)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
FStar_UInt128_uint128 xi = output[i];
uint64_t yi = input[i];
output[i] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s));
}
}
inline static void Hacl_Bignum_Fproduct_carry_wide_(FStar_UInt128_uint128 *tmp)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
{
uint32_t ctr = i;
FStar_UInt128_uint128 tctr = tmp[ctr];
FStar_UInt128_uint128 tctrp1 = tmp[ctr + (uint32_t)1U];
uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0x7ffffffffffffU;
FStar_UInt128_uint128 c = FStar_UInt128_shift_right(tctr, (uint32_t)51U);
tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0);
tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c);
}
}
inline static void Hacl_Bignum_Fmul_shift_reduce(uint64_t *output)
{
uint64_t tmp = output[4U];
uint64_t b0;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U)
{
uint32_t ctr = (uint32_t)5U - i - (uint32_t)1U;
uint64_t z = output[ctr - (uint32_t)1U];
output[ctr] = z;
}
}
output[0U] = tmp;
b0 = output[0U];
output[0U] = (uint64_t)19U * b0;
}
static void
Hacl_Bignum_Fmul_mul_shift_reduce_(
FStar_UInt128_uint128 *output,
uint64_t *input,
uint64_t *input2
)
{
uint32_t i;
uint64_t input2i;
{
uint32_t i0;
for (i0 = (uint32_t)0U; i0 < (uint32_t)4U; i0 = i0 + (uint32_t)1U)
{
uint64_t input2i0 = input2[i0];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i0);
Hacl_Bignum_Fmul_shift_reduce(input);
}
}
i = (uint32_t)4U;
input2i = input2[i];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
}
inline static void Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2)
{
uint64_t tmp[5U] = { 0U };
memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]);
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
{
FStar_UInt128_uint128 t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
}
{
FStar_UInt128_uint128 b4;
FStar_UInt128_uint128 b0;
FStar_UInt128_uint128 b4_;
FStar_UInt128_uint128 b0_;
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
Hacl_Bignum_Fproduct_carry_wide_(t);
b4 = t[4U];
b0 = t[0U];
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
b0_ =
FStar_UInt128_add(b0,
FStar_UInt128_mul_wide((uint64_t)19U,
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
t[4U] = b4_;
t[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
i0 = output[0U];
i1 = output[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
output[0U] = i0_;
output[1U] = i1_;
}
}
}
inline static void Hacl_Bignum_Fsquare_fsquare__(FStar_UInt128_uint128 *tmp, uint64_t *output)
{
uint64_t r0 = output[0U];
uint64_t r1 = output[1U];
uint64_t r2 = output[2U];
uint64_t r3 = output[3U];
uint64_t r4 = output[4U];
uint64_t d0 = r0 * (uint64_t)2U;
uint64_t d1 = r1 * (uint64_t)2U;
uint64_t d2 = r2 * (uint64_t)2U * (uint64_t)19U;
uint64_t d419 = r4 * (uint64_t)19U;
uint64_t d4 = d419 * (uint64_t)2U;
FStar_UInt128_uint128
s0 =
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(r0, r0),
FStar_UInt128_mul_wide(d4, r1)),
FStar_UInt128_mul_wide(d2, r3));
FStar_UInt128_uint128
s1 =
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r1),
FStar_UInt128_mul_wide(d4, r2)),
FStar_UInt128_mul_wide(r3 * (uint64_t)19U, r3));
FStar_UInt128_uint128
s2 =
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r2),
FStar_UInt128_mul_wide(r1, r1)),
FStar_UInt128_mul_wide(d4, r3));
FStar_UInt128_uint128
s3 =
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r3),
FStar_UInt128_mul_wide(d1, r2)),
FStar_UInt128_mul_wide(r4, d419));
FStar_UInt128_uint128
s4 =
FStar_UInt128_add(FStar_UInt128_add(FStar_UInt128_mul_wide(d0, r4),
FStar_UInt128_mul_wide(d1, r3)),
FStar_UInt128_mul_wide(r2, r2));
tmp[0U] = s0;
tmp[1U] = s1;
tmp[2U] = s2;
tmp[3U] = s3;
tmp[4U] = s4;
}
inline static void Hacl_Bignum_Fsquare_fsquare_(FStar_UInt128_uint128 *tmp, uint64_t *output)
{
FStar_UInt128_uint128 b4;
FStar_UInt128_uint128 b0;
FStar_UInt128_uint128 b4_;
FStar_UInt128_uint128 b0_;
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_Bignum_Fsquare_fsquare__(tmp, output);
Hacl_Bignum_Fproduct_carry_wide_(tmp);
b4 = tmp[4U];
b0 = tmp[0U];
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
b0_ =
FStar_UInt128_add(b0,
FStar_UInt128_mul_wide((uint64_t)19U,
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
tmp[4U] = b4_;
tmp[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
i0 = output[0U];
i1 = output[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
output[0U] = i0_;
output[1U] = i1_;
}
static void
Hacl_Bignum_Fsquare_fsquare_times_(
uint64_t *input,
FStar_UInt128_uint128 *tmp,
uint32_t count1
)
{
uint32_t i;
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
for (i = (uint32_t)1U; i < count1; i = i + (uint32_t)1U)
Hacl_Bignum_Fsquare_fsquare_(tmp, input);
}
inline static void
Hacl_Bignum_Fsquare_fsquare_times(uint64_t *output, uint64_t *input, uint32_t count1)
{
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
{
FStar_UInt128_uint128 t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
}
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
}
}
inline static void Hacl_Bignum_Fsquare_fsquare_times_inplace(uint64_t *output, uint32_t count1)
{
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
{
FStar_UInt128_uint128 t[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
}
Hacl_Bignum_Fsquare_fsquare_times_(output, t, count1);
}
}
inline static void Hacl_Bignum_Crecip_crecip(uint64_t *out, uint64_t *z)
{
uint64_t buf[20U] = { 0U };
uint64_t *a0 = buf;
uint64_t *t00 = buf + (uint32_t)5U;
uint64_t *b0 = buf + (uint32_t)10U;
uint64_t *t01;
uint64_t *b1;
uint64_t *c0;
uint64_t *a;
uint64_t *t0;
uint64_t *b;
uint64_t *c;
Hacl_Bignum_Fsquare_fsquare_times(a0, z, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)2U);
Hacl_Bignum_Fmul_fmul(b0, t00, z);
Hacl_Bignum_Fmul_fmul(a0, b0, a0);
Hacl_Bignum_Fsquare_fsquare_times(t00, a0, (uint32_t)1U);
Hacl_Bignum_Fmul_fmul(b0, t00, b0);
Hacl_Bignum_Fsquare_fsquare_times(t00, b0, (uint32_t)5U);
t01 = buf + (uint32_t)5U;
b1 = buf + (uint32_t)10U;
c0 = buf + (uint32_t)15U;
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)10U);
Hacl_Bignum_Fmul_fmul(c0, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, c0, (uint32_t)20U);
Hacl_Bignum_Fmul_fmul(t01, t01, c0);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t01, (uint32_t)10U);
Hacl_Bignum_Fmul_fmul(b1, t01, b1);
Hacl_Bignum_Fsquare_fsquare_times(t01, b1, (uint32_t)50U);
a = buf;
t0 = buf + (uint32_t)5U;
b = buf + (uint32_t)10U;
c = buf + (uint32_t)15U;
Hacl_Bignum_Fmul_fmul(c, t0, b);
Hacl_Bignum_Fsquare_fsquare_times(t0, c, (uint32_t)100U);
Hacl_Bignum_Fmul_fmul(t0, t0, c);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)50U);
Hacl_Bignum_Fmul_fmul(t0, t0, b);
Hacl_Bignum_Fsquare_fsquare_times_inplace(t0, (uint32_t)5U);
Hacl_Bignum_Fmul_fmul(out, t0, a);
}
inline static void Hacl_Bignum_fsum(uint64_t *a, uint64_t *b)
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = a[i];
uint64_t yi = b[i];
a[i] = xi + yi;
}
}
inline static void Hacl_Bignum_fdifference(uint64_t *a, uint64_t *b)
{
uint64_t tmp[5U] = { 0U };
uint64_t b0;
uint64_t b1;
uint64_t b2;
uint64_t b3;
uint64_t b4;
memcpy(tmp, b, (uint32_t)5U * sizeof b[0U]);
b0 = tmp[0U];
b1 = tmp[1U];
b2 = tmp[2U];
b3 = tmp[3U];
b4 = tmp[4U];
tmp[0U] = b0 + (uint64_t)0x3fffffffffff68U;
tmp[1U] = b1 + (uint64_t)0x3ffffffffffff8U;
tmp[2U] = b2 + (uint64_t)0x3ffffffffffff8U;
tmp[3U] = b3 + (uint64_t)0x3ffffffffffff8U;
tmp[4U] = b4 + (uint64_t)0x3ffffffffffff8U;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = a[i];
uint64_t yi = tmp[i];
a[i] = yi - xi;
}
}
}
inline static void Hacl_Bignum_fscalar(uint64_t *output, uint64_t *b, uint64_t s)
{
KRML_CHECK_SIZE(sizeof (FStar_UInt128_uint128), (uint32_t)5U);
{
FStar_UInt128_uint128 tmp[5U];
{
uint32_t _i;
for (_i = 0U; _i < (uint32_t)5U; ++_i)
tmp[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
}
{
FStar_UInt128_uint128 b4;
FStar_UInt128_uint128 b0;
FStar_UInt128_uint128 b4_;
FStar_UInt128_uint128 b0_;
{
uint32_t i;
for (i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U)
{
uint64_t xi = b[i];
tmp[i] = FStar_UInt128_mul_wide(xi, s);
}
}
Hacl_Bignum_Fproduct_carry_wide_(tmp);
b4 = tmp[4U];
b0 = tmp[0U];
b4_ = FStar_UInt128_logand(b4, FStar_UInt128_uint64_to_uint128((uint64_t)0x7ffffffffffffU));
b0_ =
FStar_UInt128_add(b0,
FStar_UInt128_mul_wide((uint64_t)19U,
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b4, (uint32_t)51U))));
tmp[4U] = b4_;
tmp[0U] = b0_;
Hacl_Bignum_Fproduct_copy_from_wide_(output, tmp);
}
}
}
inline static void Hacl_Bignum_fmul(uint64_t *output, uint64_t *a, uint64_t *b)
{
Hacl_Bignum_Fmul_fmul(output, a, b);
}
inline static void Hacl_Bignum_crecip(uint64_t *output, uint64_t *input)
{
Hacl_Bignum_Crecip_crecip(output, input);
}
static void
Hacl_EC_Point_swap_conditional_step(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
{
uint32_t i = ctr - (uint32_t)1U;
uint64_t ai = a[i];
uint64_t bi = b[i];
uint64_t x = swap1 & (ai ^ bi);
uint64_t ai1 = ai ^ x;
uint64_t bi1 = bi ^ x;
a[i] = ai1;
b[i] = bi1;
}
static void
Hacl_EC_Point_swap_conditional_(uint64_t *a, uint64_t *b, uint64_t swap1, uint32_t ctr)
{
if (!(ctr == (uint32_t)0U))
{
uint32_t i;
Hacl_EC_Point_swap_conditional_step(a, b, swap1, ctr);
i = ctr - (uint32_t)1U;
Hacl_EC_Point_swap_conditional_(a, b, swap1, i);
}
}
static void Hacl_EC_Point_swap_conditional(uint64_t *a, uint64_t *b, uint64_t iswap)
{
uint64_t swap1 = (uint64_t)0U - iswap;
Hacl_EC_Point_swap_conditional_(a, b, swap1, (uint32_t)5U);
Hacl_EC_Point_swap_conditional_(a + (uint32_t)5U, b + (uint32_t)5U, swap1, (uint32_t)5U);
}
static void Hacl_EC_Point_copy(uint64_t *output, uint64_t *input)
{
memcpy(output, input, (uint32_t)5U * sizeof input[0U]);
memcpy(output + (uint32_t)5U,
input + (uint32_t)5U,
(uint32_t)5U * sizeof (input + (uint32_t)5U)[0U]);
}
static void Hacl_EC_Format_fexpand(uint64_t *output, uint8_t *input)
{
uint64_t i0 = load64_le(input);
uint8_t *x00 = input + (uint32_t)6U;
uint64_t i1 = load64_le(x00);
uint8_t *x01 = input + (uint32_t)12U;
uint64_t i2 = load64_le(x01);
uint8_t *x02 = input + (uint32_t)19U;
uint64_t i3 = load64_le(x02);
uint8_t *x0 = input + (uint32_t)24U;
uint64_t i4 = load64_le(x0);
uint64_t output0 = i0 & (uint64_t)0x7ffffffffffffU;
uint64_t output1 = i1 >> (uint32_t)3U & (uint64_t)0x7ffffffffffffU;
uint64_t output2 = i2 >> (uint32_t)6U & (uint64_t)0x7ffffffffffffU;
uint64_t output3 = i3 >> (uint32_t)1U & (uint64_t)0x7ffffffffffffU;
uint64_t output4 = i4 >> (uint32_t)12U & (uint64_t)0x7ffffffffffffU;
output[0U] = output0;
output[1U] = output1;
output[2U] = output2;
output[3U] = output3;
output[4U] = output4;
}
static void Hacl_EC_Format_fcontract_first_carry_pass(uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
input[0U] = t0_;
input[1U] = t1__;
input[2U] = t2__;
input[3U] = t3__;
input[4U] = t4_;
}
static void Hacl_EC_Format_fcontract_first_carry_full(uint64_t *input)
{
Hacl_EC_Format_fcontract_first_carry_pass(input);
Hacl_Bignum_Modulo_carry_top(input);
}
static void Hacl_EC_Format_fcontract_second_carry_pass(uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t t1_ = t1 + (t0 >> (uint32_t)51U);
uint64_t t0_ = t0 & (uint64_t)0x7ffffffffffffU;
uint64_t t2_ = t2 + (t1_ >> (uint32_t)51U);
uint64_t t1__ = t1_ & (uint64_t)0x7ffffffffffffU;
uint64_t t3_ = t3 + (t2_ >> (uint32_t)51U);
uint64_t t2__ = t2_ & (uint64_t)0x7ffffffffffffU;
uint64_t t4_ = t4 + (t3_ >> (uint32_t)51U);
uint64_t t3__ = t3_ & (uint64_t)0x7ffffffffffffU;
input[0U] = t0_;
input[1U] = t1__;
input[2U] = t2__;
input[3U] = t3__;
input[4U] = t4_;
}
static void Hacl_EC_Format_fcontract_second_carry_full(uint64_t *input)
{
uint64_t i0;
uint64_t i1;
uint64_t i0_;
uint64_t i1_;
Hacl_EC_Format_fcontract_second_carry_pass(input);
Hacl_Bignum_Modulo_carry_top(input);
i0 = input[0U];
i1 = input[1U];
i0_ = i0 & (uint64_t)0x7ffffffffffffU;
i1_ = i1 + (i0 >> (uint32_t)51U);
input[0U] = i0_;
input[1U] = i1_;
}
static void Hacl_EC_Format_fcontract_trim(uint64_t *input)
{
uint64_t a0 = input[0U];
uint64_t a1 = input[1U];
uint64_t a2 = input[2U];
uint64_t a3 = input[3U];
uint64_t a4 = input[4U];
uint64_t mask0 = FStar_UInt64_gte_mask(a0, (uint64_t)0x7ffffffffffedU);
uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0x7ffffffffffffU);
uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x7ffffffffffffU);
uint64_t mask3 = FStar_UInt64_eq_mask(a3, (uint64_t)0x7ffffffffffffU);
uint64_t mask4 = FStar_UInt64_eq_mask(a4, (uint64_t)0x7ffffffffffffU);
uint64_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4;
uint64_t a0_ = a0 - ((uint64_t)0x7ffffffffffedU & mask);
uint64_t a1_ = a1 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a2_ = a2 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a3_ = a3 - ((uint64_t)0x7ffffffffffffU & mask);
uint64_t a4_ = a4 - ((uint64_t)0x7ffffffffffffU & mask);
input[0U] = a0_;
input[1U] = a1_;
input[2U] = a2_;
input[3U] = a3_;
input[4U] = a4_;
}
static void Hacl_EC_Format_fcontract_store(uint8_t *output, uint64_t *input)
{
uint64_t t0 = input[0U];
uint64_t t1 = input[1U];
uint64_t t2 = input[2U];
uint64_t t3 = input[3U];
uint64_t t4 = input[4U];
uint64_t o0 = t1 << (uint32_t)51U | t0;
uint64_t o1 = t2 << (uint32_t)38U | t1 >> (uint32_t)13U;
uint64_t o2 = t3 << (uint32_t)25U | t2 >> (uint32_t)26U;
uint64_t o3 = t4 << (uint32_t)12U | t3 >> (uint32_t)39U;
uint8_t *b0 = output;
uint8_t *b1 = output + (uint32_t)8U;
uint8_t *b2 = output + (uint32_t)16U;
uint8_t *b3 = output + (uint32_t)24U;
store64_le(b0, o0);
store64_le(b1, o1);
store64_le(b2, o2);
store64_le(b3, o3);
}
static void Hacl_EC_Format_fcontract(uint8_t *output, uint64_t *input)
{
Hacl_EC_Format_fcontract_first_carry_full(input);
Hacl_EC_Format_fcontract_second_carry_full(input);
Hacl_EC_Format_fcontract_trim(input);
Hacl_EC_Format_fcontract_store(output, input);
}
static void Hacl_EC_Format_scalar_of_point(uint8_t *scalar, uint64_t *point)
{
uint64_t *x = point;
uint64_t *z = point + (uint32_t)5U;
uint64_t buf[10U] = { 0U };
uint64_t *zmone = buf;
uint64_t *sc = buf + (uint32_t)5U;
Hacl_Bignum_crecip(zmone, z);
Hacl_Bignum_fmul(sc, x, zmone);
Hacl_EC_Format_fcontract(scalar, sc);
}
static void
Hacl_EC_AddAndDouble_fmonty(
uint64_t *pp,
uint64_t *ppq,
uint64_t *p,
uint64_t *pq,
uint64_t *qmqp
)
{
uint64_t *qx = qmqp;
uint64_t *x2 = pp;
uint64_t *z2 = pp + (uint32_t)5U;
uint64_t *x3 = ppq;
uint64_t *z3 = ppq + (uint32_t)5U;
uint64_t *x = p;
uint64_t *z = p + (uint32_t)5U;
uint64_t *xprime = pq;
uint64_t *zprime = pq + (uint32_t)5U;
uint64_t buf[40U] = { 0U };
uint64_t *origx = buf;
uint64_t *origxprime0 = buf + (uint32_t)5U;
uint64_t *xxprime0 = buf + (uint32_t)25U;
uint64_t *zzprime0 = buf + (uint32_t)30U;
uint64_t *origxprime;
uint64_t *xx0;
uint64_t *zz0;
uint64_t *xxprime;
uint64_t *zzprime;
uint64_t *zzzprime;
uint64_t *zzz;
uint64_t *xx;
uint64_t *zz;
uint64_t scalar;
memcpy(origx, x, (uint32_t)5U * sizeof x[0U]);
Hacl_Bignum_fsum(x, z);
Hacl_Bignum_fdifference(z, origx);
memcpy(origxprime0, xprime, (uint32_t)5U * sizeof xprime[0U]);
Hacl_Bignum_fsum(xprime, zprime);
Hacl_Bignum_fdifference(zprime, origxprime0);
Hacl_Bignum_fmul(xxprime0, xprime, z);
Hacl_Bignum_fmul(zzprime0, x, zprime);
origxprime = buf + (uint32_t)5U;
xx0 = buf + (uint32_t)15U;
zz0 = buf + (uint32_t)20U;
xxprime = buf + (uint32_t)25U;
zzprime = buf + (uint32_t)30U;
zzzprime = buf + (uint32_t)35U;
memcpy(origxprime, xxprime, (uint32_t)5U * sizeof xxprime[0U]);
Hacl_Bignum_fsum(xxprime, zzprime);
Hacl_Bignum_fdifference(zzprime, origxprime);
Hacl_Bignum_Fsquare_fsquare_times(x3, xxprime, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(zzzprime, zzprime, (uint32_t)1U);
Hacl_Bignum_fmul(z3, zzzprime, qx);
Hacl_Bignum_Fsquare_fsquare_times(xx0, x, (uint32_t)1U);
Hacl_Bignum_Fsquare_fsquare_times(zz0, z, (uint32_t)1U);
zzz = buf + (uint32_t)10U;
xx = buf + (uint32_t)15U;
zz = buf + (uint32_t)20U;
Hacl_Bignum_fmul(x2, xx, zz);
Hacl_Bignum_fdifference(zz, xx);
scalar = (uint64_t)121665U;
Hacl_Bignum_fscalar(zzz, zz, scalar);
Hacl_Bignum_fsum(zzz, xx);
Hacl_Bignum_fmul(z2, zzz, zz);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt
)
{
uint64_t bit0 = (uint64_t)(byt >> (uint32_t)7U);
uint64_t bit;
Hacl_EC_Point_swap_conditional(nq, nqpq, bit0);
Hacl_EC_AddAndDouble_fmonty(nq2, nqpq2, nq, nqpq, q);
bit = (uint64_t)(byt >> (uint32_t)7U);
Hacl_EC_Point_swap_conditional(nq2, nqpq2, bit);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt
)
{
uint8_t byt1;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq, nqpq, nq2, nqpq2, q, byt);
byt1 = byt << (uint32_t)1U;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_step(nq2, nqpq2, nq, nqpq, q, byt1);
}
static void
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint8_t byt,
uint32_t i
)
{
if (!(i == (uint32_t)0U))
{
uint32_t i_ = i - (uint32_t)1U;
uint8_t byt_;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop_double_step(nq, nqpq, nq2, nqpq2, q, byt);
byt_ = byt << (uint32_t)2U;
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byt_, i_);
}
}
static void
Hacl_EC_Ladder_BigLoop_cmult_big_loop(
uint8_t *n1,
uint64_t *nq,
uint64_t *nqpq,
uint64_t *nq2,
uint64_t *nqpq2,
uint64_t *q,
uint32_t i
)
{
if (!(i == (uint32_t)0U))
{
uint32_t i1 = i - (uint32_t)1U;
uint8_t byte = n1[i1];
Hacl_EC_Ladder_SmallLoop_cmult_small_loop(nq, nqpq, nq2, nqpq2, q, byte, (uint32_t)4U);
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, i1);
}
}
static void Hacl_EC_Ladder_cmult(uint64_t *result, uint8_t *n1, uint64_t *q)
{
uint64_t point_buf[40U] = { 0U };
uint64_t *nq = point_buf;
uint64_t *nqpq = point_buf + (uint32_t)10U;
uint64_t *nq2 = point_buf + (uint32_t)20U;
uint64_t *nqpq2 = point_buf + (uint32_t)30U;
Hacl_EC_Point_copy(nqpq, q);
nq[0U] = (uint64_t)1U;
Hacl_EC_Ladder_BigLoop_cmult_big_loop(n1, nq, nqpq, nq2, nqpq2, q, (uint32_t)32U);
Hacl_EC_Point_copy(result, nq);
}
void Hacl_Curve25519_crypto_scalarmult(uint8_t *mypublic, uint8_t *secret, uint8_t *basepoint)
{
uint64_t buf0[10U] = { 0U };
uint64_t *x0 = buf0;
uint64_t *z = buf0 + (uint32_t)5U;
uint64_t *q;
Hacl_EC_Format_fexpand(x0, basepoint);
z[0U] = (uint64_t)1U;
q = buf0;
{
uint8_t e[32U] = { 0U };
uint8_t e0;
uint8_t e31;
uint8_t e01;
uint8_t e311;
uint8_t e312;
uint8_t *scalar;
memcpy(e, secret, (uint32_t)32U * sizeof secret[0U]);
e0 = e[0U];
e31 = e[31U];
e01 = e0 & (uint8_t)248U;
e311 = e31 & (uint8_t)127U;
e312 = e311 | (uint8_t)64U;
e[0U] = e01;
e[31U] = e312;
scalar = e;
{
uint64_t buf[15U] = { 0U };
uint64_t *nq = buf;
uint64_t *x = nq;
x[0U] = (uint64_t)1U;
Hacl_EC_Ladder_cmult(nq, scalar, q);
Hacl_EC_Format_scalar_of_point(mypublic, nq);
}
}
}

190
3rdparty/everest/library/x25519.c vendored Normal file
View File

@ -0,0 +1,190 @@
/*
* ECDH with curve-optimized implementation multiplexing
*
* Copyright 2016-2018 INRIA and Microsoft Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
#include <mbedtls/ecdh.h>
#if !(defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16))
#define KRML_VERIFIED_UINT128
#endif
#include <Hacl_Curve25519.h>
#include <mbedtls/platform_util.h>
#include "x25519.h"
#include <string.h>
/*
* Initialize context
*/
void mbedtls_x25519_init( mbedtls_x25519_context *ctx )
{
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x25519_context ) );
}
/*
* Free context
*/
void mbedtls_x25519_free( mbedtls_x25519_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
mbedtls_platform_zeroize( ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
}
int mbedtls_x25519_make_params( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng )
{
int ret = 0;
uint8_t base[MBEDTLS_X25519_KEY_SIZE_BYTES] = {0};
if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
return ret;
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 4;
if( blen < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
*buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 >> 8;
*buf++ = MBEDTLS_ECP_TLS_CURVE25519 & 0xFF;
*buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
base[0] = 9;
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
base[0] = 0;
if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( 0 );
}
int mbedtls_x25519_read_params( mbedtls_x25519_context *ctx,
const unsigned char **buf, const unsigned char *end )
{
if( end - *buf < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( *(*buf)++ != MBEDTLS_X25519_KEY_SIZE_BYTES ) )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
memcpy( ctx->peer_point, *buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
*buf += MBEDTLS_X25519_KEY_SIZE_BYTES;
return( 0 );
}
int mbedtls_x25519_get_params( mbedtls_x25519_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_x25519_ecdh_side side )
{
size_t olen = 0;
switch( side ) {
case MBEDTLS_X25519_ECDH_THEIRS:
return mbedtls_ecp_point_write_binary( &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED, &olen, ctx->peer_point, MBEDTLS_X25519_KEY_SIZE_BYTES );
case MBEDTLS_X25519_ECDH_OURS:
return mbedtls_mpi_write_binary_le( &key->d, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
default:
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
}
int mbedtls_x25519_calc_secret( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng )
{
/* f_rng and p_rng are not used here because this implementation does not
need blinding since it has constant trace. */
(( void )f_rng);
(( void )p_rng);
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES;
if( blen < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, ctx->peer_point);
/* Wipe the DH secret and don't let the peer chose a small subgroup point */
mbedtls_platform_zeroize( ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES );
if( memcmp( buf, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES) == 0 )
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( 0 );
}
int mbedtls_x25519_make_public( mbedtls_x25519_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int( *f_rng )(void *, unsigned char *, size_t),
void *p_rng )
{
int ret = 0;
unsigned char base[MBEDTLS_X25519_KEY_SIZE_BYTES] = { 0 };
if( ctx == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = f_rng( p_rng, ctx->our_secret, MBEDTLS_X25519_KEY_SIZE_BYTES ) ) != 0 )
return ret;
*olen = MBEDTLS_X25519_KEY_SIZE_BYTES + 1;
if( blen < *olen )
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
*buf++ = MBEDTLS_X25519_KEY_SIZE_BYTES;
base[0] = 9;
Hacl_Curve25519_crypto_scalarmult( buf, ctx->our_secret, base );
base[0] = 0;
if( memcmp( buf, base, MBEDTLS_X25519_KEY_SIZE_BYTES ) == 0 )
return MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( ret );
}
int mbedtls_x25519_read_public( mbedtls_x25519_context *ctx,
const unsigned char *buf, size_t blen )
{
if( blen < MBEDTLS_X25519_KEY_SIZE_BYTES + 1 )
return(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL);
if( (*buf++ != MBEDTLS_X25519_KEY_SIZE_BYTES) )
return(MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
memcpy( ctx->peer_point, buf, MBEDTLS_X25519_KEY_SIZE_BYTES );
return( 0 );
}
#endif /* MBEDTLS_ECDH_C && MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED */

View File

@ -5,6 +5,7 @@ else()
project("mbed TLS" C)
endif()
# Set the project root directory.
set(MBEDTLS_DIR ${CMAKE_CURRENT_SOURCE_DIR})
option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF)
@ -14,9 +15,6 @@ option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
# export the submodule flag so that crypto knows it's being built as a submodule
set( USE_CRYPTO_SUBMODULE ON )
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}")
@ -142,8 +140,8 @@ if(CMAKE_COMPILER_IS_GNU)
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 -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -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_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
endif(CMAKE_COMPILER_IS_GNU)
@ -154,7 +152,7 @@ if(CMAKE_COMPILER_IS_CLANG)
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=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_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")
@ -181,6 +179,9 @@ else()
set(LIB_INSTALL_DIR lib)
endif()
include_directories(include/)
include_directories(library/)
if(ENABLE_ZLIB_SUPPORT)
find_package(ZLIB)
@ -189,15 +190,14 @@ if(ENABLE_ZLIB_SUPPORT)
endif(ZLIB_FOUND)
endif(ENABLE_ZLIB_SUPPORT)
add_subdirectory(crypto/3rdparty)
add_subdirectory(include)
add_subdirectory(3rdparty)
include_directories(${thirdparty_inc})
list(APPEND libs ${thirdparty_lib})
add_definitions(${thirdparty_def})
add_subdirectory(library)
add_subdirectory(include)
add_subdirectory(crypto/library)
add_subdirectory(crypto/include)
if(ENABLE_PROGRAMS)
add_subdirectory(programs)
@ -211,7 +211,6 @@ if(ENABLE_TESTING)
enable_testing()
add_subdirectory(tests)
add_subdirectory(crypto/tests)
# additional convenience targets for Unix only
if(UNIX)

View File

@ -1,5 +1,3 @@
# export the submodule flag so that crypto knows it's being built as a submodule
export USE_CRYPTO_SUBMODULE=1
DESTDIR=/usr/local
PREFIX=mbedtls_
@ -20,20 +18,18 @@ lib:
tests: lib
$(MAKE) -C tests
$(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C crypto/tests
ifndef WINDOWS
install: no_test
mkdir -p $(DESTDIR)/include/mbedtls
cp -rp include/mbedtls $(DESTDIR)/include
mkdir -p $(DESTDIR)/include/psa
cp -rp include/psa $(DESTDIR)/include
mkdir -p $(DESTDIR)/lib
cp -RP library/libmbedtls.* $(DESTDIR)/lib
cp -RP library/libmbedx509.* $(DESTDIR)/lib
mkdir -p $(DESTDIR)/include/psa
cp -rp crypto/include/psa $(DESTDIR)/include
cp -RP crypto/library/libmbedcrypto.* $(DESTDIR)/lib
cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
mkdir -p $(DESTDIR)/bin
for p in programs/*/* ; do \
@ -49,8 +45,6 @@ uninstall:
rm -f $(DESTDIR)/lib/libmbedtls.*
rm -f $(DESTDIR)/lib/libmbedx509.*
rm -f $(DESTDIR)/lib/libmbedcrypto.*
$(MAKE) -C crypto uninstall
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
@ -92,14 +86,12 @@ clean:
$(MAKE) -C library clean
$(MAKE) -C programs clean
$(MAKE) -C tests clean
$(MAKE) -C crypto clean
ifndef WINDOWS
find . \( -name \*.gcno -o -name \*.gcda -o -name \*.info \) -exec rm {} +
endif
check: lib tests
$(MAKE) -C tests check
$(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C crypto/tests check
test: check

3377
configs/config-default.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,6 @@
/* Miscellaneous options */
#define MBEDTLS_AES_ROM_TABLES
#include "check_config.h"
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

3373
configs/config-psa-crypto.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
/**
* \file config-symmetric-only.h
*
* \brief Configuration without any asymmetric cryptography.
*/
/*
* Copyright (C) 2019, 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_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
//#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_HAVE_TIME_DATE
/* Mbed Crypto feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_CIPHER_MODE_CFB
#define MBEDTLS_CIPHER_MODE_CTR
#define MBEDTLS_CIPHER_MODE_OFB
#define MBEDTLS_CIPHER_MODE_XTS
#define MBEDTLS_CIPHER_PADDING_PKCS7
#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
#define MBEDTLS_CIPHER_PADDING_ZEROS
#define MBEDTLS_ERROR_STRERROR_DUMMY
#define MBEDTLS_FS_IO
#define MBEDTLS_ENTROPY_NV_SEED
#define MBEDTLS_SELF_TEST
#define MBEDTLS_USE_PSA_CRYPTO
#define MBEDTLS_VERSION_FEATURES
/* Mbed Crypto modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ARC4_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_BLOWFISH_C
#define MBEDTLS_CAMELLIA_C
#define MBEDTLS_ARIA_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CHACHA20_C
#define MBEDTLS_CHACHAPOLY_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CMAC_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_DES_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_ERROR_C
#define MBEDTLS_GCM_C
//#define MBEDTLS_HAVEGE_C
#define MBEDTLS_HKDF_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_NIST_KW_C
#define MBEDTLS_MD_C
#define MBEDTLS_MD2_C
#define MBEDTLS_MD4_C
#define MBEDTLS_MD5_C
#define MBEDTLS_OID_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_PEM_WRITE_C
#define MBEDTLS_PKCS5_C
#define MBEDTLS_PKCS12_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_POLY1305_C
#define MBEDTLS_PSA_CRYPTO_C
#define MBEDTLS_PSA_CRYPTO_SE_C
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
#define MBEDTLS_PSA_ITS_FILE_C
#define MBEDTLS_RIPEMD160_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
//#define MBEDTLS_THREADING_C
#define MBEDTLS_TIMING_C
#define MBEDTLS_VERSION_C
#define MBEDTLS_XTEA_C
#include "check_config.h"
#endif /* MBEDTLS_CONFIG_H */

Binary file not shown.

View File

@ -3,6 +3,8 @@ PANDOC = pandoc
default: all
all_markdown = \
mbed-crypto-storage-specification.md \
testing/driver-interface-test-strategy.md \
testing/test-framework.md \
# This line is intentionally left blank
@ -17,3 +19,6 @@ all: html pdf
$(PANDOC) -o $@ $<
.md.pdf:
$(PANDOC) -o $@ $<
clean:
rm -f *.html *.pdf

View File

@ -0,0 +1,284 @@
Mbed Crypto storage specification
=================================
This document specifies how Mbed Crypto uses storage.
Mbed Crypto may be upgraded on an existing device with the storage preserved. Therefore:
1. Any change may break existing installations and may require an upgrade path.
1. This document retains historical information about all past released versions. Do not remove information from this document unless it has always been incorrect or it is about a version that you are sure was never released.
Mbed Crypto 0.1.0
-----------------
Tags: mbedcrypto-0.1.0b, mbedcrypto-0.1.0b2
Released in November 2018. <br>
Integrated in Mbed OS 5.11.
Supported backends:
* [PSA ITS](#file-namespace-on-its-for-0.1.0)
* [C stdio](#file-namespace-on-stdio-for-0.1.0)
Supported features:
* [Persistent transparent keys](#key-file-format-for-0.1.0) designated by a [slot number](#key-names-for-0.1.0).
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0) on ITS only.
This is a beta release, and we do not promise backward compatibility, with one exception:
> On Mbed OS, if a device has a nonvolatile random seed file produced with Mbed OS 5.11.x and is upgraded to a later version of Mbed OS, the nonvolatile random seed file is preserved or upgraded.
We do not make any promises regarding key storage, or regarding the nonvolatile random seed file on other platforms.
### Key names for 0.1.0
Information about each key is stored in a dedicated file whose name is constructed from the key identifier. The way in which the file name is constructed depends on the storage backend. The content of the file is described [below](#key-file-format-for-0.1.0).
The valid values for a key identifier are the range from 1 to 0xfffeffff. This limitation on the range is not documented in user-facing documentation: according to the user-facing documentation, arbitrary 32-bit values are valid.
The code uses the following constant in an internal header (note that despite the name, this value is actually one plus the maximum permitted value):
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
There is a shared namespace for all callers.
### Key file format for 0.1.0
All integers are encoded in little-endian order in 8-bit bytes.
The layout of a key file is:
* magic (8 bytes): `"PSA\0KEY\0"`
* version (4 bytes): 0
* type (4 bytes): `psa_key_type_t` value
* policy usage flags (4 bytes): `psa_key_usage_t` value
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
* key material length (4 bytes)
* key material: output of `psa_export_key`
* Any trailing data is rejected on load.
### Nonvolatile random seed file format for 0.1.0
The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
The file format is just the seed as a byte string with no metadata or encoding of any kind.
### File namespace on ITS for 0.1.0
Assumption: ITS provides a 32-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
* File 0: unused.
* Files 1 through 0xfffeffff: [content](#key-file-format-for-0.1.0) of the [key whose identifier is the file identifier](#key-names-for-0.1.0).
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff: unused.
### File namespace on stdio for 0.1.0
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
An undocumented build-time configuration value `CRYPTO_STORAGE_FILE_LOCATION` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
* `CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
* `sprintf(CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu", key_id)` [content](#key-file-format-for-0.1.0) of the [key whose identifier](#key-names-for-0.1.0) is `key_id`.
* Other files: unused.
Mbed Crypto 1.0.0
-----------------
Tags: mbedcrypto-1.0.0d4, mbedcrypto-1.0.0
Released in February 2019. <br>
Integrated in Mbed OS 5.12.
Supported integrations:
* [PSA platform](#file-namespace-on-a-psa-platform-for-1.0.0)
* [library using PSA ITS](#file-namespace-on-its-as-a-library-for-1.0.0)
* [library using C stdio](#file-namespace-on-stdio-for-1.0.0)
Supported features:
* [Persistent transparent keys](#key-file-format-for-1.0.0) designated by a [key identifier and owner](#key-names-for-1.0.0).
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0) on ITS only.
Backward compatibility commitments: TBD
### Key names for 1.0.0
Information about each key is stored in a dedicated file designated by a _key file identifier_ (`psa_key_file_id_t`). The key file identifier is constructed from the 32-bit key identifier (`psa_key_id_t`) and, if applicable, an identifier of the owner of the key. In integrations where there is no concept of key owner (in particular, in library integrations), the key file identifier is exactly the key identifier. When the library is integrated into a service, the service determines the semantics of the owner identifier.
The way in which the file name is constructed from the key file identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-1.0.0).
The valid values for a key identifier are the range from 1 to 0xfffeffff. This limitation on the range is not documented in user-facing documentation: according to the user-facing documentation, arbitrary 32-bit values are valid.
* Library integration: the key file name is just the key identifer. This is a 32-bit value.
* PSA service integration: the key file identifier is `(uint32_t)owner_uid << 32 | key_id` where `key_id` is the key identifier specified by the application and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
### Key file format for 1.0.0
The layout is identical to [0.1.0](#key-file-format-for-0.1.0) so far. However note that the encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
### Nonvolatile random seed file format for 1.0.0
[Identical to 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
### File namespace on a PSA platform for 1.0.0
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
Assumption: the owner identifier is a nonzero value of type `int32_t`.
* Files 0 through 0xffffff51, 0xffffff53 through 0xffffffff: unused, reserved for internal use of the crypto library or crypto service.
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
### File namespace on ITS as a library for 1.0.0
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
* File 0: unused.
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff, 0x100000000 through 0xffffffffffffffff: unused.
### File namespace on stdio for 1.0.0
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
[Identical to 0.1.0](#file-namespace-on-stdio-for-0.1.0).
### Upgrade from 0.1.0 to 1.0.0.
* Delete files 1 through 0xfffeffff, which contain keys in a format that is no longer supported.
### Suggested changes to make before 1.0.0
The library integration and the PSA platform integration use different sets of file names. This is annoyingly non-uniform. For example, if we want to store non-key files, we have room in different ranges (0 through 0xffffffff on a PSA platform, 0xffff0000 through 0xffffffffffffffff in a library integration).
It would simplify things to always have a 32-bit owner, with a nonzero value, and thus reserve the range 00xffffffff for internal library use.
Mbed Crypto 1.1.0
-----------------
Tags: mbedcrypto-1.1.0
Released in early June 2019. <br>
Integrated in Mbed OS 5.13.
Identical to [1.0.0](#mbed-crypto-1.0.0) except for some changes in the key file format.
### Key file format for 1.1.0
The key file format is identical to [1.0.0](#key-file-format-for-1.0.0), except for the following changes:
* A new policy field, marked as [NEW:1.1.0] below.
* The encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
A self-contained description of the file layout follows.
All integers are encoded in little-endian order in 8-bit bytes.
The layout of a key file is:
* magic (8 bytes): `"PSA\0KEY\0"`
* version (4 bytes): 0
* type (4 bytes): `psa_key_type_t` value
* policy usage flags (4 bytes): `psa_key_usage_t` value
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value [NEW:1.1.0]
* key material length (4 bytes)
* key material: output of `psa_export_key`
* Any trailing data is rejected on load.
Mbed Crypto TBD
---------------
Tags: TBD
Released in TBD 2019. <br>
Integrated in Mbed OS TBD.
### Changes introduced in TBD
* The layout of a key file now has a lifetime field before the type field.
* Key files can store references to keys in a secure element. In such key files, the key material contains the slot number.
### File namespace on a PSA platform on TBD
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
Assumption: the owner identifier is a nonzero value of type `int32_t`.
* Files 0 through 0xfffeffff: unused.
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
### File namespace on ITS as a library on TBD
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
* File 0: unused.
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
* Files 0x100000000 through 0xffffffffffffffff: unused.
### Non-key files on TBD
File identifiers in the range 0xffff0000 through 0xffffffff are reserved for internal use in Mbed Crypto.
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): secure element driver storage. The content of the file is the secure element driver's persistent data.
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-tbd).
* Other files are unused and reserved for future use.
### Key file format for TBD
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
The layout of a key file is:
* magic (8 bytes): `"PSA\0KEY\0"`.
* version (4 bytes): 0.
* lifetime (4 bytes): `psa_key_lifetime_t` value.
* type (4 bytes): `psa_key_type_t` value.
* policy usage flags (4 bytes): `psa_key_usage_t` value.
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
* key material length (4 bytes).
* key material:
* For a transparent key: output of `psa_export_key`.
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
* Any trailing data is rejected on load.
### Transaction file format for TBD
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
All integers are encoded in platform endianness.
All currently existing transactions concern a key in a secure element.
The layout of a transaction file is:
* type (2 bytes): the [transaction type](#transaction-types-on-tbd).
* unused (2 bytes)
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-tbd)).
#### Transaction types on TBD
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
* The slot in the secure element designated by the slot number.
* The file containing the key metadata designated by the key identifier.
* The driver persistent data.
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
* The slot in the secure element designated by the slot number.
* The file containing the key metadata designated by the key identifier.
* The driver persistent data.

View File

@ -0,0 +1,115 @@
# Mbed Crypto driver interface test strategy
This document describes the test strategy for the driver interfaces in Mbed Crypto. Mbed Crypto has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed Crypto itself; testing drivers is out of scope.
The driver interfaces are standardized through PSA Cryptography functional specifications.
## Secure element driver interface
The secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed Crypto and one or more third-party drivers.
The SE interface consists of one function provided by Mbed Crypto (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed Crypto, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
### SE driver interface unit tests
This section describes unit tests that must be implemented to validate the secure element driver interface. Note that a test case may cover multiple requirements; for example a “good case” test can validate that the proper function is called, that it receives the expected inputs and that it produces the expected outputs.
Many SE driver interface unit tests could be covered by running the existing API tests with a key in a secure element.
#### SE driver registration
* Test `psa_register_se_driver` with valid and with invalid arguments.
* Make at least one failing call to `psa_register_se_driver` followed by a successful call.
* Make at least one test that successfully registers the maximum number of drivers and fails to register one more.
#### Dispatch to SE driver
For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
* Make at least one test with a key in a secure element that checks that the driver method is called. A few API functions involve multiple driver methods; these should validate that all the expected driver methods are called.
* Make at least one test with a key that is not in a secure element that checks that the driver method is not called.
* Make at least one test with a key in a secure element with a driver that does not have the requisite method (i.e. the method pointer is `NULL`) but has the substructure containing that method, and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
* Make at least one test with a key in a secure element with a driver that does not have the substructure containing that method (i.e. the pointer to the substructure is `NULL`), and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
* At least one test should register multiple drivers with a key in each driver and check that the expected driver is called. This does not need to be done for all operations (use a white-box approach to determine if operations may use different code paths to choose the driver).
* At least one test should register the same driver structure with multiple lifetime values and check that the driver receives the expected lifetime value.
Some methods only make sense as a group (for example a driver that provides the MAC methods must provide all or none). In those cases, test with all of them null and none of them null.
#### SE driver inputs
For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
* Wherever the specification guarantees parameters that satisfy certain preconditions, check these preconditions whenever practical.
* If the API function can take parameters that are invalid and must not reach the driver, call the API function with such parameters and verify that the driver method is not called.
* Check that the expected inputs reach the driver. This may be implicit in a test that checks the outputs if the only realistic way to obtain the correct outputs is to start from the expected inputs (as is often the case for cryptographic material, but not for metadata).
#### SE driver outputs
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed Crypto handles the outputs.
* Correct outputs.
* Incorrect outputs such as an invalid output length.
* Expected errors (e.g. `PSA_ERROR_INVALID_SIGNATURE` from a signature verification method).
* Unexpected errors. At least test that if the driver returns `PSA_ERROR_GENERIC_ERROR`, this is propagated correctly.
Key creation functions invoke multiple methods and need more complex error handling:
* Check the consequence of errors detected at each stage (slot number allocation or validation, key creation method, storage accesses).
* Check that the storage ends up in the expected state. At least make sure that no intermediate file remains after a failure.
#### Persistence of SE keys
The following tests must be performed at least one for each key creation method (import, generate, ...).
* Test that keys in a secure element survive `psa_close_key(); psa_open_key()`.
* Test that keys in a secure element survive `mbedtls_psa_crypto_free(); psa_crypto_init()`.
* Test that the driver's persistent data survives `mbedtls_psa_crypto_free(); psa_crypto_init()`.
* Test that `psa_destroy_key()` does not leave any trace of the key.
#### Resilience for SE drivers
Creating or removing a key in a secure element involves multiple storage modifications (M<sub>1</sub>, ..., M<sub>n</sub>). If the operation is interrupted by a reset at any point, it must be either rolled back or completed.
* For each potential interruption point (before M<sub>1</sub>, between M<sub>1</sub> and M<sub>2</sub>, ..., after M<sub>n</sub>), call `mbedtls_psa_crypto_free(); psa_crypto_init()` at that point and check that this either rolls back or completes the operation that was started.
* This must be done for each key creation method and for key destruction.
* This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`).
* The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too.
* Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage.
* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERRROR_DOES_NOT_EXIST`).
This requires instrumenting the storage implementation, either to force it to fail at each point or to record successive storage states and replay each of them. Each `psa_its_xxx` function call is assumed to be atomic.
### SE driver system tests
#### Real-world use case
We must have at least one driver that is close to real-world conditions:
* With its own source tree.
* Running on actual hardware.
* Run the full driver validation test suite (which does not yet exist).
* Run at least one test application (e.g. the Mbed OS TLS example).
This requirement shall be fulfilled by the [Microchip ATECC508A driver](https://github.com/ARMmbed/mbed-os-atecc608a/).
#### Complete driver
We should have at least one driver that covers the whole interface:
* With its own source tree.
* Implementing all the methods.
* Run the full driver validation test suite (which does not yet exist).
A PKCS#11 driver would be a good candidate. It would be useful as part of our product offering.
## Accelerator driver interface
The accelerator driver interface is defined by [`psa/crypto_accel_driver.h`](../../../include/psa/crypto_accel_driver.h).
TODO
## Entropy driver interface
The entropy driver interface is defined by [`psa/crypto_entropy_driver.h`](../../../include/psa/crypto_entropy_driver.h).
TODO

894
docs/getting_started.md Normal file
View File

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

View File

@ -664,7 +664,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../include ../crypto/include 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,12 +696,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = \
../crypto/include/mbedtls/check_config.h \
../crypto/include/mbedtls/compat-1.3.h \
../crypto/include/mbedtls/config.h \
../crypto/include/mbedtls/error.h \
../crypto/include/mbedtls/version.h \
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

@ -1,22 +1,22 @@
option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON)
# Declare include headers as PUBLIC to propogate to project consumers
target_include_directories(
mbedtls
PUBLIC ${CMAKE_CURRENT_LIST_DIR}
)
if(INSTALL_MBEDTLS_HEADERS)
file(GLOB headers "mbedtls/*.h")
file(GLOB psa_headers "psa/*.h")
install(FILES ${headers}
DESTINATION include/mbedtls
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
install(FILES ${psa_headers}
DESTINATION include/psa
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 (ENABLE_TESTING AND NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
link_to_source(mbedtls)
link_to_source(psa)
endif()

674
include/mbedtls/aes.h Normal file
View File

@ -0,0 +1,674 @@
/**
* \file aes.h
*
* \brief This file contains AES definitions and functions.
*
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
* cryptographic algorithm that can be used to protect electronic
* data.
*
* The AES algorithm is a symmetric block cipher that can
* encrypt and decrypt information. For more information, see
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
* <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.
* 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_AES_H
#define MBEDTLS_AES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* padlock.c and aesni.c rely on these values! */
#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
/* Error codes in range 0x0020-0x0022 */
#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 0x0021-0x0025 */
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */
/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available. For example, an unsupported AES key size. */
/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 /**< AES hardware accelerator failed. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_AES_ALT)
// Regular implementation
//
/**
* \brief The AES context-type definition.
*/
typedef struct mbedtls_aes_context
{
int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys. */
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
one of the following purposes:
<ul><li>Alignment if VIA padlock is
used.</li>
<li>Simplifying key expansion in the 256-bit
case by generating an extra round key.
</li></ul> */
}
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 */
/**
* \brief This function initializes the specified AES context.
*
* It must be the first API called before using
* the context.
*
* \param ctx The AES context to initialize. This must not be \c NULL.
*/
void mbedtls_aes_init( mbedtls_aes_context *ctx );
/**
* \brief This function releases and clears the specified AES context.
*
* \param ctx The AES context to clear.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
#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. This must not be \c NULL.
*/
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.
* If this is \c NULL, this function does nothing.
* Otherwise, the context must have been at least initialized.
*/
void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/**
* \brief This function sets the encryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The encryption key.
* This must be a readable buffer of size \p keybits bits.
* \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.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief This function sets the decryption key.
*
* \param ctx The AES context to which the key should be bound.
* It must be initialized.
* \param key The decryption key.
* This must be a readable buffer of size \p keybits bits.
* \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.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
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.
* It must be initialized.
* \param key The encryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \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.
* It must be initialized.
* \param key The decryption key. This is comprised of the XTS key1
* concatenated with the XTS key2.
* This must be a readable buffer of size \p keybits bits.
* \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.
*
* It performs the operation defined in the \p mode parameter
* (encrypt or decrypt), on the input data buffer defined in
* the \p input parameter.
*
* mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
* mbedtls_aes_setkey_dec() must be called before the first
* call to this API with the same context.
*
* \param ctx The AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param input The buffer holding the input data.
* It must be readable and at least \c 16 Bytes long.
* \param output The buffer where the output data will be written.
* It must be writeable and at least \c 16 Bytes long.
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief This function performs an AES-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_aes_init(), and either
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
* before the first call to this API with the same context.
*
* \note This function operates on full blocks, that is, the input size
* must be a multiple of the AES block size of \c 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 AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes. This must be a
* multiple of the block size (\c 16 Bytes).
* \param iv Initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* on failure.
*/
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \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.
* It must be initialized and bound to a key.
* \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
* 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_aes_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 AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT.
* \param length The length of the input data in Bytes.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief This function performs an AES-CFB8 encryption or decryption
* operation.
*
* It 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 CFB, you must use the same key schedule for
* both encryption and decryption operations. Therefore, you must
* use the context initialized with mbedtls_aes_setkey_enc() for
* both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
*
* \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 AES context to use for encryption or decryption.
* It must be initialized and bound to a key.
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
* #MBEDTLS_AES_DECRYPT
* \param length The length of the input data.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/**
* \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.
* It must be initialized and bound to a key.
* \param length The length of the input data.
* \param iv_off The offset in IV (updated after use).
* It must point to a valid \c size_t.
* \param iv The initialization vector (updated after use).
* It must be a readable and writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \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
* 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_aes_setkey_enc()
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_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 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.
* It must be initialized and bound to a key.
* \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.
* It must point to a valid \c size_t.
* \param nonce_counter The 128-bit nonce and counter.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param stream_block The saved stream block for resuming. This is
* overwritten by the function.
* It must be a readable-writeable buffer of \c 16 Bytes.
* \param input The buffer holding the input data.
* It must be readable and of size \p length Bytes.
* \param output The buffer holding the output data.
* It must be writeable and of size \p length Bytes.
*
* \return \c 0 on success.
*/
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
/**
* \brief Internal AES block encryption function. This is only
* exposed to allow overriding it using
* \c MBEDTLS_AES_ENCRYPT_ALT.
*
* \param ctx The AES context to use for encryption.
* \param input The plaintext block.
* \param output The output (ciphertext) block.
*
* \return \c 0 on success.
*/
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal AES block decryption function. This is only
* exposed to allow overriding it using see
* \c MBEDTLS_AES_DECRYPT_ALT.
*
* \param ctx The AES context to use for decryption.
* \param input The ciphertext block.
* \param output The output (plaintext) block.
*
* \return \c 0 on success.
*/
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Deprecated internal AES block encryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_encrypt()
*
* \param ctx The AES context to use for encryption.
* \param input Plaintext block.
* \param output Output (ciphertext) block.
*/
MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Deprecated internal AES block decryption function
* without return value.
*
* \deprecated Superseded by mbedtls_internal_aes_decrypt()
*
* \param ctx The AES context to use for decryption.
* \param input Ciphertext block.
* \param output Output (plaintext) block.
*/
MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_aes_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

138
include/mbedtls/aesni.h Normal file
View File

@ -0,0 +1,138 @@
/**
* \file aesni.h
*
* \brief AES-NI for hardware AES acceleration on some Intel processors
*
* \warning These functions are only for internal use by other library
* functions; you must not call them directly.
*/
/*
* Copyright (C) 2006-2015, 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_AESNI_H
#define MBEDTLS_AESNI_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/aes.h"
#define MBEDTLS_AESNI_AES 0x02000000u
#define MBEDTLS_AESNI_CLMUL 0x00000002u
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
( defined(__amd64__) || defined(__x86_64__) ) && \
! defined(MBEDTLS_HAVE_X86_64)
#define MBEDTLS_HAVE_X86_64
#endif
#if defined(MBEDTLS_HAVE_X86_64)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Internal function to detect the AES-NI feature in CPUs.
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param what The feature to detect
* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int mbedtls_aesni_has_support( unsigned int what );
/**
* \brief Internal AES-NI AES-ECB block encryption and decryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 on success (cannot fail)
*/
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal GCM multiplication: c = a * b in GF(2^128)
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param c Result
* \param a First operand
* \param b Second operand
*
* \note Both operands and result are bit strings interpreted as
* elements of GF(2^128) as per the GCM spec.
*/
void mbedtls_aesni_gcm_mult( unsigned char c[16],
const unsigned char a[16],
const unsigned char b[16] );
/**
* \brief Internal round key inversion. This function computes
* decryption round keys from the encryption round keys.
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param invkey Round keys for the equivalent inverse cipher
* \param fwdkey Original round keys (for encryption)
* \param nr Number of rounds (that is, number of round keys minus one)
*/
void mbedtls_aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey,
int nr );
/**
* \brief Internal key expansion for encryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
* \param bits Key size in bits (must be 128, 192 or 256)
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aesni_setkey_enc( unsigned char *rk,
const unsigned char *key,
size_t bits );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_HAVE_X86_64 */
#endif /* MBEDTLS_AESNI_H */

146
include/mbedtls/arc4.h Normal file
View File

@ -0,0 +1,146 @@
/**
* \file arc4.h
*
* \brief The ARCFOUR stream cipher
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*/
/*
* Copyright (C) 2006-2015, 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_ARC4_H
#define MBEDTLS_ARC4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED -0x0019 /**< ARC4 hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_ARC4_ALT)
// Regular implementation
//
/**
* \brief ARC4 context structure
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers instead.
*
*/
typedef struct mbedtls_arc4_context
{
int x; /*!< permutation index */
int y; /*!< permutation index */
unsigned char m[256]; /*!< permutation table */
}
mbedtls_arc4_context;
#else /* MBEDTLS_ARC4_ALT */
#include "arc4_alt.h"
#endif /* MBEDTLS_ARC4_ALT */
/**
* \brief Initialize ARC4 context
*
* \param ctx ARC4 context to be initialized
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/
void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
/**
* \brief Clear ARC4 context
*
* \param ctx ARC4 context to be cleared
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/
void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
/**
* \brief ARC4 key schedule
*
* \param ctx ARC4 context to be setup
* \param key the secret key
* \param keylen length of the key, in bytes
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
unsigned int keylen );
/**
* \brief ARC4 cipher function
*
* \param ctx ARC4 context
* \param length length of the input data
* \param input buffer holding the input data
* \param output buffer for the output data
*
* \return 0 if successful
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*
* \warning ARC4 is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*
*/
int mbedtls_arc4_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* arc4.h */

370
include/mbedtls/aria.h Normal file
View File

@ -0,0 +1,370 @@
/**
* \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 "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#include "mbedtls/platform_util.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. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
*/
#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, an unsupported ARIA key size. */
/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
#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. This must not be \c NULL.
*/
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. This may be \c NULL, in which
* case this function returns immediately. If it is not \c NULL,
* it must point to an initialized ARIA context.
*/
void mbedtls_aria_free( mbedtls_aria_context *ctx );
/**
* \brief This function sets the encryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* This must be initialized.
* \param key The encryption key. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The size of \p key in Bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function sets the decryption key.
*
* \param ctx The ARIA context to which the key should be bound.
* This must be initialized.
* \param key The decryption key. This must be a readable buffer
* of size \p keybits Bits.
* \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.
* \return A negative error code 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.
* This must be initialized and bound to a key.
* \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.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
#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.
* This must be initialized and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
* #MBEDTLS_ARIA_DECRYPT for decryption.
* \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).
* This must be a readable buffer of size 16 Bytes.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#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.
* This must be initialized and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
* #MBEDTLS_ARIA_DECRYPT for decryption.
* \param length The length of the input data \p input in Bytes.
* \param iv_off The offset in IV (updated after use).
* This must not be larger than 15.
* \param iv The initialization vector (updated after use).
* This must be a readable buffer of size 16 Bytes.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#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.
* This must be initialized and bound to a key.
* \param length The length of the input data \p input in Bytes.
* \param nc_off The offset in Bytes in the current \p stream_block,
* for resuming within the current cipher stream. The
* offset pointer should be \c 0 at the start of a
* stream. This must not be larger than \c 15 Bytes.
* \param nonce_counter The 128-bit nonce and counter. This must point to
* a read/write buffer of length \c 16 bytes.
* \param stream_block The saved stream block for resuming. This must
* point to a read/write buffer of length \c 16 bytes.
* This is overwritten by the function.
* \param input The buffer holding the input data. This must
* be a readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must
* be a writable buffer of length \p length Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#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 */

609
include/mbedtls/asn1.h Normal file
View File

@ -0,0 +1,609 @@
/**
* \file asn1.h
*
* \brief Generic ASN.1 parsing
*/
/*
* Copyright (C) 2006-2015, 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_ASN1_H
#define MBEDTLS_ASN1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#endif
/**
* \addtogroup asn1_module
* \{
*/
/**
* \name ASN1 Error codes
* These error codes are OR'ed to X509 error codes for
* higher error granularity.
* ASN1 is a standard to specify data structures.
* \{
*/
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
/* \} name */
/**
* \name DER constants
* These constants comply with the DER encoded ASN.1 type tags.
* DER encoding uses hexadecimal representation.
* An example DER sequence is:\n
* - 0x02 -- tag indicating INTEGER
* - 0x01 -- length in octets
* - 0x05 -- value
* Such sequences are typically read into \c ::mbedtls_x509_buf.
* \{
*/
#define MBEDTLS_ASN1_BOOLEAN 0x01
#define MBEDTLS_ASN1_INTEGER 0x02
#define MBEDTLS_ASN1_BIT_STRING 0x03
#define MBEDTLS_ASN1_OCTET_STRING 0x04
#define MBEDTLS_ASN1_NULL 0x05
#define MBEDTLS_ASN1_OID 0x06
#define MBEDTLS_ASN1_ENUMERATED 0x0A
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
#define MBEDTLS_ASN1_SEQUENCE 0x10
#define MBEDTLS_ASN1_SET 0x11
#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13
#define MBEDTLS_ASN1_T61_STRING 0x14
#define MBEDTLS_ASN1_IA5_STRING 0x16
#define MBEDTLS_ASN1_UTC_TIME 0x17
#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18
#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C
#define MBEDTLS_ASN1_BMP_STRING 0x1E
#define MBEDTLS_ASN1_PRIMITIVE 0x00
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
/* Slightly smaller way to check if tag is a string tag
* compared to canonical implementation. */
#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \
( ( tag ) < 32u && ( \
( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
( 1u << MBEDTLS_ASN1_T61_STRING ) | \
( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
* paragraph 8.1.2.2:
*
* Bit 8 7 6 5 1
* +-------+-----+------------+
* | Class | P/C | Tag number |
* +-------+-----+------------+
*/
#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
/* \} name */
/* \} addtogroup asn1_module */
/** Returns the size of the binary string, without the trailing \\0 */
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
/**
* Compares an mbedtls_asn1_buf structure to a reference OID.
*
* Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
* 'unsigned char *oid' here!
*/
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name Functions to parse ASN.1 data structures
* \{
*/
/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef struct mbedtls_asn1_buf
{
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
size_t len; /**< ASN1 length, in octets. */
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
}
mbedtls_asn1_buf;
/**
* Container for ASN1 bit strings.
*/
typedef struct mbedtls_asn1_bitstring
{
size_t len; /**< ASN1 length, in octets. */
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
unsigned char *p; /**< Raw ASN1 data for the bit string */
}
mbedtls_asn1_bitstring;
/**
* Container for a sequence of ASN.1 items
*/
typedef struct mbedtls_asn1_sequence
{
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
}
mbedtls_asn1_sequence;
/**
* Container for a sequence or list of 'named' ASN.1 data items
*/
typedef struct mbedtls_asn1_named_data
{
mbedtls_asn1_buf oid; /**< The object identifier. */
mbedtls_asn1_buf val; /**< The named value. */
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
unsigned char next_merged; /**< Merge next item into the current one? */
}
mbedtls_asn1_named_data;
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
* \param p On entry, \c *p points to the first byte of the length,
* i.e. immediately after the tag.
* On successful completion, \c *p points to the first byte
* after the length, i.e. the first byte of the content.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On successful completion, \c *len contains the length
* read from the ASN.1 input.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* \brief Get the tag and length of the element.
* Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* after the length, i.e. the first byte of the content.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On successful completion, \c *len contains the length
* read from the ASN.1 input.
* \param tag The expected tag.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
* with the requested tag.
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
* would end beyond \p end.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param val On success, the parsed value (\c 0 or \c 1).
*
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BOOLEAN.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param val On success, the parsed value.
*
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
* not fit in an \c int.
*/
int mbedtls_asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve an enumerated ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param val On success, the parsed value.
*
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 ENUMERATED.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
* not fit in an \c int.
*/
int mbedtls_asn1_get_enum( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p is equal to \p end.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param bs On success, ::mbedtls_asn1_bitstring information about
* the parsed value.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
* extra data after a valid BIT STRING.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs );
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* of the content of the BIT STRING.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param len On success, \c *len is the length of the content in bytes.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
* a valid BIT STRING with a nonzero number of unused bits.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring_null( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
* Updates the pointer to immediately behind the full sequence tag.
*
* This function allocates memory for the sequence elements. You can free
* the allocated memory with mbedtls_asn1_sequence_free().
*
* \note On error, this function may return a partial list in \p cur.
* You must set `cur->next = NULL` before calling this function!
* Otherwise it is impossible to distinguish a previously non-null
* pointer from a pointer to an object allocated by this function.
*
* \note If the sequence is empty, this function does not modify
* \c *cur. If the sequence is valid and non-empty, this
* function sets `cur->buf.tag` to \p tag. This allows
* callers to distinguish between an empty sequence and
* a one-element sequence.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p is equal to \p end.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param cur A ::mbedtls_asn1_sequence which this function fills.
* When this function returns, \c *cur is the head of a linked
* list. Each node in this list is allocated with
* mbedtls_calloc() apart from \p cur itself, and should
* therefore be freed with mbedtls_free().
* The list describes the content of the sequence.
* The head of the list (i.e. \c *cur itself) describes the
* first element, `*cur->next` describes the second element, etc.
* For each element, `buf.tag == tag`, `buf.len` is the length
* of the content of the content of the element, and `buf.p`
* points to the first byte of the content (i.e. immediately
* past the length of the element).
* Note that list elements may be allocated even on error.
* \param tag Each element of the sequence must have this tag.
*
* \return 0 if successful.
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
* extra data after a valid SEQUENCE OF \p tag.
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
* an ASN.1 SEQUENCE in which an element has a tag that
* is different from \p tag.
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 SEQUENCE.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag );
/**
* \brief Free a heap-allocated linked list presentation of
* an ASN.1 sequence, including the first element.
*
* There are two common ways to manage the memory used for the representation
* of a parsed ASN.1 sequence:
* - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
* Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
* When you have finished processing the sequence,
* call mbedtls_asn1_sequence_free() on `head`.
* - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
* for example on the stack. Make sure that `head->next == NULL`.
* Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
* When you have finished processing the sequence,
* call mbedtls_asn1_sequence_free() on `head->cur`,
* then free `head` itself in the appropriate manner.
*
* \param seq The address of the first sequence component. This may
* be \c NULL, in which case this functions returns
* immediately.
*/
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
/**
* \brief Traverse an ASN.1 SEQUENCE container and
* call a callback for each entry.
*
* This function checks that the input is a SEQUENCE of elements that
* each have a "must" tag, and calls a callback function on the elements
* that have a "may" tag.
*
* For example, to validate that the input is a SEQUENCE of `tag1` and call
* `cb` on each element, use
* ```
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
* ```
*
* To validate that the input is a SEQUENCE of ANY and call `cb` on
* each element, use
* ```
* mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
* ```
*
* To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
* and call `cb` on each element that is an OCTET STRING, use
* ```
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
* ```
*
* The callback is called on the elements with a "may" tag from left to
* right. If the input is not a valid SEQUENCE of elements with a "must" tag,
* the callback is called on the elements up to the leftmost point where
* the input is invalid.
*
* \warning This function is still experimental and may change
* at any time.
*
* \param p The address of the pointer to the beginning of
* the ASN.1 SEQUENCE header. This is updated to
* point to the end of the ASN.1 SEQUENCE container
* on a successful invocation.
* \param end The end of the ASN.1 SEQUENCE container.
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_must_value.
* \param tag_must_val The required value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_must_mask.
* Mismatching tags lead to an error.
* For example, a value of \c 0 for both \p tag_must_mask
* and \p tag_must_val means that every tag is allowed,
* while a value of \c 0xFF for \p tag_must_mask means
* that \p tag_must_val is the only allowed tag.
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within
* the SEQUENCE before comparing to \p tag_may_value.
* \param tag_may_val The desired value of each ASN.1 tag found in the
* SEQUENCE, after masking with \p tag_may_mask.
* Mismatching tags will be silently ignored.
* For example, a value of \c 0 for \p tag_may_mask and
* \p tag_may_val means that any tag will be considered,
* while a value of \c 0xFF for \p tag_may_mask means
* that all tags with value different from \p tag_may_val
* will be ignored.
* \param cb The callback to trigger for each component
* in the ASN.1 SEQUENCE that matches \p tag_may_val.
* The callback function is called with the following
* parameters:
* - \p ctx.
* - The tag of the current element.
* - A pointer to the start of the current element's
* content inside the input.
* - The length of the content of the current element.
* If the callback returns a non-zero value,
* the function stops immediately,
* forwarding the callback's return value.
* \param ctx The context to be passed to the callback \p cb.
*
* \return \c 0 if successful the entire ASN.1 SEQUENCE
* was traversed without parsing or callback errors.
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
* contains extra data after a valid SEQUENCE
* of elements with an accepted tag.
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
* with an ASN.1 SEQUENCE in which an element has a tag
* that is not accepted.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 SEQUENCE.
* \return A non-zero error code forwarded from the callback
* \p cb in case the latter returns a non-zero value.
*/
int mbedtls_asn1_traverse_sequence_of(
unsigned char **p,
const unsigned char *end,
unsigned char tag_must_mask, unsigned char tag_must_val,
unsigned char tag_may_mask, unsigned char tag_may_val,
int (*cb)( void *ctx, int tag,
unsigned char* start, size_t len ),
void *ctx );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the ASN.1 element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param X On success, the parsed value.
*
* \return 0 if successful.
* \return An ASN.1 error code if the input does not start with
* a valid ASN.1 INTEGER.
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
* not fit in an \c int.
* \return An MPI error code if the parsed value is too large.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the AlgorithmIdentifier element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param alg The buffer to receive the OID.
* \param params The buffer to receive the parameters.
* This is zeroized if there are no parameters.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
* params.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p On entry, \c *p points to the start of the ASN.1 element.
* On successful completion, \c *p points to the first byte
* beyond the AlgorithmIdentifier element.
* On error, the value of \c *p is undefined.
* \param end End of data.
* \param alg The buffer to receive the OID.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg );
/**
* \brief Find a specific named_data entry in a sequence or list based on
* the OID.
*
* \param list The list to seek through
* \param oid The OID to look for
* \param len Size of the OID
*
* \return NULL if not found, or a pointer to the existing entry.
*/
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
const char *oid, size_t len );
/**
* \brief Free a mbedtls_asn1_named_data entry
*
* \param entry The named data entry to free.
* This function calls mbedtls_free() on
* `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
* \brief Free all entries in a mbedtls_asn1_named_data list.
*
* \param head Pointer to the head of the list of named data entries to free.
* This function calls mbedtls_asn1_free_named_data() and
* mbedtls_free() on each list element and
* sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
#ifdef __cplusplus
}
#endif
#endif /* asn1.h */

372
include/mbedtls/asn1write.h Normal file
View File

@ -0,0 +1,372 @@
/**
* \file asn1write.h
*
* \brief ASN.1 buffer writing functionality
*/
/*
* Copyright (C) 2006-2015, 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_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
do \
{ \
if( ( ret = (f) ) < 0 ) \
return( ret ); \
else \
(g) += ret; \
} while( 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Write a length field in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param len The length value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start,
size_t len );
/**
* \brief Write an ASN.1 tag in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The tag to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
unsigned char tag );
/**
* \brief Write raw buffer data.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The data buffer to write.
* \param size The length of the data buffer.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
* It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start,
const mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
/**
* \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID to write.
* \param oid_len The length of the OID.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len );
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID of the algorithm to write.
* \param oid_len The length of the algorithm's OID.
* \param par_len The length of the parameters, which must be already written.
* If 0, NULL parameters are added
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len );
/**
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param boolean The boolean value to write, either \c 0 or \c 1.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
int boolean );
/**
* \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
* It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
/**
* \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value
* in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val );
/**
* \brief Write a string in ASN.1 format using a specific
* string encoding tag.
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param tag The string encoding tag to write, e.g.
* #MBEDTLS_ASN1_UTF8_STRING.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
int tag, const char *text,
size_t text_len );
/**
* \brief Write a string in ASN.1 format using the PrintableString
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_printable_string( unsigned char **p,
unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
* string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a string in ASN.1 format using the IA5String
* string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param text The string to write.
* \param text_len The length of \p text in bytes (which might
* be strictly larger than the number of characters).
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
* value in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The bitstring to write.
* \param bits The total number of bits in the bitstring.
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits );
/**
* \brief This function writes a named bitstring tag
* (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format.
*
* As stated in RFC 5280 Appendix B, trailing zeroes are
* omitted when encoding named bitstrings in DER.
*
* \note This function works backwards within the data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer which is used for bounds-checking.
* \param buf The bitstring to write.
* \param bits The total number of bits in the bitstring.
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_named_bitstring( unsigned char **p,
unsigned char *start,
const unsigned char *buf,
size_t bits );
/**
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
* and value in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param buf The buffer holding the data to write.
* \param size The length of the data buffer \p buf.
*
* \return The number of bytes written to \p p on success.
* \return A negative error code on failure.
*/
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
/**
* \brief Create or find a specific named_data entry for writing in a
* sequence or list based on the OID. If not already in there,
* a new entry is added to the head of the list.
* Warning: Destructive behaviour for the val data!
*
* \param list The pointer to the location of the head of the list to seek
* through (will be updated in case of a new entry).
* \param oid The OID to look for.
* \param oid_len The size of the OID.
* \param val The associated data to store. If this is \c NULL,
* no data is copied to the new or existing buffer.
* \param val_len The minimum length of the data buffer needed.
* If this is 0, do not allocate a buffer for the associated
* data.
* If the OID was already present, enlarge, shrink or free
* the existing buffer to fit \p val_len.
*
* \return A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
*/
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_ASN1_WRITE_H */

98
include/mbedtls/base64.h Normal file
View File

@ -0,0 +1,98 @@
/**
* \file base64.h
*
* \brief RFC 1521 base64 encoding/decoding
*/
/*
* Copyright (C) 2006-2015, 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_BASE64_H
#define MBEDTLS_BASE64_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
*
* \note Call this function with dlen = 0 to obtain the
* required buffer size in *olen
*/
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer (can be NULL for checking size)
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
* not correct. *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dst = NULL or dlen = 0 to obtain
* the required buffer size in *olen
*/
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_base64_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* base64.h */

1019
include/mbedtls/bignum.h Normal file

File diff suppressed because it is too large Load Diff

287
include/mbedtls/blowfish.h Normal file
View File

@ -0,0 +1,287 @@
/**
* \file blowfish.h
*
* \brief Blowfish block cipher
*/
/*
* Copyright (C) 2006-2015, 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_BLOWFISH_H
#define MBEDTLS_BLOWFISH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#include "mbedtls/platform_util.h"
#define MBEDTLS_BLOWFISH_ENCRYPT 1
#define MBEDTLS_BLOWFISH_DECRYPT 0
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448
#define MBEDTLS_BLOWFISH_MIN_KEY_BITS 32
#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED -0x0017 /**< Blowfish hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_BLOWFISH_ALT)
// Regular implementation
//
/**
* \brief Blowfish context structure
*/
typedef struct mbedtls_blowfish_context
{
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
uint32_t S[4][256]; /*!< key dependent S-boxes */
}
mbedtls_blowfish_context;
#else /* MBEDTLS_BLOWFISH_ALT */
#include "blowfish_alt.h"
#endif /* MBEDTLS_BLOWFISH_ALT */
/**
* \brief Initialize a Blowfish context.
*
* \param ctx The Blowfish context to be initialized.
* This must not be \c NULL.
*/
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
/**
* \brief Clear a Blowfish context.
*
* \param ctx The Blowfish context to be cleared.
* This may be \c NULL, in which case this function
* returns immediately. If it is not \c NULL, it must
* point to an initialized Blowfish context.
*/
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
/**
* \brief Perform a Blowfish key schedule operation.
*
* \param ctx The Blowfish context to perform the key schedule on.
* \param key The encryption key. This must be a readable buffer of
* length \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be between
* \c 32 and \c 448 and a multiple of \c 8.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a Blowfish-ECB block encryption/decryption operation.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param input The input block. This must be a readable buffer
* of size \c 8 Bytes.
* \param output The output block. This must be a writable buffer
* of size \c 8 Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
int mode,
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief Perform a Blowfish-CBC buffer encryption/decryption operation.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param length The length of the input data in Bytes. This must be
* multiple of \c 8.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 8 Bytes. It is updated by this function.
* \param input The input data. This must be a readable buffer of length
* \p length Bytes.
* \param output The output data. This must be a writable buffer of length
* \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief Perform a Blowfish CFB buffer encryption/decryption operation.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The Blowfish context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. Possible values are
* #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
* #MBEDTLS_BLOWFISH_DECRYPT for decryption.
* \param length The length of the input data in Bytes.
* \param iv_off The offset in the initialiation vector.
* The value pointed to must be smaller than \c 8 Bytes.
* It is updated by this function to support the aforementioned
* streaming usage.
* \param iv The initialization vector. This must be a read/write buffer
* of size \c 8 Bytes. It is updated after use.
* \param input The input data. This must be a readable buffer of length
* \p length Bytes.
* \param output The output data. This must be a writable buffer of length
* \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief Perform a Blowfish-CTR buffer encryption/decryption operation.
*
* \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 The Blowfish context to use. This must be initialized
* and bound to a key.
* \param length The length of the input data in Bytes.
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer
* should be \c 0 at the start of a stream and must be
* smaller than \c 8. It is updated by this function.
* \param nonce_counter The 64-bit nonce and counter. This must point to a
* read/write buffer of length \c 8 Bytes.
* \param stream_block The saved stream-block for resuming. This must point to
* a read/write buffer of length \c 8 Bytes.
* \param input The input data. This must be a readable buffer of
* length \p length Bytes.
* \param output The output data. This must be a writable buffer of
* length \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#ifdef __cplusplus
}
#endif
#endif /* blowfish.h */

940
include/mbedtls/bn_mul.h Normal file
View File

@ -0,0 +1,940 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*/
/*
* Copyright (C) 2006-2015, 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)
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef MBEDTLS_BN_MUL_H
#define MBEDTLS_BN_MUL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/bignum.h"
#if defined(MBEDTLS_HAVE_ASM)
#ifndef asm
#define asm __asm
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
/*
* 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( \
"movl %%ebx, %0 \n\t" \
"movl %5, %%esi \n\t" \
"movl %6, %%edi \n\t" \
"movl %7, %%ecx \n\t" \
"movl %8, %%ebx \n\t"
#define MULADDC_CORE \
"lodsl \n\t" \
"mull %%ebx \n\t" \
"addl %%ecx, %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"addl (%%edi), %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"movl %%edx, %%ecx \n\t" \
"stosl \n\t"
#if defined(MBEDTLS_HAVE_SSE2)
#define MULADDC_HUIT \
"movd %%ecx, %%mm1 \n\t" \
"movd %%ebx, %%mm0 \n\t" \
"movd (%%edi), %%mm3 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd (%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"movd 4(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"movd 8(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd 12(%%esi), %%mm7 \n\t" \
"pmuludq %%mm0, %%mm7 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 4(%%edi), %%mm3 \n\t" \
"paddq %%mm4, %%mm3 \n\t" \
"movd 8(%%edi), %%mm5 \n\t" \
"paddq %%mm6, %%mm5 \n\t" \
"movd 12(%%edi), %%mm4 \n\t" \
"paddq %%mm4, %%mm7 \n\t" \
"movd %%mm1, (%%edi) \n\t" \
"movd 16(%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 20(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd 24(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd %%mm1, 4(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 28(%%esi), %%mm3 \n\t" \
"pmuludq %%mm0, %%mm3 \n\t" \
"paddq %%mm5, %%mm1 \n\t" \
"movd 16(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm2 \n\t" \
"movd %%mm1, 8(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm7, %%mm1 \n\t" \
"movd 20(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm4 \n\t" \
"movd %%mm1, 12(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 24(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm6 \n\t" \
"movd %%mm1, 16(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm4, %%mm1 \n\t" \
"movd 28(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm3 \n\t" \
"movd %%mm1, 20(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm6, %%mm1 \n\t" \
"movd %%mm1, 24(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd %%mm1, 28(%%edi) \n\t" \
"addl $32, %%edi \n\t" \
"addl $32, %%esi \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd %%mm1, %%ecx \n\t"
#define MULADDC_STOP \
"emms \n\t" \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ebx", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( \
"xorq %%r8, %%r8\n"
#define MULADDC_CORE \
"movq (%%rsi), %%rax\n" \
"mulq %%rbx\n" \
"addq $8, %%rsi\n" \
"addq %%rcx, %%rax\n" \
"movq %%r8, %%rcx\n" \
"adcq $0, %%rdx\n" \
"nop \n" \
"addq %%rax, (%%rdi)\n" \
"adcq %%rdx, %%rcx\n" \
"addq $8, %%rdi\n"
#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s) \
: "b" (b) \
: "rax", "rdx", "r8" \
);
#endif /* AMD64 */
#if defined(__aarch64__)
#define MULADDC_INIT \
asm(
#define MULADDC_CORE \
"ldr x4, [%2], #8 \n\t" \
"ldr x5, [%1] \n\t" \
"mul x6, x4, %3 \n\t" \
"umulh x7, x4, %3 \n\t" \
"adds x5, x5, x6 \n\t" \
"adc x7, x7, xzr \n\t" \
"adds x5, x5, %0 \n\t" \
"adc %0, x7, xzr \n\t" \
"str x5, [%1], #8 \n\t"
#define MULADDC_STOP \
: "+r" (c), "+r" (d), "+r" (s) \
: "r" (b) \
: "x4", "x5", "x6", "x7", "cc" \
);
#endif /* Aarch64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( \
"movl %3, %%a2 \n\t" \
"movl %4, %%a3 \n\t" \
"movl %5, %%d3 \n\t" \
"movl %6, %%d2 \n\t" \
"moveq #0, %%d0 \n\t"
#define MULADDC_CORE \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"moveq #0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d4, %%d3 \n\t"
#define MULADDC_STOP \
"movl %%d3, %0 \n\t" \
"movl %%a3, %1 \n\t" \
"movl %%a2, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
);
#define MULADDC_HUIT \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d0, %%d3 \n\t"
#endif /* MC68000 */
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"ld r3, %3 \n\t" \
"ld r4, %4 \n\t" \
"ld r5, %5 \n\t" \
"ld r6, %6 \n\t" \
"addi r3, r3, -8 \n\t" \
"addi r4, r4, -8 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"ldu r7, 8(r3) \n\t" \
"mulld r8, r7, r6 \n\t" \
"mulhdu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"ld r7, 8(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stdu r8, 8(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 8 \n\t" \
"addi r3, r3, 8 \n\t" \
"std r5, %0 \n\t" \
"std r4, %1 \n\t" \
"std r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"ld %%r3, %3 \n\t" \
"ld %%r4, %4 \n\t" \
"ld %%r5, %5 \n\t" \
"ld %%r6, %6 \n\t" \
"addi %%r3, %%r3, -8 \n\t" \
"addi %%r4, %%r4, -8 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"ldu %%r7, 8(%%r3) \n\t" \
"mulld %%r8, %%r7, %%r6 \n\t" \
"mulhdu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"ld %%r7, 8(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stdu %%r8, 8(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 8 \n\t" \
"addi %%r3, %%r3, 8 \n\t" \
"std %%r5, %0 \n\t" \
"std %%r4, %1 \n\t" \
"std %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"lwz r3, %3 \n\t" \
"lwz r4, %4 \n\t" \
"lwz r5, %5 \n\t" \
"lwz r6, %6 \n\t" \
"addi r3, r3, -4 \n\t" \
"addi r4, r4, -4 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu r7, 4(r3) \n\t" \
"mullw r8, r7, r6 \n\t" \
"mulhwu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"lwz r7, 4(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stwu r8, 4(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 4 \n\t" \
"addi r3, r3, 4 \n\t" \
"stw r5, %0 \n\t" \
"stw r4, %1 \n\t" \
"stw r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"lwz %%r3, %3 \n\t" \
"lwz %%r4, %4 \n\t" \
"lwz %%r5, %5 \n\t" \
"lwz %%r6, %6 \n\t" \
"addi %%r3, %%r3, -4 \n\t" \
"addi %%r4, %%r4, -4 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu %%r7, 4(%%r3) \n\t" \
"mullw %%r8, %%r7, %%r6 \n\t" \
"mulhwu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"lwz %%r7, 4(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stwu %%r8, 4(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 4 \n\t" \
"addi %%r3, %%r3, 4 \n\t" \
"stw %%r5, %0 \n\t" \
"stw %%r4, %1 \n\t" \
"stw %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#endif /* PPC32 */
/*
* The Sparc(64) assembly is reported to be broken.
* Disable it for now, until we're able to fix it.
*/
#if 0 && defined(__sparc__)
#if defined(__sparc64__)
#define MULADDC_INIT \
asm( \
"ldx %3, %%o0 \n\t" \
"ldx %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"stx %%o1, %1 \n\t" \
"stx %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#else /* __sparc64__ */
#define MULADDC_INIT \
asm( \
"ld %3, %%o0 \n\t" \
"ld %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"st %%o1, %1 \n\t" \
"st %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* __sparc64__ */
#endif /* __sparc__ */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( \
"lwi r3, %3 \n\t" \
"lwi r4, %4 \n\t" \
"lwi r5, %5 \n\t" \
"lwi r6, %6 \n\t" \
"andi r7, r6, 0xffff \n\t" \
"bsrli r6, r6, 16 \n\t"
#define MULADDC_CORE \
"lhui r8, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"lhui r9, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"mul r10, r9, r6 \n\t" \
"mul r11, r8, r7 \n\t" \
"mul r12, r9, r7 \n\t" \
"mul r13, r8, r6 \n\t" \
"bsrli r8, r10, 16 \n\t" \
"bsrli r9, r11, 16 \n\t" \
"add r13, r13, r8 \n\t" \
"add r13, r13, r9 \n\t" \
"bslli r10, r10, 16 \n\t" \
"bslli r11, r11, 16 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r11 \n\t" \
"addc r13, r13, r0 \n\t" \
"lwi r10, r4, 0 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r5 \n\t" \
"addc r5, r13, r0 \n\t" \
"swi r12, r4, 0 \n\t" \
"addi r4, r4, 4 \n\t"
#define MULADDC_STOP \
"swi r5, %0 \n\t" \
"swi r4, %1 \n\t" \
"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", \
"r9", "r10", "r11", "r12", "r13" \
);
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( \
"ld.a %%a2, %3 \n\t" \
"ld.a %%a3, %4 \n\t" \
"ld.w %%d4, %5 \n\t" \
"ld.w %%d1, %6 \n\t" \
"xor %%d5, %%d5 \n\t"
#define MULADDC_CORE \
"ld.w %%d0, [%%a2+] \n\t" \
"madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
"ld.w %%d0, [%%a3] \n\t" \
"addx %%d2, %%d2, %%d0 \n\t" \
"addc %%d3, %%d3, 0 \n\t" \
"mov %%d4, %%d3 \n\t" \
"st.w [%%a3+], %%d2 \n\t"
#define MULADDC_STOP \
"st.w %0, %%d4 \n\t" \
"st.a %1, %%a3 \n\t" \
"st.a %2, %%a2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "e2", "d4", "a2", "a3" \
);
#endif /* TriCore */
/*
* 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
* clang and armcc5 under the same conditions).
*
* So, only use the optimized assembly below for optimized build, which avoids
* the build error and is pretty reasonable anyway.
*/
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define MULADDC_CANNOT_USE_R7
#endif
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t" \
"lsr r7, r3, #16 \n\t" \
"mov r9, r7 \n\t" \
"lsl r7, r3, #16 \n\t" \
"lsr r7, r7, #16 \n\t" \
"mov r8, r7 \n\t"
#define MULADDC_CORE \
"ldmia r0!, {r6} \n\t" \
"lsr r7, r6, #16 \n\t" \
"lsl r6, r6, #16 \n\t" \
"lsr r6, r6, #16 \n\t" \
"mov r4, r8 \n\t" \
"mul r4, r6 \n\t" \
"mov r3, r9 \n\t" \
"mul r6, r3 \n\t" \
"mov r5, r9 \n\t" \
"mul r5, r7 \n\t" \
"mov r3, r8 \n\t" \
"mul r7, r3 \n\t" \
"lsr r3, r6, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"lsr r3, r7, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"add r4, r4, r2 \n\t" \
"mov r2, #0 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r6, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r7, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"ldr r3, [r1] \n\t" \
"add r4, r4, r3 \n\t" \
"adc r2, r5 \n\t" \
"stmia r1!, {r4} \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#elif (__ARM_ARCH >= 6) && \
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 \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t"
#define MULADDC_CORE \
"ldr r4, [r0], #4 \n\t" \
"mov r5, #0 \n\t" \
"ldr r6, [r1] \n\t" \
"umlal r2, r5, r3, r4 \n\t" \
"adds r7, r6, r2 \n\t" \
"adc r2, r5, #0 \n\t" \
"str r7, [r1], #4 \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( \
"ldq $1, %3 \n\t" \
"ldq $2, %4 \n\t" \
"ldq $3, %5 \n\t" \
"ldq $4, %6 \n\t"
#define MULADDC_CORE \
"ldq $6, 0($1) \n\t" \
"addq $1, 8, $1 \n\t" \
"mulq $6, $4, $7 \n\t" \
"umulh $6, $4, $6 \n\t" \
"addq $7, $3, $7 \n\t" \
"cmpult $7, $3, $3 \n\t" \
"ldq $5, 0($2) \n\t" \
"addq $7, $5, $7 \n\t" \
"cmpult $7, $5, $5 \n\t" \
"stq $7, 0($2) \n\t" \
"addq $2, 8, $2 \n\t" \
"addq $6, $3, $3 \n\t" \
"addq $5, $3, $3 \n\t"
#define MULADDC_STOP \
"stq $3, %0 \n\t" \
"stq $2, %1 \n\t" \
"stq $1, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
);
#endif /* Alpha */
#if defined(__mips__) && !defined(__mips64)
#define MULADDC_INIT \
asm( \
"lw $10, %3 \n\t" \
"lw $11, %4 \n\t" \
"lw $12, %5 \n\t" \
"lw $13, %6 \n\t"
#define MULADDC_CORE \
"lw $14, 0($10) \n\t" \
"multu $13, $14 \n\t" \
"addi $10, $10, 4 \n\t" \
"mflo $14 \n\t" \
"mfhi $9 \n\t" \
"addu $14, $12, $14 \n\t" \
"lw $15, 0($11) \n\t" \
"sltu $12, $14, $12 \n\t" \
"addu $15, $14, $15 \n\t" \
"sltu $14, $15, $14 \n\t" \
"addu $12, $12, $9 \n\t" \
"sw $15, 0($11) \n\t" \
"addu $12, $12, $14 \n\t" \
"addi $11, $11, 4 \n\t"
#define MULADDC_STOP \
"sw $12, %0 \n\t" \
"sw $11, %1 \n\t" \
"sw $10, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \
);
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(MBEDTLS_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* MBEDTLS_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(MBEDTLS_HAVE_UDBL)
#define MULADDC_INIT \
{ \
mbedtls_t_udbl r; \
mbedtls_mpi_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (mbedtls_t_udbl) b; \
r0 = (mbedtls_mpi_uint) r; \
r1 = (mbedtls_mpi_uint)( r >> biL ); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
mbedtls_mpi_uint s0, s1, b0, b1; \
mbedtls_mpi_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

326
include/mbedtls/camellia.h Normal file
View File

@ -0,0 +1,326 @@
/**
* \file camellia.h
*
* \brief Camellia block cipher
*/
/*
* Copyright (C) 2006-2015, 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_CAMELLIA_H
#define MBEDTLS_CAMELLIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#include "mbedtls/platform_util.h"
#define MBEDTLS_CAMELLIA_ENCRYPT 1
#define MBEDTLS_CAMELLIA_DECRYPT 0
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED -0x0027 /**< Camellia hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CAMELLIA_ALT)
// Regular implementation
//
/**
* \brief CAMELLIA context structure
*/
typedef struct mbedtls_camellia_context
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
}
mbedtls_camellia_context;
#else /* MBEDTLS_CAMELLIA_ALT */
#include "camellia_alt.h"
#endif /* MBEDTLS_CAMELLIA_ALT */
/**
* \brief Initialize a CAMELLIA context.
*
* \param ctx The CAMELLIA context to be initialized.
* This must not be \c NULL.
*/
void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
/**
* \brief Clear a CAMELLIA context.
*
* \param ctx The CAMELLIA context to be cleared. This may be \c NULL,
* in which case this function returns immediately. If it is not
* \c NULL, it must be initialized.
*/
void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
/**
* \brief Perform a CAMELLIA key schedule operation for encryption.
*
* \param ctx The CAMELLIA context to use. This must be initialized.
* \param key The encryption key to use. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be either \c 128,
* \c 192 or \c 256.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a CAMELLIA key schedule operation for decryption.
*
* \param ctx The CAMELLIA context to use. This must be initialized.
* \param key The decryption key. This must be a readable buffer
* of size \p keybits Bits.
* \param keybits The length of \p key in Bits. This must be either \c 128,
* \c 192 or \c 256.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits );
/**
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param input The input block. This must be a readable buffer
* of size \c 16 Bytes.
* \param output The output block. This must be a writable buffer
* of size \c 16 Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param length The length in Bytes of the input data \p input.
* This must be a multiple of \c 16 Bytes.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 16 Bytes. It is updated to allow streaming
* use as explained above.
* \param input The buffer holding the input data. This must point to a
* readable buffer of length \p length Bytes.
* \param output The buffer holding the output data. This must point to a
* writable buffer of length \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption
* operation.
*
* \note Due to the nature of CFB mode, you should use the same
* key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx The CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param mode The mode of operation. This must be either
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
* \param length The length of the input data \p input. Any value is allowed.
* \param iv_off The current offset in the IV. This must be smaller
* than \c 16 Bytes. It is updated after this call to allow
* the aforementioned streaming usage.
* \param iv The initialization vector. This must be a read/write buffer
* of length \c 16 Bytes. It is updated after this call to
* allow the aforementioned streaming usage.
* \param input The buffer holding the input data. This must be a readable
* buffer of size \p length Bytes.
* \param output The buffer to hold the output data. This must be a writable
* buffer of length \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation.
*
* *note Due to the nature of CTR mode, you should use the same
* key for both encryption and decryption. In particular, calls
* to this function should be preceded by a key-schedule via
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
* is #MBEDTLS_CAMELLIA_ENCRYPT or #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 \c 12 Bytes for the
* per-message nonce, and the last \c 4 Bytes for internal use.
* In that case, before calling this function on a new message you
* need to set the first \c 12 Bytes of \p nonce_counter to your
* chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
* (which will cause \p stream_block to be ignored). That way, you
* can encrypt at most \c 2**96 messages of up to \c 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 \c 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 CAMELLIA context to use. This must be initialized
* and bound to a key.
* \param length The length of the input data \p input in Bytes.
* Any value is allowed.
* \param nc_off The offset in the current \p stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be \c 0 at the start of a stream. It is updated
* at the end of this call.
* \param nonce_counter The 128-bit nonce and counter. This must be a read/write
* buffer of length \c 16 Bytes.
* \param stream_block The saved stream-block for resuming. This must be a
* read/write buffer of length \c 16 Bytes.
* \param input The input data stream. This must be a readable buffer of
* size \p length Bytes.
* \param output The output data stream. This must be a writable buffer
* of size \p length Bytes.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_camellia_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* camellia.h */

310
include/mbedtls/ccm.h Normal file
View File

@ -0,0 +1,310 @@
/**
* \file ccm.h
*
* \brief This file provides an API for the CCM authenticated encryption
* mode for block ciphers.
*
* CCM combines Counter mode encryption with CBC-MAC authentication
* for 128-bit block ciphers.
*
* Input to CCM includes the following elements:
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
* <li>Associated data (Adata) - data that is authenticated but not
* encrypted, For example, a header.</li>
* <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
* 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_CCM_H
#define MBEDTLS_CCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/cipher.h"
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_CCM_ALT)
// Regular implementation
//
/**
* \brief The CCM context-type definition. The CCM context is passed
* to the APIs called.
*/
typedef struct mbedtls_ccm_context
{
mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */
}
mbedtls_ccm_context;
#else /* MBEDTLS_CCM_ALT */
#include "ccm_alt.h"
#endif /* MBEDTLS_CCM_ALT */
/**
* \brief This function initializes the specified CCM context,
* to make references valid, and prepare the context
* for mbedtls_ccm_setkey() or mbedtls_ccm_free().
*
* \param ctx The CCM context to initialize. This must not be \c NULL.
*/
void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
/**
* \brief This function initializes the CCM context set in the
* \p ctx parameter and sets the encryption key.
*
* \param ctx The CCM context to initialize. This must be an initialized
* context.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must not be \c NULL.
* \param keybits The key size in bits. This must be acceptable by the cipher.
*
* \return \c 0 on success.
* \return A CCM or cipher-specific error code on failure.
*/
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function releases and clears the specified CCM context
* and underlying cipher sub-context.
*
* \param ctx The CCM context to clear. If this is \c NULL, the function
* has no effect. Otherwise, this must be initialized.
*/
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
* \p tag = \p output + \p length, and make sure that the
* output buffer is at least \p length + \p tag_len wide.
*
* \param ctx The CCM context to use for encryption. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \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. If \p add_len is greater than
* zero, \p add must be a readable buffer of at least that
* length.
* \param add_len The length of additional data in Bytes.
* This must be less than `2^16 - 2^8`.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \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.
* \return A CCM or cipher-specific error code on failure.
*/
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 );
/**
* \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
* \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. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \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. This must be a readable buffer of
* at least \p add_len Bytes.
* \param add_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field to generate in Bytes:
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing \c 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. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \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. This must be a readable buffer
* of at least that \p add_len Bytes..
* \param add_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \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. This indicates that the message is authentic.
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
* \return A cipher-specific error code on calculation failure.
*/
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 );
/**
* \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. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \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. This must be a readable buffer of
* at least that \p add_len Bytes.
* \param add_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
* \param output The buffer holding the output data. If \p length is greater
* than zero, \p output must be a writable buffer of at least
* that length.
* \param tag The buffer holding the authentication field. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication field in Bytes.
* 0, 4, 6, 8, 10, 12, 14 or 16.
*
* \warning Passing \c 0 as \p tag_len means that the message is nos
* 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)
/**
* \brief The CCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_ccm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CCM_H */

226
include/mbedtls/chacha20.h Normal file
View File

@ -0,0 +1,226 @@
/**
* \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 "mbedtls/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). */
/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be
* used. */
#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#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.
* This must not be \c NULL.
*/
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. This may be \c NULL,
* in which case this function is a no-op. If it is not
* \c NULL, it must point to an initialized context.
*
*/
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.
* It must be initialized.
* \param key The encryption/decryption key. This must be \c 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.
* It must be initialized and bound to a key.
* \param nonce The nonce. This must be \c 12 Bytes in size.
* \param counter The initial counter value. This is usually \c 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.
* It must be initialized and bound to a key and nonce.
* \param size The length of the input data in Bytes.
* \param input The buffer holding the input data.
* This pointer can be \c NULL if `size == 0`.
* \param output The buffer holding the output data.
* This must be able to hold \p size Bytes.
* This pointer can be \c NULL if `size == 0`.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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.
* This must be \c 32 Bytes in length.
* \param nonce The nonce. This must be \c 12 Bytes in size.
* \param counter The initial counter value. This is usually \c 0.
* \param size The length of the input data in Bytes.
* \param input The buffer holding the input data.
* This pointer can be \c NULL if `size == 0`.
* \param output The buffer holding the output data.
* This must be able to hold \p size Bytes.
* This pointer can be \c NULL if `size == 0`.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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,358 @@
/**
* \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 "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
/* for shared error codes */
#include "mbedtls/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 "mbedtls/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. Must not be \c NULL.
*/
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. This may be \c NULL, in which
* case this function is a no-op.
*/
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. This must be initialized.
* \param key The \c 256 Bit (\c 32 Bytes) key.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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. This must be initialized
* and bound to a key.
* \param nonce The nonce/IV to use for the message.
* This must be a redable buffer of length \c 12 Bytes.
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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. This must be initialized
* and bound to a key.
* \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 \c 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. This must be initialized.
* \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 \c NULL if `len == 0`.
* \param output The buffer to where the encrypted or decrypted data is
* written. This must be able to hold \p len bytes.
* This pointer can be \c NULL if `len == 0`.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
* \return Another negative error code on other kinds of failure.
*/
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. This must be initialized.
* \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_CHACHAPOLY_BAD_STATE
* if the operation has not been started or has been
* finished.
* \return Another negative error code on other kinds of failure.
*/
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).
* This must be initialized.
* \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 \c 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 \c NULL if `ilen == 0`.
* \param output The buffer to where the encrypted or decrypted data
* is written. This pointer can be \c NULL if `ilen == 0`.
* \param tag The buffer to where the computed 128-bit (16 bytes) MAC
* is written. This must not be \c NULL.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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 \c 96 Bit (\c 12 bytes) nonce/IV to use.
* \param aad The buffer containing the additional authenticated data (AAD).
* This pointer can be \c 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.
* This must be a readable buffer of length \c 16 Bytes.
* \param input The buffer containing the data to decrypt.
* This pointer can be \c NULL if `ilen == 0`.
* \param output The buffer to where the decrypted data is written.
* This pointer can be \c NULL if `ilen == 0`.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
* if the data was not authentic.
* \return Another negative error code on other kinds of failure.
*/
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

@ -189,7 +189,7 @@
#endif
#if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
@ -553,6 +553,12 @@
#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \
! ( defined(MBEDTLS_PSA_CRYPTO_C) && \
defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) )
#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
! defined(MBEDTLS_PSA_CRYPTO_C)
#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
@ -589,6 +595,10 @@
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SHA512_NO_SHA384) && !defined(MBEDTLS_SHA512_C)
#error "MBEDTLS_SHA512_NO_SHA384 defined without MBEDTLS_SHA512_C"
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
@ -664,23 +674,6 @@
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \
MBEDTLS_SSL_CID_IN_LEN_MAX > 255
#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \
MBEDTLS_SSL_CID_OUT_LEN_MAX > 255
#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"

926
include/mbedtls/cipher.h Normal file
View File

@ -0,0 +1,926 @@
/**
* \file cipher.h
*
* \brief This file contains an abstraction interface for use with the cipher
* primitives provided by the library. It provides a common interface to all of
* the available cipher operations.
*
* \author Adriaan de Jong <dejong@fox-it.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_CIPHER_H
#define MBEDTLS_CIPHER_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#define MBEDTLS_CIPHER_MODE_AEAD
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
defined(MBEDTLS_CHACHA20_C)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters. */
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid. For example, because it was freed. */
/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 /**< Cipher hardware accelerator failed. */
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Supported cipher types.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */
MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */
MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */
MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */
MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */
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;
/**
* \brief Supported {cipher type, cipher mode} pairs.
*
* \warning RC4 and DES are considered weak ciphers and their use
* constitutes a security risk. Arm recommends considering stronger
* ciphers instead.
*/
typedef enum {
MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */
MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */
MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */
MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */
MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */
MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */
MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */
MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */
MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */
MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */
MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */
MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */
MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */
MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */
MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */
MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */
MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */
MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */
MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */
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_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */
MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */
MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */
MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */
MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */
MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */
} mbedtls_cipher_type_t;
/** Supported cipher modes. */
typedef enum {
MBEDTLS_MODE_NONE = 0, /**< None. */
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. */
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_MODE_KW, /**< The SP800-38F KW mode */
MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */
} mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
typedef enum {
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */
MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */
MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */
} mbedtls_cipher_padding_t;
/** Type of operation. */
typedef enum {
MBEDTLS_OPERATION_NONE = -1,
MBEDTLS_DECRYPT = 0,
MBEDTLS_ENCRYPT,
} mbedtls_operation_t;
enum {
/** Undefined key length. */
MBEDTLS_KEY_LENGTH_NONE = 0,
/** Key length, in bits (including parity), for DES keys. */
MBEDTLS_KEY_LENGTH_DES = 64,
/** Key length in bits, including parity, for DES in two-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE = 128,
/** Key length in bits, including parity, for DES in three-key EDE. */
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
};
/** Maximum length of any IV, in Bytes. */
#define MBEDTLS_MAX_IV_LENGTH 16
/** Maximum block size of any cipher, in Bytes. */
#define MBEDTLS_MAX_BLOCK_LENGTH 16
/**
* Base cipher information (opaque struct).
*/
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
/**
* CMAC context (opaque struct).
*/
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
/**
* Cipher information. Allows calling cipher functions
* in a generic way.
*/
typedef struct mbedtls_cipher_info_t
{
/** Full cipher identifier. For example,
* MBEDTLS_CIPHER_AES_256_CBC.
*/
mbedtls_cipher_type_t type;
/** The cipher mode. For example, MBEDTLS_MODE_CBC. */
mbedtls_cipher_mode_t mode;
/** The cipher key length, in bits. This is the
* default length for variable sized ciphers.
* Includes parity bits for ciphers like DES.
*/
unsigned int key_bitlen;
/** Name of the cipher. */
const char * name;
/** IV or nonce size, in Bytes.
* For ciphers that accept variable IV sizes,
* this is the recommended size.
*/
unsigned int iv_size;
/** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
* MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
* cipher supports variable IV or variable key sizes, respectively.
*/
int flags;
/** The block size, in Bytes. */
unsigned int block_size;
/** Struct for base cipher information and functions. */
const mbedtls_cipher_base_t *base;
} mbedtls_cipher_info_t;
/**
* Generic cipher context.
*/
typedef struct mbedtls_cipher_context_t
{
/** Information about the associated cipher. */
const mbedtls_cipher_info_t *cipher_info;
/** Key length to use. */
int key_bitlen;
/** Operation that the key of the context has been
* initialized for.
*/
mbedtls_operation_t operation;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** Padding functions to use, if relevant for
* the specific cipher mode.
*/
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
#endif
/** Buffer for input that has not been processed yet. */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Number of Bytes that have not been processed yet. */
size_t unprocessed_len;
/** 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. */
size_t iv_size;
/** The cipher-specific context. */
void *cipher_ctx;
#if defined(MBEDTLS_CMAC_C)
/** CMAC-specific context. */
mbedtls_cmac_context_t *cmac_ctx;
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/** Indicates whether the cipher operations should be performed
* by Mbed TLS' own crypto library or an external implementation
* of the PSA Crypto API.
* This is unset if the cipher context was established through
* mbedtls_cipher_setup(), and set if it was established through
* mbedtls_cipher_setup_psa().
*/
unsigned char psa_enabled;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
} mbedtls_cipher_context_t;
/**
* \brief This function retrieves the list of ciphers supported
* by the generic cipher module.
*
* For any cipher identifier in the returned list, you can
* obtain the corresponding generic cipher information structure
* via mbedtls_cipher_info_from_type(), which can then be used
* to prepare a cipher context via mbedtls_cipher_setup().
*
*
* \return A statically-allocated array of cipher identifiers
* of type cipher_type_t. The last entry is zero.
*/
const int *mbedtls_cipher_list( void );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher name.
*
* \param cipher_name Name of the cipher to search for. This must not be
* \c NULL.
*
* \return The cipher information structure associated with the
* given \p cipher_name.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher type.
*
* \param cipher_type Type of the cipher to search for.
*
* \return The cipher information structure associated with the
* given \p cipher_type.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
/**
* \brief This function retrieves the cipher-information
* structure associated with the given cipher ID,
* key size and mode.
*
* \param cipher_id The ID of the cipher to search for. For example,
* #MBEDTLS_CIPHER_ID_AES.
* \param key_bitlen The length of the key in bits.
* \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC.
*
* \return The cipher information structure associated with the
* given \p cipher_id.
* \return \c NULL if the associated cipher information is not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
int key_bitlen,
const mbedtls_cipher_mode_t mode );
/**
* \brief This function initializes a \p cipher_context as NONE.
*
* \param ctx The context to be initialized. This must not be \c NULL.
*/
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
/**
* \brief This function frees and clears the cipher-specific
* context of \p ctx. Freeing \p ctx itself remains the
* responsibility of the caller.
*
* \param ctx The context to be freed. If this is \c NULL, the
* function has no effect, otherwise this must point to an
* initialized context.
*/
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
/**
* \brief This function initializes a cipher context for
* use with the given cipher primitive.
*
* \param ctx The context to initialize. This must be initialized.
* \param cipher_info The cipher to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context fails.
*
* \internal Currently, the function also clears the structure.
* In future versions, the caller will be required to call
* mbedtls_cipher_init() on the structure first.
*/
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief This function initializes a cipher context for
* PSA-based use with the given cipher primitive.
*
* \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA.
*
* \param ctx The context to initialize. May not be \c NULL.
* \param cipher_info The cipher to use.
* \param taglen For AEAD ciphers, the length in bytes of the
* authentication tag to use. Subsequent uses of
* mbedtls_cipher_auth_encrypt() or
* mbedtls_cipher_auth_decrypt() must provide
* the same tag length.
* For non-AEAD ciphers, the value must be \c 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context fails.
*/
int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info,
size_t taglen );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/**
* \brief This function returns the block size of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The block size of the underlying cipher.
* \return \c 0 if \p ctx has not been initialized.
*/
static inline unsigned int mbedtls_cipher_get_block_size(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
return ctx->cipher_info->block_size;
}
/**
* \brief This function returns the mode of operation for
* the cipher. For example, MBEDTLS_MODE_CBC.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The mode of operation.
* \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_MODE_NONE;
return ctx->cipher_info->mode;
}
/**
* \brief This function returns the size of the IV or nonce
* of the cipher, in Bytes.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The recommended IV size if no IV has been set.
* \return \c 0 for ciphers not using an IV or a nonce.
* \return The actual size if an IV has been set.
*/
static inline int mbedtls_cipher_get_iv_size(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
if( ctx->iv_size != 0 )
return (int) ctx->iv_size;
return (int) ctx->cipher_info->iv_size;
}
/**
* \brief This function returns the type of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The type of the cipher.
* \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_CIPHER_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_CIPHER_NONE;
return ctx->cipher_info->type;
}
/**
* \brief This function returns the name of the given cipher
* as a string.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The name of the cipher.
* \return NULL if \p ctx has not been not initialized.
*/
static inline const char *mbedtls_cipher_get_name(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
if( ctx->cipher_info == NULL )
return 0;
return ctx->cipher_info->name;
}
/**
* \brief This function returns the key length of the cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The key length of the cipher in bits.
* \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
* initialized.
*/
static inline int mbedtls_cipher_get_key_bitlen(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_KEY_LENGTH_NONE;
return (int) ctx->cipher_info->key_bitlen;
}
/**
* \brief This function returns the operation of the given cipher.
*
* \param ctx The context of the cipher. This must be initialized.
*
* \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
* \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
*/
static inline mbedtls_operation_t mbedtls_cipher_get_operation(
const mbedtls_cipher_context_t *ctx )
{
MBEDTLS_INTERNAL_VALIDATE_RET(
ctx != NULL, MBEDTLS_OPERATION_NONE );
if( ctx->cipher_info == NULL )
return MBEDTLS_OPERATION_NONE;
return ctx->operation;
}
/**
* \brief This function sets the key to use with the given context.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param key The key to use. This must be a readable buffer of at
* least \p key_bitlen Bits.
* \param key_bitlen The key length to use, in Bits.
* \param operation The operation that the key will be used for:
* #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
const mbedtls_operation_t operation );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/**
* \brief This function sets the padding mode, for cipher modes
* that use padding.
*
* The default passing mode is PKCS7 padding.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param mode The padding mode.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if the selected padding mode is not supported.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* does not support padding.
*/
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode );
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/**
* \brief This function sets the initialization vector (IV)
* or nonce.
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, this function has no effect.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a cipher information structure.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
* must be a readable buffer of at least \p iv_len Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
*/
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv,
size_t iv_len );
/**
* \brief This function resets the cipher state.
*
* \param ctx The generic cipher context. This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
*/
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function adds additional data for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called exactly once, after
* mbedtls_cipher_reset().
*
* \param ctx The generic cipher context. This must be initialized.
* \param ad The additional data to use. This must be a readable
* buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad in Bytes.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic cipher update function. It encrypts or
* decrypts using the given cipher context. Writes as
* many block-sized blocks of data as possible to output.
* Any data that cannot be written immediately is either
* added to the next block, or flushed when
* mbedtls_cipher_finish() is called.
* Exception: For MBEDTLS_MODE_ECB, expects a single block
* in size. For example, 16 Bytes for AES.
*
* \note If the underlying cipher is used in GCM mode, all calls
* to this function, except for the last one before
* mbedtls_cipher_finish(), must have \p ilen as a
* multiple of the block size of the cipher.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx,
const unsigned char *input,
size_t ilen, unsigned char *output,
size_t *olen );
/**
* \brief The generic cipher finalization function. If data still
* needs to be flushed from an incomplete block, the data
* contained in it is padded to the size of
* the last block, and written to the \p output buffer.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param output The buffer to write data to. This needs to be a writable
* buffer of at least \p block_size Bytes.
* \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
/**
* \brief This function writes a tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized,
* bound to a key, and have just completed a cipher
* operation through mbedtls_cipher_finish() the tag for
* which should be written.
* \param tag The buffer to write the tag to. This must be a writable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to write.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len );
/**
* \brief This function checks the tag for AEAD ciphers.
* Currently supported with GCM and ChaCha20+Poly1305.
* This must be called after mbedtls_cipher_finish().
*
* \param ctx The generic cipher context. This must be initialized.
* \param tag The buffer holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to check.
*
* \return \c 0 on success.
* \return A specific error code on failure.
*/
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
/**
* \brief The generic all-in-one encryption/decryption function,
* for all ciphers except AEAD constructs.
*
* \param ctx The generic cipher context. This must be initialized.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size
* IV.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data in Bytes.
* \param output The buffer for the output data. This must be able to
* hold at least `ilen + block_size`. This must not be the
* same buffer as \p input.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
*
* \note Some ciphers do not use IVs nor nonce. For these
* ciphers, use \p iv = NULL and \p iv_len = 0.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
* expecting a full block but not receiving one.
* \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/**
* \brief The generic autenticated encryption (AEAD) function.
*
* \param ctx The generic cipher context. This must be initialized and
* bound to a key.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to authenticate. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data. This must be able to
* hold at least \p ilen Bytes.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
* \param tag The buffer for the authentication tag. This must be a
* writable buffer of at least \p tag_len Bytes.
* \param tag_len The desired length of the authentication tag.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len );
/**
* \brief The generic autenticated decryption (AEAD) function.
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext being
* used, making this interface safer.
*
* \param ctx The generic cipher context. This must be initialized and
* and bound to a key.
* \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
* This must be a readable buffer of at least \p iv_len
* Bytes.
* \param iv_len The IV length for ciphers with variable-size IV.
* This parameter is discarded by ciphers with fixed-size IV.
* \param ad The additional data to be authenticated. This must be a
* readable buffer of at least \p ad_len Bytes.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
* readable buffer of at least \p ilen Bytes.
* \param ilen The length of the input data.
* \param output The buffer for the output data.
* This must be able to hold at least \p ilen Bytes.
* \param olen The length of the output data, to be updated with the
* actual number of Bytes written. This must not be
* \c NULL.
* \param tag The buffer holding the authentication tag. This must be
* a readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the authentication tag.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
* parameter-verification failure.
* \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_H */

View File

@ -0,0 +1,152 @@
/**
* \file cipher_internal.h
*
* \brief Cipher wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
* Copyright (C) 2006-2015, 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_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Base cipher information. The non-mode specific functions and values.
*/
struct mbedtls_cipher_base_t
{
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
mbedtls_cipher_id_t cipher;
/** Encrypt using ECB */
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
const unsigned char *input, unsigned char *output );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/** Encrypt using CBC */
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/** Encrypt using CFB (Full length) */
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
unsigned char *iv, const unsigned char *input,
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,
unsigned char *nonce_counter, unsigned char *stream_block,
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,
const unsigned char *input, unsigned char *output );
#endif
/** Set key for encryption purposes */
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen );
/** Set key for decryption purposes */
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen);
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
};
typedef struct
{
mbedtls_cipher_type_t type;
const mbedtls_cipher_info_t *info;
} mbedtls_cipher_definition_t;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
typedef enum
{
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
/* use raw key material internally imported */
/* as a volatile key, and which hence need */
/* to destroy that key when the context is */
/* freed. */
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
/* which use a key provided by the */
/* user, and which hence will not be */
/* destroyed when the context is freed. */
} mbedtls_cipher_psa_key_ownership;
typedef struct
{
psa_algorithm_t alg;
psa_key_handle_t slot;
mbedtls_cipher_psa_key_ownership slot_state;
} mbedtls_cipher_context_psa;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_WRAP_H */

213
include/mbedtls/cmac.h Normal file
View File

@ -0,0 +1,213 @@
/**
* \file cmac.h
*
* \brief This file contains CMAC definitions and functions.
*
* The Cipher-based Message Authentication Code (CMAC) Mode for
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
*/
/*
* Copyright (C) 2015-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_CMAC_H
#define MBEDTLS_CMAC_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A /**< CMAC hardware accelerator failed. */
#define MBEDTLS_AES_BLOCK_SIZE 16
#define MBEDTLS_DES3_BLOCK_SIZE 8
#if defined(MBEDTLS_AES_C)
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /**< The longest block used by CMAC is that of AES. */
#else
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /**< The longest block used by CMAC is that of 3DES. */
#endif
#if !defined(MBEDTLS_CMAC_ALT)
/**
* The CMAC context structure.
*/
struct mbedtls_cmac_context_t
{
/** The internal state of the CMAC algorithm. */
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** Unprocessed data - either data that was not block aligned and is still
* pending processing, or the final block. */
unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** The length of data pending processing. */
size_t unprocessed_len;
};
#else /* !MBEDTLS_CMAC_ALT */
#include "cmac_alt.h"
#endif /* !MBEDTLS_CMAC_ALT */
/**
* \brief This function sets the CMAC key, and prepares to authenticate
* the input data.
* Must be called with an initialized cipher context.
*
* \param ctx The cipher context used for the CMAC operation, initialized
* as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
* MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
* or MBEDTLS_CIPHER_DES_EDE3_ECB.
* \param key The CMAC key.
* \param keybits The length of the CMAC key in bits.
* Must be supported by the cipher.
*
* \return \c 0 on success.
* \return A cipher-specific error code on failure.
*/
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
const unsigned char *key, size_t keybits );
/**
* \brief This function feeds an input buffer into an ongoing CMAC
* computation.
*
* It is called between mbedtls_cipher_cmac_starts() or
* mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish().
* Can be called repeatedly.
*
* \param ctx The cipher context used for the CMAC operation.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief This function finishes the CMAC operation, and writes
* the result to the output buffer.
*
* It is called after mbedtls_cipher_cmac_update().
* It can be followed by mbedtls_cipher_cmac_reset() and
* mbedtls_cipher_cmac_update(), or mbedtls_cipher_free().
*
* \param ctx The cipher context used for the CMAC operation.
* \param output The output buffer for the CMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output );
/**
* \brief This function prepares the authentication of another
* message with the same key as the previous CMAC
* operation.
*
* It is called after mbedtls_cipher_cmac_finish()
* and before mbedtls_cipher_cmac_update().
*
* \param ctx The cipher context used for the CMAC operation.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
/**
* \brief This function calculates the full generic CMAC
* on the input buffer with the provided key.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The CMAC result is calculated as
* output = generic CMAC(cmac key, input buffer).
*
*
* \param cipher_info The cipher information.
* \param key The CMAC key.
* \param keylen The length of the CMAC key in bits.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The buffer for the generic CMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_AES_C)
/**
* \brief This function implements the AES-CMAC-PRF-128 pseudorandom
* function, as defined in
* <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
* Message Authentication Code-Pseudo-Random Function-128
* (AES-CMAC-PRF-128) Algorithm for the Internet Key
* Exchange Protocol (IKE).</em>
*
* \param key The key to use.
* \param key_len The key length in Bytes.
* \param input The buffer holding the input data.
* \param in_len The length of the input data in Bytes.
* \param output The buffer holding the generated 16 Bytes of
* pseudorandom output.
*
* \return \c 0 on success.
*/
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
const unsigned char *input, size_t in_len,
unsigned char output[16] );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
/**
* \brief The CMAC checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_cmac_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CMAC_H */

View File

@ -441,6 +441,16 @@
* dependencies on them, and considering stronger message digests
* and ciphers instead.
*
* \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are
* enabled, then the deterministic ECDH signature functions pass the
* the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore
* alternative implementations should use the RNG only for generating
* the ephemeral key and nothing else. If this is not possible, then
* MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative
* implementation should be provided for mbedtls_ecdsa_sign_det_ext()
* (and for mbedtls_ecdsa_sign_det() too if backward compatibility is
* desirable).
*
*/
//#define MBEDTLS_MD2_PROCESS_ALT
//#define MBEDTLS_MD4_PROCESS_ALT
@ -680,6 +690,13 @@
#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
#define MBEDTLS_CIPHER_PADDING_ZEROS
/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
*
* Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
* By default, CTR_DRBG uses a 256-bit key.
*/
//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
/**
* \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
*
@ -1219,6 +1236,21 @@
*/
//#define MBEDTLS_ENTROPY_NV_SEED
/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
*
* In PSA key storage, encode the owner of the key.
*
* This is only meaningful when building the library as part of a
* multi-client service. When you activate this option, you must provide
* an implementation of the type psa_key_owner_id_t and a translation
* from psa_key_file_id_t to file name in all the storage backends that
* you wish to support.
*
* Note that this option is meant for internal use only and may be removed
* without notice.
*/
//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
/**
* \def MBEDTLS_MEMORY_DEBUG
*
@ -1336,6 +1368,28 @@
*/
//#define MBEDTLS_SHA256_SMALLER
/**
* \def MBEDTLS_SHA512_SMALLER
*
* Enable an implementation of SHA-512 that has lower ROM footprint but also
* lower performance.
*
* Uncomment to enable the smaller implementation of SHA512.
*/
//#define MBEDTLS_SHA512_SMALLER
/**
* \def MBEDTLS_SHA512_NO_SHA384
*
* Disable the SHA-384 option of the SHA-512 module. Use this to save some
* code size on devices that don't use SHA-384.
*
* Requires: MBEDTLS_SHA512_C
*
* Uncomment to disable SHA-384
*/
//#define MBEDTLS_SHA512_NO_SHA384
/**
* \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
*
@ -1350,48 +1404,6 @@
*/
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
/**
* \def MBEDTLS_SSL_RECORD_CHECKING
*
* Enable the function mbedtls_ssl_check_record() which can be used to check
* the validity and authenticity of an incoming record, to verify that it has
* not been seen before. These checks are performed without modifying the
* externally visible state of the SSL context.
*
* See mbedtls_ssl_check_record() for more information.
*
* Uncomment to enable support for record checking.
*/
#define MBEDTLS_SSL_RECORD_CHECKING
/**
* \def MBEDTLS_SSL_DTLS_CONNECTION_ID
*
* Enable support for the DTLS Connection ID extension
* (version draft-ietf-tls-dtls-connection-id-05,
* https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
* which allows to identify DTLS connections across changes
* in the underlying transport.
*
* Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`,
* `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`.
* See the corresponding documentation for more information.
*
* \warning The Connection ID extension is still in draft state.
* We make no stability promises for the availability
* or the shape of the API controlled by this option.
*
* The maximum lengths of outgoing and incoming CIDs can be configured
* through the options
* - MBEDTLS_SSL_CID_OUT_LEN_MAX
* - MBEDTLS_SSL_CID_IN_LEN_MAX.
*
* Requires: MBEDTLS_SSL_PROTO_DTLS
*
* Uncomment to enable the Connection ID extension.
*/
//#define MBEDTLS_SSL_DTLS_CONNECTION_ID
/**
* \def MBEDTLS_SSL_ASYNC_PRIVATE
*
@ -1403,33 +1415,6 @@
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/**
* \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
*
* Enable serialization of the TLS context structures, through use of the
* functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
*
* This pair of functions allows one side of a connection to serialize the
* context associated with the connection, then free or re-use that context
* while the serialized state is persisted elsewhere, and finally deserialize
* that state to a live context for resuming read/write operations on the
* connection. From a protocol perspective, the state of the connection is
* unaffected, in particular this is entirely transparent to the peer.
*
* Note: this is distinct from TLS session resumption, which is part of the
* protocol and fully visible by the peer. TLS session resumption enables
* establishing new connections associated to a saved session with shorter,
* lighter handshakes, while context serialization is a local optimization in
* handling a single, potentially long-lived connection.
*
* Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
* saved after the handshake to allow for more efficient serialization, so if
* you don't need this feature you'll save RAM by disabling it.
*
* Comment to disable the context serialization APIs.
*/
#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
/**
* \def MBEDTLS_SSL_DEBUG_ALL
*
@ -1831,14 +1816,14 @@
* Make the X.509 and TLS library use PSA for cryptographic operations, and
* enable new APIs for using keys handled by PSA Crypto.
*
* \note Development of this option is currently in progress, and parts
* of the X.509 and TLS modules are not ported to PSA yet. However, these parts
* \note Development of this option is currently in progress, and parts of Mbed
* TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts
* will still continue to work as usual, so enabling this option should not
* break backwards compatibility.
*
* \warning The PSA Crypto API is in beta stage. While you're welcome to
* experiment using it, incompatible API changes are still possible, and some
* parts may not have reached the same quality as the rest of Mbed TLS yet.
* \warning Support for PSA is still an experimental feature.
* Any public API that depends on this option may change
* at any time until this warning is removed.
*
* \warning This option enables new Mbed TLS APIs that are dependent on the
* PSA Crypto API, so can't come with the same stability guarantees as the
@ -2335,14 +2320,18 @@
* Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
*
*/
//#define MBEDTLS_CMAC_C
#define MBEDTLS_CMAC_C
/**
* \def MBEDTLS_CTR_DRBG_C
*
* Enable the CTR_DRBG AES-based random generator.
* The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
*
* \note To achieve a 256-bit security strength with CTR_DRBG,
* you must use AES-256 *and* use sufficient entropy.
* See ctr_drbg.h for more details.
*
* Module: library/ctr_drbg.c
* Caller:
@ -2510,11 +2499,11 @@
/**
* \def MBEDTLS_GCM_C
*
* Enable the Galois/Counter Mode (GCM) for AES.
* Enable the Galois/Counter Mode (GCM).
*
* Module: library/gcm.c
*
* Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
* Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C
*
* This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
* requisites are enabled as well.
@ -2891,25 +2880,41 @@
* experiment using it, incompatible API changes are still possible, and some
* parts may not have reached the same quality as the rest of Mbed TLS yet.
*
* Module: crypto/library/psa_crypto.c
* Module: library/psa_crypto.c
*
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
*
*/
#define MBEDTLS_PSA_CRYPTO_C
/**
* \def MBEDTLS_PSA_CRYPTO_SE_C
*
* Enable secure element support in the Platform Security Architecture
* cryptography API.
*
* \warning This feature is not yet suitable for production. It is provided
* for API evaluation and testing purposes only.
*
* Module: library/psa_crypto_se.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
*
*/
//#define MBEDTLS_PSA_CRYPTO_SE_C
/**
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
*
* Enable the Platform Security Architecture persistent key storage.
*
* Module: crypto/library/psa_crypto_storage.c
* Module: library/psa_crypto_storage.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C,
* either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
* the PSA ITS interface
*/
//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
/**
* \def MBEDTLS_PSA_ITS_FILE_C
@ -2917,12 +2922,11 @@
* Enable the emulation of the Platform Security Architecture
* Internal Trusted Storage (PSA ITS) over files.
*
* Module: crypto/library/psa_its_file.c
* Module: library/psa_its_file.c
*
* Requires: MBEDTLS_FS_IO
*
*/
//#define MBEDTLS_PSA_ITS_FILE_C
#define MBEDTLS_PSA_ITS_FILE_C
/**
* \def MBEDTLS_RIPEMD160_C
@ -3279,7 +3283,6 @@
//#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 */
@ -3424,37 +3427,6 @@
*/
//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384
/** \def MBEDTLS_SSL_CID_IN_LEN_MAX
*
* The maximum length of CIDs used for incoming DTLS messages.
*
*/
//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32
/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX
*
* The maximum length of CIDs used for outgoing DTLS messages.
*
*/
//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32
/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY
*
* This option controls the use of record plaintext padding
* when using the Connection ID extension in DTLS 1.2.
*
* The padding will always be chosen so that the length of the
* padded plaintext is a multiple of the value of this option.
*
* Note: A value of \c 1 means that no padding will be used
* for outgoing records.
*
* Note: On systems lacking division instructions,
* a power of two should be preferred.
*
*/
//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16
/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
*
* Maximum length (in bytes) of outgoing plaintext fragments.
@ -3530,7 +3502,7 @@
* on it, and considering stronger message digests instead.
*
*/
//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
/**
* Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake

562
include/mbedtls/ctr_drbg.h Normal file
View File

@ -0,0 +1,562 @@
/**
* \file ctr_drbg.h
*
* \brief This file contains definitions and functions for the
* CTR_DRBG pseudorandom generator.
*
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher
* in counter mode operation, as defined in <em>NIST SP 800-90A:
* Recommendation for Random Number Generation Using Deterministic Random
* Bit Generators</em>.
*
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function.
*
* The security strength as defined in NIST SP 800-90A is
* 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
* and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
* kept at its default value (and not overridden in config.h) and that the
* DRBG instance is set up with default parameters.
* See the documentation of mbedtls_ctr_drbg_seed() for more
* information.
*/
/*
* Copyright (C) 2006-2019, 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_CTR_DRBG_H
#define MBEDTLS_CTR_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< The requested random buffer length is too big. */
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< The input (entropy + additional data) is too large. */
#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. */
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
#define MBEDTLS_CTR_DRBG_KEYSIZE 16
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 16 bytes (128 bits)
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
*/
#else
#define MBEDTLS_CTR_DRBG_KEYSIZE 32
/**< The key size in bytes used by the cipher.
*
* Compile-time choice: 32 bytes (256 bits)
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
*/
#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). */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them using the compiler command
* line.
* \{
*/
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
*
* \brief The amount of entropy used per seed by default, in bytes.
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
/** This is 48 bytes because the entropy module uses SHA-512
* (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled).
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
/** This is 32 bytes because the entropy module uses SHA-256
* (the SHA512 module is disabled or
* \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled).
*/
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
/** \warning To achieve a 256-bit security strength, you must pass a nonce
* to mbedtls_ctr_drbg_seed().
*/
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
/**< The interval before reseed is performed by default. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256
/**< The maximum number of additional input Bytes. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024
/**< The maximum number of requested Bytes per call. */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
/**< The maximum size of seed or reseed buffer in bytes. */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_CTR_DRBG_PR_OFF 0
/**< Prediction resistance is disabled. */
#define MBEDTLS_CTR_DRBG_PR_ON 1
/**< Prediction resistance is enabled. */
#ifdef __cplusplus
extern "C" {
#endif
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
/** The default length of the nonce read from the entropy source.
*
* This is \c 0 because a single read from the entropy source is sufficient
* to include a nonce.
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
#else
/** The default length of the nonce read from the entropy source.
*
* This is half of the default entropy length because a single read from
* the entropy source does not provide enough material to form a nonce.
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
*/
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2
#endif
/**
* \brief The CTR_DRBG context structure.
*/
typedef struct mbedtls_ctr_drbg_context
{
unsigned char counter[16]; /*!< The counter (V). */
int reseed_counter; /*!< The reseed counter.
* This is the number of requests that have
* been made since the last (re)seeding,
* minus one.
* Before the initial seeding, this field
* contains the amount of entropy in bytes
* to use as a nonce for the initial seeding,
* or -1 if no nonce length has been explicitly
* set (see mbedtls_ctr_drbg_set_nonce_len()).
*/
int prediction_resistance; /*!< This determines whether prediction
resistance is enabled, that is
whether to systematically reseed before
each random generation. */
size_t entropy_len; /*!< The amount of entropy grabbed on each
seed or reseed operation, in bytes. */
int reseed_interval; /*!< The reseed interval.
* This is the maximum number of requests
* that can be made between reseedings. */
mbedtls_aes_context aes_ctx; /*!< The AES context. */
/*
* Callbacks (Entropy)
*/
int (*f_entropy)(void *, unsigned char *, size_t);
/*!< The entropy callback function. */
void *p_entropy; /*!< The context for the entropy function. */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
}
mbedtls_ctr_drbg_context;
/**
* \brief This function initializes the CTR_DRBG context,
* and prepares it for mbedtls_ctr_drbg_seed()
* or mbedtls_ctr_drbg_free().
*
* \param ctx The CTR_DRBG context to initialize.
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
/**
* \brief This function seeds and sets up the CTR_DRBG
* entropy source for future reseeds.
*
* A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
* The entropy nonce length is:
* - \c 0 if the entropy length is at least 3/2 times the entropy length,
* which guarantees that the security strength is the maximum permitted
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
* - Half the entropy length otherwise.
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
* With the default entropy length, the entropy nonce length is
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
*
* You can provide a nonce and personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
* See SP 800-90A §8.6.7 for more details about nonces.
*
* The _seed_material_ value passed to the derivation function in
* the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2
* is the concatenation of the following strings:
* - A string obtained by calling \p f_entropy function for the entropy
* length.
*/
#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
/**
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
* obtained by calling \p f_entropy function for the specified length.
*/
#else
/**
* - A string obtained by calling \p f_entropy function for the entropy nonce
* length. If the entropy nonce length is \c 0, this function does not
* make a second call to \p f_entropy.
*/
#endif
/**
* - The \p custom string.
*
* \note To achieve the nominal security strength permitted
* by CTR_DRBG, the entropy length must be:
* - at least 16 bytes for a 128-bit strength
* (maximum achievable strength when using AES-128);
* - at least 32 bytes for a 256-bit strength
* (maximum achievable strength when using AES-256).
*
* In addition, if you do not pass a nonce in \p custom,
* the sum of the entropy length
* and the entropy nonce length must be:
* - at least 24 bytes for a 128-bit strength
* (maximum achievable strength when using AES-128);
* - at least 48 bytes for a 256-bit strength
* (maximum achievable strength when using AES-256).
*
* \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
* After a successful call to mbedtls_ctr_drbg_seed(),
* you may not call mbedtls_ctr_drbg_seed() again on
* the same context unless you call
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
* again first.
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a buffer size
* less than or equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief This function clears CTR_CRBG context data.
*
* \param ctx The CTR_DRBG context to clear.
*/
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
/**
* \brief This function turns prediction resistance on or off.
* The default value is off.
*
* \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_ctr_drbg_random_with_add()
* or mbedtls_ctr_drbg_random().
* Only use this if your entropy source has sufficient
* throughput.
*
* \param ctx The CTR_DRBG context.
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
*/
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
int resistance );
/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
*
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
*
* \note The security strength of CTR_DRBG is bounded by the
* entropy length. Thus:
* - When using AES-256
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
* which is the default),
* \p len must be at least 32 (in bytes)
* to achieve a 256-bit strength.
* - When using AES-128
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
* \p len must be at least 16 (in bytes)
* to achieve a 128-bit strength.
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* and at most the maximum length accepted by the
* entropy function that is set in the context.
*/
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief This function sets the amount of entropy grabbed
* as a nonce for the initial seeding.
*
* Call this function before calling mbedtls_ctr_drbg_seed() to read
* a nonce from the entropy source during the initial seeding.
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab for the nonce, in bytes.
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
* and at most the maximum length accepted by the
* entropy function that is set in the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
* more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
* if the initial seeding has already taken place.
*/
int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief This function sets the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
*
* \param ctx The CTR_DRBG context.
* \param interval The reseed interval.
*/
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
int interval );
/**
* \brief This function reseeds the CTR_DRBG context, that is
* extracts data from the entropy source.
*
* \param ctx The CTR_DRBG context.
* \param additional Additional data to add to the state. Can be \c NULL.
* \param len The length of the additional data.
* This must be less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. This must not be
* \c NULL unless \p add_len is \c 0.
* \param add_len Length of \p additional in bytes. This must be at
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
* \p add_len is more than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
* \return An error from the underlying AES cipher on failure.
*/
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
/**
* \brief This function updates a CTR_DRBG instance with additional
* data and uses it to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* \param additional Additional data to update. Can be \c NULL, in which
* case the additional data is empty regardless of
* the value of \p add_len.
* \param add_len The length of the additional data
* if \p additional is not \c NULL.
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
* and less than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
* where \c entropy_len is the entropy length
* configured for the context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
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 );
/**
* \brief This function uses CTR_DRBG to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
*
* \param p_rng The CTR_DRBG context. This must be a pointer to a
* #mbedtls_ctr_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
*/
int mbedtls_ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function updates the state of the CTR_DRBG context.
*
* \deprecated Superseded by mbedtls_ctr_drbg_update_ret()
* in 2.16.0.
*
* \note If \p add_len is greater than
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
* The remaining Bytes are silently discarded.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with.
* \param add_len Length of \p additional data.
*/
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional,
size_t add_len );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function writes a seed file.
*
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure.
*/
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
/**
* \brief This function reads and updates a seed file. The seed
* is added to this instance.
*
* \param ctx The CTR_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
*/
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The CTR_DRBG checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_ctr_drbg_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* ctr_drbg.h */

356
include/mbedtls/des.h Normal file
View File

@ -0,0 +1,356 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
/*
* Copyright (C) 2006-2015, 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_DES_H
#define MBEDTLS_DES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED -0x0033 /**< DES hardware accelerator failed. */
#define MBEDTLS_DES_KEY_SIZE 8
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_DES_ALT)
// Regular implementation
//
/**
* \brief DES context structure
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
typedef struct mbedtls_des_context
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct mbedtls_des3_context
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
#else /* MBEDTLS_DES_ALT */
#include "des_alt.h"
#endif /* MBEDTLS_DES_ALT */
/**
* \brief Initialize DES context
*
* \param ctx DES context to be initialized
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_init( mbedtls_des_context *ctx );
/**
* \brief Clear DES context
*
* \param ctx DES context to be cleared
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_free( mbedtls_des_context *ctx );
/**
* \brief Initialize Triple-DES context
*
* \param ctx DES3 context to be initialized
*/
void mbedtls_des3_init( mbedtls_des3_context *ctx );
/**
* \brief Clear Triple-DES context
*
* \param ctx DES3 context to be cleared
*/
void mbedtls_des3_free( mbedtls_des3_context *ctx );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx 3DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief Internal function for key expansion.
* (Only exposed to allow overriding it,
* see MBEDTLS_DES_SETKEY_ALT)
*
* \param SK Round keys
* \param key Base key
*
* \warning DES is considered a weak cipher and its use constitutes a
* security risk. We recommend considering stronger ciphers
* instead.
*/
void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_des_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* des.h */

1094
include/mbedtls/dhm.h Normal file

File diff suppressed because it is too large Load Diff

448
include/mbedtls/ecdh.h Normal file
View File

@ -0,0 +1,448 @@
/**
* \file ecdh.h
*
* \brief This file contains ECDH definitions and functions.
*
* The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
* key agreement protocol allowing two parties to establish a shared
* secret over an insecure channel. Each party must have an
* elliptic-curve publicprivate key pair.
*
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
* Cryptography</em>.
*/
/*
* 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_ECDH_H
#define MBEDTLS_ECDH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/ecp.h"
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
#undef MBEDTLS_ECDH_LEGACY_CONTEXT
#include "everest/everest.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Defines the source of the imported EC key.
*/
typedef enum
{
MBEDTLS_ECDH_OURS, /**< Our key. */
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
} mbedtls_ecdh_side;
#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
/**
* Defines the ECDH implementation used.
*
* Later versions of the library may add new variants, therefore users should
* not make any assumptions about them.
*/
typedef enum
{
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */
#endif
} mbedtls_ecdh_variant;
/**
* The context used by the default ECDH implementation.
*
* Later versions might change the structure of this context, therefore users
* should not make any assumptions about the structure of
* mbedtls_ecdh_context_mbed.
*/
typedef struct mbedtls_ecdh_context_mbed
{
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< The shared secret. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
#endif
} mbedtls_ecdh_context_mbed;
#endif
/**
*
* \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 mbedtls_ecdh_context
{
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
mbedtls_ecp_group grp; /*!< The elliptic curve used. */
mbedtls_mpi d; /*!< The private key. */
mbedtls_ecp_point Q; /*!< The public key. */
mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */
mbedtls_mpi z; /*!< The shared secret. */
int point_format; /*!< The format of point export in TLS messages. */
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_ECP_RESTARTABLE */
#else
uint8_t point_format; /*!< The format of point export in TLS messages
as defined in RFC 4492. */
mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */
union
{
mbedtls_ecdh_context_mbed mbed_ecdh;
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
mbedtls_ecdh_context_everest everest_ecdh;
#endif
} ctx; /*!< Implementation-specific context. The
context in use is specified by the \c var
field. */
#if defined(MBEDTLS_ECP_RESTARTABLE)
uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of
an alternative implementation not supporting
restartable mode must return
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
if this flag is set. */
#endif /* MBEDTLS_ECP_RESTARTABLE */
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
}
mbedtls_ecdh_context;
/**
* \brief Check whether a given group can be used for ECDH.
*
* \param gid The ECP group ID to check.
*
* \return \c 1 if the group can be used, \c 0 otherwise
*/
int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid );
/**
* \brief This function generates an ECDH keypair on an elliptic
* curve.
*
* This function performs the first of two core computations
* implemented during the ECDH key exchange. The second core
* computation is performed by mbedtls_ecdh_compute_shared().
*
* \see ecp.h
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param d The destination MPI (private key).
* This must be initialized.
* \param Q The destination point (public key).
* This must be initialized.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \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),
void *p_rng );
/**
* \brief This function computes the shared secret.
*
* This function performs the second of two core computations
* implemented during the ECDH key exchange. The first core
* computation is performed by mbedtls_ecdh_gen_public().
*
* \see ecp.h
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \param grp The ECP group to use. This must be initialized and have
* domain parameters loaded, for example through
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
* \param z The destination MPI (shared secret).
* This must be initialized.
* \param Q The public key from another party.
* This must be initialized.
* \param d Our secret exponent (private key).
* This must be initialized.
* \param f_rng The RNG function. This may be \c NULL if randomization
* of intermediate results during the ECP computations is
* not needed (discouraged). See the documentation of
* mbedtls_ecp_mul() for more.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't need a
* context argument.
*
* \return \c 0 on success.
* \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,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function initializes an ECDH context.
*
* \param ctx The ECDH context to initialize. This must not be \c NULL.
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/**
* \brief This function sets up the ECDH context with the information
* given.
*
* This function should be called after mbedtls_ecdh_init() but
* before mbedtls_ecdh_make_params(). There is no need to call
* this function before mbedtls_ecdh_read_params().
*
* This is the first function used by a TLS server for ECDHE
* ciphersuites.
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param grp_id The group id of the group to set up the context for.
*
* \return \c 0 on success.
*/
int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
mbedtls_ecp_group_id grp_id );
/**
* \brief This function frees a context.
*
* \param ctx The context to free. This may be \c NULL, in which
* case this function does nothing. If it is not \c NULL,
* it must point to an initialized ECDH context.
*/
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
/**
* \brief This function generates an EC key pair and exports its
* in the format used in a TLS ServerKeyExchange handshake
* message.
*
* This is the second function used by a TLS server for ECDHE
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param olen The address at which to store the number of Bytes written.
* \param buf The destination buffer. This must be a writable buffer of
* length \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \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 error code on failure.
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses the ECDHE parameters in a
* TLS ServerKeyExchange handshake message.
*
* \note In a TLS handshake, this is the how the client
* sets up its ECDHE context from the server's public
* ECDHE key material.
*
* \see ecp.h
*
* \param ctx The ECDHE context to use. This must be initialized.
* \param buf On input, \c *buf must be the start of the input buffer.
* On output, \c *buf is updated to point to the end of the
* data that has been read. On success, this is the first byte
* past the end of the ServerKeyExchange parameters.
* On error, this is the point at which an error has been
* detected, which is usually not useful except to debug
* failures.
* \param end The end of the input buffer.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*
*/
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf,
const unsigned char *end );
/**
* \brief This function sets up an ECDH context from an EC key.
*
* It is used by clients and servers in place of the
* ServerKeyEchange for static ECDH, and imports ECDH
* parameters from the EC key information of a certificate.
*
* \see ecp.h
*
* \param ctx The ECDH context to set up. This must be initialized.
* \param key The EC key to use. This must be initialized.
* \param side Defines the source of the key. Possible values are:
* - #MBEDTLS_ECDH_OURS: The key is ours.
* - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
*
* \return \c 0 on success.
* \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,
mbedtls_ecdh_side side );
/**
* \brief This function generates a public key and exports it
* as a TLS ClientKeyExchange payload.
*
* This is the second function used by a TLS client for ECDH(E)
* ciphersuites.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, the latter usually by
* mbedtls_ecdh_read_params().
* \param olen The address at which to store the number of Bytes written.
* This must not be \c NULL.
* \param buf The destination buffer. This must be a writable buffer
* of length \p blen Bytes.
* \param blen The size of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \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 error code on failure.
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function parses and processes the ECDHE payload of a
* TLS ClientKeyExchange message.
*
* This is the third function used by a TLS server for ECDH(E)
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
* mbedtls_ecdh_make_params().)
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param buf The pointer to the ClientKeyExchange payload. This must
* be a readable buffer of length \p blen Bytes.
* \param blen The length of the input buffer \p buf in Bytes.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen );
/**
* \brief This function derives and exports the shared secret.
*
* This is the last function used by both TLS client
* and servers.
*
* \note If \p f_rng is not NULL, it is used to implement
* countermeasures against side-channel attacks.
* For more information, see mbedtls_ecp_mul().
*
* \see ecp.h
* \param ctx The ECDH context to use. This must be initialized
* and have its own private key generated and the peer's
* public key imported.
* \param olen The address at which to store the total number of
* Bytes written on success. This must not be \c NULL.
* \param buf The buffer to write the generated shared key to. This
* must be a writable buffer of size \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function, for blinding purposes. This may
* b \c NULL if blinding isn't needed.
* \param p_rng The RNG context. This may be \c NULL if \p f_rng
* doesn't need a context argument.
*
* \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 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 to use. This must be initialized.
*/
void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif
#endif /* ecdh.h */

628
include/mbedtls/ecdsa.h Normal file
View File

@ -0,0 +1,628 @@
/**
* \file ecdsa.h
*
* \brief This file contains ECDSA definitions and functions.
*
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
* <em>Standards for Efficient Cryptography Group (SECG):
* SEC1 Elliptic Curve Cryptography</em>.
* The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
* Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
*
*/
/*
* 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_ECDSA_H
#define MBEDTLS_ECDSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
/**
* \brief Maximum ECDSA signature size for a given curve bit size
*
* \param bits Curve size in bits
* \return Maximum signature size in bytes
*
* \note This macro returns a compile-time constant if its argument
* is one. It may evaluate its argument multiple times.
*/
/*
* Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* For each of r and s, the value (V) may include an extra initial "0" bit.
*/
#define MBEDTLS_ECDSA_MAX_SIG_LEN( bits ) \
( /*T,L of SEQUENCE*/ ( ( bits ) >= 61 * 8 ? 3 : 2 ) + \
/*T,L of r,s*/ 2 * ( ( ( bits ) >= 127 * 8 ? 3 : 2 ) + \
/*V of r,s*/ ( ( bits ) + 8 ) / 8 ) )
/** The maximal size of an ECDSA signature in Bytes. */
#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN( MBEDTLS_ECP_MAX_BITS )
#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 checks whether a given group can be used
* for ECDSA.
*
* \param gid The ECP group ID to check.
*
* \return \c 1 if the group can be used, \c 0 otherwise
*/
int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid );
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
*
* \note The deterministic version implemented in
* mbedtls_ecdsa_sign_det() is usually preferred.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated
* as defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized.
* \param buf The content to be signed. This is usually the hash of
* the original data to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX
* or \c MBEDTLS_MPI_XXX error code on failure.
*/
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 );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
*
* For more information, see <em>RFC-6979: Deterministic
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \warning Since the output of the internal RNG is always the same for
* the same key and message, this limits the efficiency of
* blinding and leaks information through side channels. For
* secure behavior use mbedtls_ecdsa_sign_det_ext() instead.
*
* (Optimally the blinding is a random value that is different
* on every execution. In this case the blinding is still
* random from the attackers perspective, but is the same on
* each execution. This means that this blinding does not
* prevent attackers from recovering secrets by combining
* several measurement traces, but may prevent some attacks
* that exploit relationships between secret data.)
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
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 ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
*
* For more information, see <em>RFC-6979: Deterministic
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param grp The context for the elliptic curve to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param r The MPI context in which to store the first part
* the signature. This must be initialized.
* \param s The MPI context in which to store the second part
* the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
* \param f_rng_blind The RNG function used for blinding. This must not be
* \c NULL.
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure.
*/
int mbedtls_ecdsa_sign_det_ext( 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,
int (*f_rng_blind)(void *, unsigned char *, size_t),
void *p_rng_blind );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief This function verifies the ECDSA signature of a
* previously-hashed message.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
*
* \see ecp.h
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
* \param buf The hashed content that was signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param Q The public key to use for verification. This must be
* initialized and setup.
* \param r The first integer of the signature.
* This must be initialized.
* \param s The second integer of the signature.
* This must be initialized.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
* is invalid.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure for any other reason.
*/
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);
/**
* \brief This function computes the ECDSA signature and writes it
* to a buffer, serialized as defined in <em>RFC-4492:
* Elliptic Curve Cryptography (ECC) Cipher Suites for
* Transport Layer Security (TLS)</em>.
*
* \warning It is not thread-safe to use the same context in
* multiple threads.
*
* \note The deterministic version is used if
* #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
* information, see <em>RFC-6979: Deterministic Usage
* of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is used only for blinding and may be set to \c NULL, but
* doing so is DEPRECATED.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
* \return \c 0 on success.
* \return An \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( 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 );
/**
* \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 to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message.
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \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)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function computes an ECDSA signature and writes
* it to a buffer, serialized as defined in <em>RFC-4492:
* Elliptic Curve Cryptography (ECC) Cipher Suites for
* Transport Layer Security (TLS)</em>.
*
* The deterministic version is defined in <em>RFC-6979:
* Deterministic Usage of the Digital Signature Algorithm (DSA)
* and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
*
* \warning It is not thread-safe to use the same context in
* multiple threads.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.3, step 5.
*
* \see ecp.h
*
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in
* Mbed TLS version 2.0 and later.
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param hash The message hash to be signed. This must be a readable
* buffer of length \p blen Bytes.
* \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param md_alg The message digest that was used to hash the message.
*
* \return \c 0 on success.
* \return An \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_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief This function reads and verifies an ECDSA signature.
*
* \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
* 4.1.4, step 3.
*
* \see ecp.h
*
* \param ctx The ECDSA context to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
*
* \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 An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
* error code on failure for any other reason.
*/
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 to use. This must be initialized
* and have a group and public key bound to it.
* \param hash The message hash that was signed. This must be a readable
* buffer of length \p size Bytes.
* \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
*
* \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.
*
* \see ecp.h
*
* \param ctx The ECDSA context to store the keypair in.
* This must be initialized.
* \param gid The elliptic curve to use. One of the various
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief This function sets up an ECDSA context from an EC key pair.
*
* \see ecp.h
*
* \param ctx The ECDSA context to setup. This must be initialized.
* \param key The EC key to use. This must be initialized and hold
* a private-public key pair or a public key. In the former
* case, the ECDSA context may be used for signature creation
* and verification after this call. In the latter case, it
* may be used for signature verification.
*
* \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
const mbedtls_ecp_keypair *key );
/**
* \brief This function initializes an ECDSA context.
*
* \param ctx The ECDSA context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/**
* \brief This function frees an ECDSA context.
*
* \param ctx The ECDSA context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context.
*
* \param ctx The restart context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
/**
* \brief Free the components of a restart context.
*
* \param ctx The restart context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */
#ifdef __cplusplus
}
#endif
#endif /* ecdsa.h */

277
include/mbedtls/ecjpake.h Normal file
View File

@ -0,0 +1,277 @@
/**
* \file ecjpake.h
*
* \brief Elliptic curve J-PAKE
*/
/*
* Copyright (C) 2006-2015, 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_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
/*
* J-PAKE is a password-authenticated key exchange that allows deriving a
* strong shared secret from a (potentially low entropy) pre-shared
* passphrase, with forward secrecy and mutual authentication.
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
*
* This file implements the Elliptic Curve variant of J-PAKE,
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
* available to members of the Thread Group http://threadgroup.org/
*
* As the J-PAKE algorithm is inherently symmetric, so is our API.
* Each party needs to send its first round message, in any order, to the
* other party, then each sends its second round message, in any order.
* The payloads are serialized in a way suitable for use in TLS, but could
* also be use outside TLS.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Roles in the EC J-PAKE exchange
*/
typedef enum {
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
MBEDTLS_ECJPAKE_SERVER, /**< Server */
} mbedtls_ecjpake_role;
#if !defined(MBEDTLS_ECJPAKE_ALT)
/**
* EC J-PAKE context structure.
*
* J-PAKE is a symmetric protocol, except for the identifiers used in
* Zero-Knowledge Proofs, and the serialization of the second message
* (KeyExchange) as defined by the Thread spec.
*
* In order to benefit from this symmetry, we choose a different naming
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct mbedtls_ecjpake_context
{
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
} mbedtls_ecjpake_context;
#else /* MBEDTLS_ECJPAKE_ALT */
#include "ecjpake_alt.h"
#endif /* MBEDTLS_ECJPAKE_ALT */
/**
* \brief Initialize an ECJPAKE context.
*
* \param ctx The ECJPAKE context to initialize.
* This must not be \c NULL.
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
/**
* \brief Set up an ECJPAKE context for use.
*
* \note Currently the only values for hash/curve allowed by the
* standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
*
* \param ctx The ECJPAKE context to set up. This must be initialized.
* \param role The role of the caller. This must be either
* #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
* \param hash The identifier of the hash function to use,
* for example #MBEDTLS_MD_SHA256.
* \param curve The identifier of the elliptic curve to use,
* for example #MBEDTLS_ECP_DP_SECP256R1.
* \param secret The pre-shared secret (passphrase). This must be
* a readable buffer of length \p len Bytes. It need
* only be valid for the duration of this call.
* \param len The length of the pre-shared secret \p secret.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
mbedtls_ecjpake_role role,
mbedtls_md_type_t hash,
mbedtls_ecp_group_id curve,
const unsigned char *secret,
size_t len );
/**
* \brief Check if an ECJPAKE context is ready for use.
*
* \param ctx The ECJPAKE context to check. This must be
* initialized.
*
* \return \c 0 if the context is ready for use.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
/**
* \brief Generate and write the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes).
*
* \param ctx The ECJPAKE context to use. This must be
* initialized and set up.
* \param buf The buffer to write the contents to. This must be a
* writable buffer of length \p len Bytes.
* \param len The length of \p buf in Bytes.
* \param olen The address at which to store the total number
* of Bytes written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes).
*
* \param ctx The ECJPAKE context to use. This must be initialized
* and set up.
* \param buf The buffer holding the first round message. This must
* be a readable buffer of length \p len Bytes.
* \param len The length in Bytes of \p buf.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Generate and write the second round message
* (TLS: contents of the Client/ServerKeyExchange).
*
* \param ctx The ECJPAKE context to use. This must be initialized,
* set up, and already have performed round one.
* \param buf The buffer to write the round two contents to.
* This must be a writable buffer of length \p len Bytes.
* \param len The size of \p buf in Bytes.
* \param olen The address at which to store the total number of Bytes
* written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the second round message
* (TLS: contents of the Client/ServerKeyExchange).
*
* \param ctx The ECJPAKE context to use. This must be initialized
* and set up and already have performed round one.
* \param buf The buffer holding the second round message. This must
* be a readable buffer of length \p len Bytes.
* \param len The length in Bytes of \p buf.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Derive the shared secret
* (TLS: Pre-Master Secret).
*
* \param ctx The ECJPAKE context to use. This must be initialized,
* set up and have performed both round one and two.
* \param buf The buffer to write the derived secret to. This must
* be a writable buffer of length \p len Bytes.
* \param len The length of \p buf in Bytes.
* \param olen The address at which to store the total number of Bytes
* written to \p buf. This must not be \c NULL.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG parameter to be passed to \p f_rng. This
* may be \c NULL if \p f_rng doesn't use a context.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This clears an ECJPAKE context and frees any
* embedded data structure.
*
* \param ctx The ECJPAKE context to free. This may be \c NULL,
* in which case this function does nothing. If it is not
* \c NULL, it must point to an initialized ECJPAKE context.
*/
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_ecjpake_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* ecjpake.h */

1185
include/mbedtls/ecp.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
/**
* \file ecp_internal.h
*
* \brief Function declarations for alternative implementation of elliptic curve
* point arithmetic.
*/
/*
* Copyright (C) 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)
*/
/*
* References:
*
* [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records.
* <http://cr.yp.to/ecdh/curve25519-20060209.pdf>
*
* [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
* for elliptic curve cryptosystems. In : Cryptographic Hardware and
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
* <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
*
* [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
* render ECC resistant against Side Channel Attacks. IACR Cryptology
* ePrint Archive, 2004, vol. 2004, p. 342.
* <http://eprint.iacr.org/2004/342.pdf>
*
* [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters.
* <http://www.secg.org/sec2-v2.pdf>
*
* [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic
* Curve Cryptography.
*
* [6] Digital Signature Standard (DSS), FIPS 186-4.
* <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
*
* [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
* Security (TLS), RFC 4492.
* <https://tools.ietf.org/search/rfc4492>
*
* [8] <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html>
*
* [9] COHEN, Henri. A Course in Computational Algebraic Number Theory.
* Springer Science & Business Media, 1 Aug 2000
*/
#ifndef MBEDTLS_ECP_INTERNAL_H
#define MBEDTLS_ECP_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
/**
* \brief Indicate if the Elliptic Curve Point module extension can
* handle the group.
*
* \param grp The pointer to the elliptic curve group that will be the
* basis of the cryptographic computations.
*
* \return Non-zero if successful.
*/
unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp );
/**
* \brief Initialise the Elliptic Curve Point module extension.
*
* If mbedtls_internal_ecp_grp_capable returns true for a
* group, this function has to be able to initialise the
* module for it.
*
* This module can be a driver to a crypto hardware
* accelerator, for which this could be an initialise function.
*
* \param grp The pointer to the group the module needs to be
* initialised for.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
/**
* \brief Frees and deallocates the Elliptic Curve Point module
* extension.
*
* \param grp The pointer to the group the module was initialised for.
*/
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
/**
* \brief Randomize jacobian coordinates:
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l.
*
* \param grp Pointer to the group representing the curve.
*
* \param pt The point on the curve to be randomised, given with Jacobian
* coordinates.
*
* \param f_rng A function pointer to the random number generator.
*
* \param p_rng A pointer to the random number generator state.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#endif
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
/**
* \brief Addition: R = P + Q, mixed affine-Jacobian coordinates.
*
* The coordinates of Q must be normalized (= affine),
* but those of P don't need to. R is not normalized.
*
* This function is used only as a subrutine of
* ecp_mul_comb().
*
* Special cases: (1) P or Q is zero, (2) R is zero,
* (3) P == Q.
* None of these cases can happen as intermediate step in
* ecp_mul_comb():
* - at each step, P, Q and R are multiples of the base
* point, the factor being less than its order, so none of
* them is zero;
* - Q is an odd multiple of the base point, P an even
* multiple, due to the choice of precomputed points in the
* modified comb method.
* So branches for these cases do not leak secret information.
*
* We accept Q->Z being unset (saving memory in tables) as
* meaning 1.
*
* Cost in field operations if done by [5] 3.22:
* 1A := 8M + 3S
*
* \param grp Pointer to the group representing the curve.
*
* \param R Pointer to a point structure to hold the result.
*
* \param P Pointer to the first summand, given with Jacobian
* coordinates
*
* \param Q Pointer to the second summand, given with affine
* coordinates.
*
* \return 0 if successful.
*/
int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q );
#endif
/**
* \brief Point doubling R = 2 P, Jacobian coordinates.
*
* Cost: 1D := 3M + 4S (A == 0)
* 4M + 4S (A == -3)
* 3M + 6S + 1a otherwise
* when the implementation is based on the "dbl-1998-cmo-2"
* doubling formulas in [8] and standard optimizations are
* applied when curve parameter A is one of { 0, -3 }.
*
* \param grp Pointer to the group representing the curve.
*
* \param R Pointer to a point structure to hold the result.
*
* \param P Pointer to the point that has to be doubled, given with
* Jacobian coordinates.
*
* \return 0 if successful.
*/
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, const mbedtls_ecp_point *P );
#endif
/**
* \brief Normalize jacobian coordinates of an array of (pointers to)
* points.
*
* Using Montgomery's trick to perform only one inversion mod P
* the cost is:
* 1N(t) := 1I + (6t - 3)M + 1S
* (See for example Algorithm 10.3.4. in [9])
*
* This function is used only as a subrutine of
* ecp_mul_comb().
*
* Warning: fails (returning an error) if one of the points is
* zero!
* This should never happen, see choice of w in ecp_mul_comb().
*
* \param grp Pointer to the group representing the curve.
*
* \param T Array of pointers to the points to normalise.
*
* \param t_len Number of elements in the array.
*
* \return 0 if successful,
* an error if one of the points is zero.
*/
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *T[], size_t t_len );
#endif
/**
* \brief Normalize jacobian coordinates so that Z == 0 || Z == 1.
*
* Cost in field operations if done by [5] 3.2.1:
* 1N := 1I + 3M + 1S
*
* \param grp Pointer to the group representing the curve.
*
* \param pt pointer to the point to be normalised. This is an
* input/output parameter.
*
* \return 0 if successful.
*/
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt );
#endif
#endif /* ECP_SHORTWEIERSTRASS */
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d );
#endif
/**
* \brief Randomize projective x/z coordinates:
* (X, Z) -> (l X, l Z) for random l
*
* \param grp pointer to the group representing the curve
*
* \param P the point on the curve to be randomised given with
* projective coordinates. This is an input/output parameter.
*
* \param f_rng a function pointer to the random number generator
*
* \param p_rng a pointer to the random number generator state
*
* \return 0 if successful
*/
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#endif
/**
* \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1.
*
* \param grp pointer to the group representing the curve
*
* \param P pointer to the point to be normalised. This is an
* input/output parameter.
*
* \return 0 if successful
*/
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P );
#endif
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
#endif /* ecp_internal.h */

289
include/mbedtls/entropy.h Normal file
View File

@ -0,0 +1,289 @@
/**
* \file entropy.h
*
* \brief Entropy accumulator implementation
*/
/*
* 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)
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "mbedtls/sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "mbedtls/sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "mbedtls/havege.h"
#endif
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
#endif
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif
/* \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Entropy poll callback pointer
*
* \param data Callback-specific data pointer
* \param output Data to fill
* \param len Maximum size to provide
* \param olen The actual amount of bytes put into the buffer (Can be 0)
*
* \return 0 if no critical failures occurred,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
*/
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
size_t *olen);
/**
* \brief Entropy source state
*/
typedef struct mbedtls_entropy_source_state
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
size_t size; /**< Amount received in bytes */
size_t threshold; /**< Minimum bytes required before release */
int strong; /**< Is the source strong? */
}
mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct mbedtls_entropy_context
{
int accumulator_started;
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator;
#else
mbedtls_sha256_context accumulator;
#endif
int source_count;
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state havege_data;
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; /*!< mutex */
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int initial_entropy_run;
#endif
}
mbedtls_entropy_context;
/**
* \brief Initialize the context
*
* \param ctx Entropy context to initialize
*/
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
/**
* \brief Free the data in the context
*
* \param ctx Entropy context to free
*/
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
/**
* \brief Adds an entropy source to poll
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param f_source Entropy function
* \param p_source Function data
* \param threshold Minimum required from source before entropy is released
* ( with mbedtls_entropy_func() ) (in bytes)
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
* MBEDTLS_ENTROPY_SOURCE_WEAK.
* At least one strong source needs to be added.
* Weaker sources (such as the cycle counter) can be used as
* a complement.
*
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
*/
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong );
/**
* \brief Trigger an extra gather poll for the accumulator
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
/**
* \brief Retrieve entropy from the accumulator
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param data Entropy context
* \param output Buffer to fill
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
/**
* \brief Add data to the accumulator manually
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param data Data to add
* \param len Length of data
*
* \return 0 if successful
*/
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len );
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Trigger an update of the seed file in NV by using the
* current entropy pool.
*
* \param ctx Entropy context
*
* \return 0 if successful
*/
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
* read from the seed file. The rest is ignored.
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* This module self-test also calls the entropy self-test,
* mbedtls_entropy_source_self_test();
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_self_test( int verbose );
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Checkup routine
*
* Verifies the integrity of the hardware entropy source
* provided by the function 'mbedtls_hardware_poll()'.
*
* Note this is the only hardware entropy source that is known
* at link time, and other entropy sources configured
* dynamically at runtime by the function
* mbedtls_entropy_add_source() will not be tested.
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_source_self_test( int verbose );
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* entropy.h */

View File

@ -0,0 +1,110 @@
/**
* \file entropy_poll.h
*
* \brief Platform-specific and custom entropy polling functions
*/
/*
* 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)
*/
#ifndef MBEDTLS_ENTROPY_POLL_H
#define MBEDTLS_ENTROPY_POLL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Default thresholds for built-in sources, in bytes
*/
#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */
#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */
#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */
#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */
#endif
/**
* \brief Entropy poll callback that provides 0 entropy.
*/
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
int mbedtls_null_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
/**
* \brief Platform-specific entropy poll callback
*/
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_HAVEGE_C)
/**
* \brief HAVEGE based entropy poll callback
*
* Requires an HAVEGE state as its data pointer.
*/
int mbedtls_havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_TIMING_C)
/**
* \brief mbedtls_timing_hardclock-based entropy poll callback
*/
int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Entropy poll callback for a hardware source
*
* \warning This is not provided by mbed TLS!
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_hardware_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Entropy poll callback for a non-volatile seed file
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_nv_seed_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#ifdef __cplusplus
}
#endif
#endif /* entropy_poll.h */

326
include/mbedtls/gcm.h Normal file
View File

@ -0,0 +1,326 @@
/**
* \file gcm.h
*
* \brief This file contains GCM definitions and functions.
*
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
* (GCM), Natl. Inst. Stand. Technol.</em>
*
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
*
*/
/*
* 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_GCM_H
#define MBEDTLS_GCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/cipher.h"
#include <stdint.h>
#define MBEDTLS_GCM_ENCRYPT 1
#define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 /**< GCM hardware accelerator failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_GCM_ALT)
/**
* \brief The GCM context structure.
*/
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. */
uint64_t len; /*!< The total length of the encrypted data. */
uint64_t add_len; /*!< The total length of the additional data. */
unsigned char base_ectr[16]; /*!< The first ECTR for tag. */
unsigned char y[16]; /*!< The Y working value. */
unsigned char buf[16]; /*!< The buf working value. */
int mode; /*!< The operation to perform:
#MBEDTLS_GCM_ENCRYPT or
#MBEDTLS_GCM_DECRYPT. */
}
mbedtls_gcm_context;
#else /* !MBEDTLS_GCM_ALT */
#include "gcm_alt.h"
#endif /* !MBEDTLS_GCM_ALT */
/**
* \brief This function initializes the specified GCM context,
* to make references valid, and prepares the context
* for mbedtls_gcm_setkey() or mbedtls_gcm_free().
*
* The function does not bind the GCM context to a particular
* cipher, nor set the key. For this purpose, use
* mbedtls_gcm_setkey().
*
* \param ctx The GCM context to initialize. This must not be \c NULL.
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
/**
* \brief This function associates a GCM context with a
* cipher algorithm and a key.
*
* \param ctx The GCM context. This must be initialized.
* \param cipher The 128-bit block cipher to use.
* \param key The encryption key. This must be a readable buffer of at
* least \p keybits bits.
* \param keybits The key size in bits. Valid options are:
* <ul><li>128 bits</li>
* <li>192 bits</li>
* <li>256 bits</li></ul>
*
* \return \c 0 on success.
* \return A cipher-specific error code on failure.
*/
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief This function performs GCM encryption or decryption of a buffer.
*
* \note For encryption, the output buffer can be the same as the
* input buffer. For decryption, the output buffer cannot be
* 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. This
* must be initialized.
* \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. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add_len The length of the additional data.
* \param input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is greater
* than zero, this must be a writable buffer of at least that
* size in Bytes.
* \param tag_len The length of the tag to generate.
* \param tag The buffer for holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
*
* \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 or pointers are
* not valid or a cipher-specific error code if the encryption
* or decryption failed.
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
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,
size_t tag_len,
unsigned char *tag );
/**
* \brief This function performs a GCM authenticated decryption of a
* buffer.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the ciphertext to decrypt, which is also
* the length of the decrypted plaintext.
* \param iv The initialization vector. This must be a readable buffer
* of at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data. This must be of at
* least that size in Bytes.
* \param add_len The length of the additional data.
* \param tag The buffer holding the tag to verify. This must be a
* readable buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to verify.
* \param input The buffer holding the ciphertext. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size.
* \param output The buffer for holding the decrypted plaintext. If \p length
* is greater than zero, this must be a writable buffer of at
* least that size.
*
* \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 or pointers are
* not valid or a cipher-specific error code if the decryption
* failed.
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function starts a GCM encryption or decryption
* operation.
*
* \param ctx The GCM context. This must be initialized.
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
* #MBEDTLS_GCM_DECRYPT.
* \param iv The initialization vector. This must be a readable buffer of
* at least \p iv_len Bytes.
* \param iv_len The length of the IV.
* \param add The buffer holding the additional data, or \c NULL
* if \p add_len is \c 0.
* \param add_len The length of the additional data. If \c 0,
* \p add may be \c NULL.
*
* \return \c 0 on success.
*/
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len );
/**
* \brief This function feeds an input buffer into an ongoing GCM
* encryption or decryption operation.
*
* ` The function expects input to be a multiple of 16
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
*
* \param ctx The GCM context. This must be initialized.
* \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 input The buffer holding the input data. If \p length is greater
* than zero, this must be a readable buffer of at least that
* size in Bytes.
* \param output The buffer for holding the output data. If \p length is
* greater than zero, this must be a writable buffer of at
* least that size in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *input,
unsigned char *output );
/**
* \brief This function finishes the GCM operation and generates
* the authentication tag.
*
* It wraps up the GCM stream, and generates the
* tag. The tag can have a maximum length of 16 Bytes.
*
* \param ctx The GCM context. This must be initialized.
* \param tag The buffer for holding the tag. This must be a readable
* buffer of at least \p tag_len Bytes.
* \param tag_len The length of the tag to generate. This must be at least
* four.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
*/
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag,
size_t tag_len );
/**
* \brief This function clears a GCM context and the underlying
* cipher sub-context.
*
* \param ctx The GCM context to clear. If this is \c NULL, the call has
* no effect. Otherwise, this must be initialized.
*/
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The GCM checkup routine.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*/
int mbedtls_gcm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* gcm.h */

82
include/mbedtls/havege.h Normal file
View File

@ -0,0 +1,82 @@
/**
* \file havege.h
*
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*/
/*
* Copyright (C) 2006-2015, 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_HAVEGE_H
#define MBEDTLS_HAVEGE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief HAVEGE state structure
*/
typedef struct mbedtls_havege_state
{
uint32_t PT1, PT2, offset[2];
uint32_t pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
uint32_t WALK[8192];
}
mbedtls_havege_state;
/**
* \brief HAVEGE initialization
*
* \param hs HAVEGE state to be initialized
*/
void mbedtls_havege_init( mbedtls_havege_state *hs );
/**
* \brief Clear HAVEGE state
*
* \param hs HAVEGE state to be cleared
*/
void mbedtls_havege_free( mbedtls_havege_state *hs );
/**
* \brief HAVEGE rand function
*
* \param p_rng A HAVEGE state
* \param output Buffer to fill
* \param len Length of buffer
*
* \return 0
*/
int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len );
#ifdef __cplusplus
}
#endif
#endif /* havege.h */

141
include/mbedtls/hkdf.h Normal file
View File

@ -0,0 +1,141 @@
/**
* \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) 2018-2019, 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
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/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 */

415
include/mbedtls/hmac_drbg.h Normal file
View File

@ -0,0 +1,415 @@
/**
* \file hmac_drbg.h
*
* \brief The HMAC_DRBG pseudorandom generator.
*
* This module implements the HMAC_DRBG pseudorandom generator described
* in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
* Deterministic Random Bit Generators</em>.
*/
/*
* Copyright (C) 2006-2019, 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_HMAC_DRBG_H
#define MBEDTLS_HMAC_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/md.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
/*
* Error codes
*/
#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */
#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */
#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */
#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
#ifdef __cplusplus
extern "C" {
#endif
/**
* HMAC_DRBG context.
*/
typedef struct mbedtls_hmac_drbg_context
{
/* Working state: the key K is not stored explicitly,
* but is implied by the HMAC context */
mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */
unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */
int reseed_counter; /*!< reseed counter */
/* Administrative state */
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
int prediction_resistance; /*!< enable prediction resistance (Automatic
reseed before every random generation) */
int reseed_interval; /*!< reseed interval */
/* Callbacks */
int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
} mbedtls_hmac_drbg_context;
/**
* \brief HMAC_DRBG context initialization.
*
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
*
* \param ctx HMAC_DRBG context to be initialized.
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
/**
* \brief HMAC_DRBG initial seeding.
*
* Set the initial seed and set up the entropy source for future reseeds.
*
* A typical choice for the \p f_entropy and \p p_entropy parameters is
* to use the entropy module:
* - \p f_entropy is mbedtls_entropy_func();
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
* with mbedtls_entropy_init() (which registers the platform's default
* entropy sources).
*
* You can provide a personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
*
* \note By default, the security strength as defined by NIST is:
* - 128 bits if \p md_info is SHA-1;
* - 192 bits if \p md_info is SHA-224;
* - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
* Note that SHA-256 is just as efficient as SHA-224.
* The security strength can be reduced if a smaller
* entropy length is set with
* mbedtls_hmac_drbg_set_entropy_len().
*
* \note The default entropy length is the security strength
* (converted from bits to bytes). You can override
* it by calling mbedtls_hmac_drbg_set_entropy_len().
*
* \note During the initial seeding, this function calls
* the entropy source to obtain a nonce
* whose length is half the entropy length.
*
* \param ctx HMAC_DRBG context to be seeded.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param f_entropy The entropy callback, taking as arguments the
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a length that is
* less than or equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
* string is empty regardless of the value of \p len.
* \param len The length of the personalization string.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2
* where \p entropy_len is the entropy length
* described above.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if the call to \p f_entropy failed.
*/
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief Initilisation of simpified HMAC_DRBG (never reseeds).
*
* This function is meant for use in algorithms that need a pseudorandom
* input such as deterministic ECDSA.
*
* \param ctx HMAC_DRBG context to be initialised.
* \param md_info MD algorithm to use for HMAC_DRBG.
* \param data Concatenation of the initial entropy string and
* the additional data.
* \param data_len Length of \p data in bytes.
*
* \return \c 0 if successful. or
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
* invalid.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
* memory to allocate context data.
*/
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len );
/**
* \brief This function turns prediction resistance on or off.
* The default value is off.
*
* \note If enabled, entropy is gathered at the beginning of
* every call to mbedtls_hmac_drbg_random_with_add()
* or mbedtls_hmac_drbg_random().
* Only use this if your entropy source has sufficient
* throughput.
*
* \param ctx The HMAC_DRBG context.
* \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
*/
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
int resistance );
/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
*
* See the documentation of mbedtls_hmac_drbg_seed() for the default value.
*
* \param ctx The HMAC_DRBG context.
* \param len The amount of entropy to grab, in bytes.
*/
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
size_t len );
/**
* \brief Set the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
* or mbedtls_hmac_drbg_random_with_add() after which the entropy function
* is called again.
*
* The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
*
* \param ctx The HMAC_DRBG context.
* \param interval The reseed interval.
*/
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
int interval );
/**
* \brief This function updates the state of the HMAC_DRBG context.
*
* \param ctx The HMAC_DRBG context.
* \param additional The data to update the state with.
* If this is \c NULL, there is no additional data.
* \param add_len Length of \p additional in bytes.
* Unused if \p additional is \c NULL.
*
* \return \c 0 on success, or an error from the underlying
* hash calculation.
*/
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
* \brief This function reseeds the HMAC_DRBG context, that is
* extracts data from the entropy source.
*
* \param ctx The HMAC_DRBG context.
* \param additional Additional data to add to the state.
* If this is \c NULL, there is no additional data
* and \p len should be \c 0.
* \param len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
* and also at most
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len
* where \p entropy_len is the entropy length
* (see mbedtls_hmac_drbg_set_entropy_len()).
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy function failed.
*/
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief This function updates an HMAC_DRBG instance with additional
* data and uses it to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
* \param output_len The length of the buffer in bytes.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \param additional Additional data to update with.
* If this is \c NULL, there is no additional data
* and \p add_len should be \c 0.
* \param add_len The length of the additional data.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy source failed.
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
* \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
*/
int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional,
size_t add_len );
/**
* \brief This function uses HMAC_DRBG to generate random data.
*
* This function automatically reseeds if the reseed counter is exceeded
* or prediction resistance is enabled.
*
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
* #mbedtls_hmac_drbg_context structure.
* \param output The buffer to fill.
* \param out_len The length of the buffer in bytes.
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
*
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
* if a call to the entropy source failed.
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
* \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
/**
* \brief Free an HMAC_DRBG context
*
* \param ctx The HMAC_DRBG context to free.
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function updates the state of the HMAC_DRBG context.
*
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
* in 2.16.0.
*
* \param ctx The HMAC_DRBG context.
* \param additional The data to update the state with.
* If this is \c NULL, there is no additional data.
* \param add_len Length of \p additional in bytes.
* Unused if \p additional is \c NULL.
*/
MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function writes a seed file.
*
* \param ctx The HMAC_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
* failure.
*/
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
/**
* \brief This function reads and updates a seed file. The seed
* is added to this instance.
*
* \param ctx The HMAC_DRBG context.
* \param path The name of the file.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
* reseed failure.
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
* seed file is too large.
*/
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The HMAC_DRBG Checkup routine.
*
* \return \c 0 if successful.
* \return \c 1 if the test failed.
*/
int mbedtls_hmac_drbg_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* hmac_drbg.h */

474
include/mbedtls/md.h Normal file
View File

@ -0,0 +1,474 @@
/**
* \file md.h
*
* \brief This file contains the generic message-digest wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.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_MD_H
#define MBEDTLS_MD_H
#include <stddef.h>
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 /**< MD hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Supported message digests.
*
* \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and
* their use constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef enum {
MBEDTLS_MD_NONE=0, /**< None. */
MBEDTLS_MD_MD2, /**< The MD2 message digest. */
MBEDTLS_MD_MD4, /**< The MD4 message digest. */
MBEDTLS_MD_MD5, /**< The MD5 message digest. */
MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */
MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */
MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */
MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */
MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */
MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
} mbedtls_md_type_t;
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#else
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
#else
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
#endif
/**
* Opaque struct defined in md_internal.h.
*/
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* The generic message-digest context.
*/
typedef struct mbedtls_md_context_t
{
/** Information about the associated message digest. */
const mbedtls_md_info_t *md_info;
/** The digest-specific context. */
void *md_ctx;
/** The HMAC part of the context. */
void *hmac_ctx;
} mbedtls_md_context_t;
/**
* \brief This function returns the list of digests supported by the
* generic digest module.
*
* \return A statically allocated array of digests. Each element
* in the returned list is an integer belonging to the
* message-digest enumeration #mbedtls_md_type_t.
* The last entry is 0.
*/
const int *mbedtls_md_list( void );
/**
* \brief This function returns the message-digest information
* associated with the given digest name.
*
* \param md_name The name of the digest to search for.
*
* \return The message-digest information associated with \p md_name.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief This function returns the message-digest information
* associated with the given digest type.
*
* \param md_type The type of digest to search for.
*
* \return The message-digest information associated with \p md_type.
* \return NULL if the associated message-digest information is not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief This function initializes a message-digest context without
* binding it to a particular message-digest algorithm.
*
* This function should always be called first. It prepares the
* context for mbedtls_md_setup() for binding it to a
* message-digest algorithm.
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx );
/**
* \brief This function clears the internal structure of \p ctx and
* frees any embedded internal structure, but does not free
* \p ctx itself.
*
* If you have called mbedtls_md_setup() on \p ctx, you must
* call mbedtls_md_free() when you are no longer using the
* context.
* Calling this function if you have previously
* called mbedtls_md_init() and nothing else is optional.
* You must not call this function if you have not called
* mbedtls_md_init().
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function selects the message digest algorithm to use,
* and allocates internal structures.
*
* It should be called after mbedtls_md_init() or
* mbedtls_md_free(). Makes it necessary to call
* mbedtls_md_free() later.
*
* \param ctx The context to set up.
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
* or non-zero: HMAC is used with this context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief This function clones the state of an message-digest
* context.
*
* \note You must call mbedtls_md_setup() on \c dst before calling
* this function.
*
* \note The two contexts must have the same type,
* for example, both are SHA-256.
*
* \warning This function clones the message-digest state, not the
* HMAC state.
*
* \param dst The destination context.
* \param src The context to be cloned.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
/**
* \brief This function extracts the message-digest size from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The size of the message-digest output in Bytes.
*/
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest type from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The type of the message digest.
*/
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/**
* \brief This function extracts the message-digest name from the
* message-digest information structure.
*
* \param md_info The information structure of the message-digest algorithm
* to use.
*
* \return The name of the message digest.
*/
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/**
* \brief This function starts a message-digest computation.
*
* You must call this function after setting up the context
* with mbedtls_md_setup(), and before passing data with
* mbedtls_md_update().
*
* \param ctx The generic message-digest context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
* \brief This function feeds an input buffer into an ongoing
* message-digest computation.
*
* You must call mbedtls_md_starts() before calling this
* function. You may call this function multiple times.
* Afterwards, call mbedtls_md_finish().
*
* \param ctx The generic message-digest context.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief This function finishes the digest operation,
* and writes the result to the output buffer.
*
* Call this function after a call to mbedtls_md_starts(),
* followed by any number of calls to mbedtls_md_update().
* Afterwards, you may either clear the context with
* mbedtls_md_free(), or call mbedtls_md_starts() to reuse
* the context for another digest operation with the same
* algorithm.
*
* \param ctx The generic message-digest context.
* \param output The buffer for the generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
* \brief This function calculates the message-digest of a buffer,
* with respect to a configurable message-digest algorithm
* in a single call.
*
* The result is calculated as
* Output = message_digest(input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param input The buffer holding the data.
* \param ilen The length of the input data.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_FS_IO)
/**
* \brief This function calculates the message-digest checksum
* result of the contents of the provided file.
*
* The result is calculated as
* Output = message_digest(file contents).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param path The input file name.
* \param output The generic message-digest checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
/**
* \brief This function sets the HMAC key and prepares to
* authenticate a new message.
*
* Call this function after mbedtls_md_setup(), to use
* the MD context for an HMAC calculation, then call
* mbedtls_md_hmac_update() to provide the input data, and
* mbedtls_md_hmac_finish() to get the HMAC value.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC key in Bytes.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
/**
* \brief This function feeds an input buffer into an ongoing HMAC
* computation.
*
* Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
* before calling this function.
* You may call this function multiple times to pass the
* input piecewise.
* Afterwards, call mbedtls_md_hmac_finish().
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief This function finishes the HMAC operation, and writes
* the result to the output buffer.
*
* Call this function after mbedtls_md_hmac_starts() and
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards
* you may either call mbedtls_md_free() to clear the context,
* or call mbedtls_md_hmac_reset() to reuse the context with
* the same HMAC key.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
* \param output The generic HMAC checksum result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
* \brief This function prepares to authenticate a new message with
* the same key as the previous HMAC operation.
*
* You may call this function after mbedtls_md_hmac_finish().
* Afterwards call mbedtls_md_hmac_update() to pass the new
* input.
*
* \param ctx The message digest context containing an embedded HMAC
* context.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
* \brief This function calculates the full generic HMAC
* on the input buffer with the provided key.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The HMAC result is calculated as
* output = generic HMAC(hmac key, input buffer).
*
* \param md_info The information structure of the message-digest algorithm
* to use.
* \param key The HMAC secret key.
* \param keylen The length of the HMAC secret key in Bytes.
* \param input The buffer holding the input data.
* \param ilen The length of the input data.
* \param output The generic HMAC result.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_H */

306
include/mbedtls/md2.h Normal file
View File

@ -0,0 +1,306 @@
/**
* \file md2.h
*
* \brief MD2 message digest algorithm (hash function)
*
* \warning MD2 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message digests
* instead.
*/
/*
* Copyright (C) 2006-2015, 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_MD2_H
#define MBEDTLS_MD2_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD2_ALT)
// Regular implementation
//
/**
* \brief MD2 context structure
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef struct mbedtls_md2_context
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */
unsigned char buffer[16]; /*!< data block being processed */
size_t left; /*!< amount of data in buffer */
}
mbedtls_md2_context;
#else /* MBEDTLS_MD2_ALT */
#include "md2_alt.h"
#endif /* MBEDTLS_MD2_ALT */
/**
* \brief Initialize MD2 context
*
* \param ctx MD2 context to be initialized
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md2_init( mbedtls_md2_context *ctx );
/**
* \brief Clear MD2 context
*
* \param ctx MD2 context to be cleared
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md2_free( mbedtls_md2_context *ctx );
/**
* \brief Clone (the state of) an MD2 context
*
* \param dst The destination context
* \param src The context to be cloned
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md2_clone( mbedtls_md2_context *dst,
const mbedtls_md2_context *src );
/**
* \brief MD2 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD2 final digest
*
* \param ctx MD2 context
* \param output MD2 checksum result
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] );
/**
* \brief MD2 process data block (internal use only)
*
* \param ctx MD2 context
*
* \return 0 if successful
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md2_process( mbedtls_md2_context *ctx );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD2 context setup
*
* \deprecated Superseded by mbedtls_md2_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \deprecated Superseded by mbedtls_md2_update_ret() in 2.7.0
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD2 final digest
*
* \deprecated Superseded by mbedtls_md2_finish_ret() in 2.7.0
*
* \param ctx MD2 context
* \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx,
unsigned char output[16] );
/**
* \brief MD2 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md2_process() in 2.7.0
*
* \param ctx MD2 context
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Output = MD2( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD2( input buffer )
*
* \deprecated Superseded by mbedtls_md2_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*
* \warning MD2 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md2_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md2.h */

311
include/mbedtls/md4.h Normal file
View File

@ -0,0 +1,311 @@
/**
* \file md4.h
*
* \brief MD4 message digest algorithm (hash function)
*
* \warning MD4 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message digests
* instead.
*/
/*
* Copyright (C) 2006-2015, 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_MD4_H
#define MBEDTLS_MD4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD4_ALT)
// Regular implementation
//
/**
* \brief MD4 context structure
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef struct mbedtls_md4_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md4_context;
#else /* MBEDTLS_MD4_ALT */
#include "md4_alt.h"
#endif /* MBEDTLS_MD4_ALT */
/**
* \brief Initialize MD4 context
*
* \param ctx MD4 context to be initialized
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md4_init( mbedtls_md4_context *ctx );
/**
* \brief Clear MD4 context
*
* \param ctx MD4 context to be cleared
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md4_free( mbedtls_md4_context *ctx );
/**
* \brief Clone (the state of) an MD4 context
*
* \param dst The destination context
* \param src The context to be cloned
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md4_clone( mbedtls_md4_context *dst,
const mbedtls_md4_context *src );
/**
* \brief MD4 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*/
int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD4 final digest
*
* \param ctx MD4 context
* \param output MD4 checksum result
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] );
/**
* \brief MD4 process data block (internal use only)
*
* \param ctx MD4 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD4 context setup
*
* \deprecated Superseded by mbedtls_md4_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \deprecated Superseded by mbedtls_md4_update_ret() in 2.7.0
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD4 final digest
*
* \deprecated Superseded by mbedtls_md4_finish_ret() in 2.7.0
*
* \param ctx MD4 context
* \param output MD4 checksum result
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx,
unsigned char output[16] );
/**
* \brief MD4 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md4_process() in 2.7.0
*
* \param ctx MD4 context
* \param data buffer holding one block of data
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Output = MD4( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*
* \return 0 if successful
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD4( input buffer )
*
* \deprecated Superseded by mbedtls_md4_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*
* \warning MD4 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md4_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md4.h */

311
include/mbedtls/md5.h Normal file
View File

@ -0,0 +1,311 @@
/**
* \file md5.h
*
* \brief MD5 message digest algorithm (hash function)
*
* \warning MD5 is considered a weak message digest and its use constitutes a
* security risk. We recommend considering stronger message
* digests instead.
*/
/*
* Copyright (C) 2006-2015, 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_MD5_H
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED -0x002F /**< MD5 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_MD5_ALT)
// Regular implementation
//
/**
* \brief MD5 context structure
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef struct mbedtls_md5_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md5_context;
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
/**
* \brief Initialize MD5 context
*
* \param ctx MD5 context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_init( mbedtls_md5_context *ctx );
/**
* \brief Clear MD5 context
*
* \param ctx MD5 context to be cleared
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_free( mbedtls_md5_context *ctx );
/**
* \brief Clone (the state of) an MD5 context
*
* \param dst The destination context
* \param src The context to be cloned
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src );
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief MD5 context setup
*
* \deprecated Superseded by mbedtls_md5_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \deprecated Superseded by mbedtls_md5_update_ret() in 2.7.0
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief MD5 final digest
*
* \deprecated Superseded by mbedtls_md5_finish_ret() in 2.7.0
*
* \param ctx MD5 context
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
unsigned char output[16] );
/**
* \brief MD5 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_md5_process() in 2.7.0
*
* \param ctx MD5 context
* \param data buffer holding one block of data
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*
* \return 0 if successful
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = MD5( input buffer )
*
* \deprecated Superseded by mbedtls_md5_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
size_t ilen,
unsigned char output[16] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*
* \warning MD5 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
int mbedtls_md5_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md5.h */

View File

@ -0,0 +1,92 @@
/**
* \file md_internal.h
*
* \brief Message digest wrappers.
*
* \warning This in an internal header. Do not include directly.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*/
/*
* Copyright (C) 2006-2015, 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_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Message digest information.
* Allows message digest functions to be called in a generic way.
*/
struct mbedtls_md_info_t
{
/** Name of the message digest */
const char * name;
/** Digest identifier */
mbedtls_md_type_t type;
/** Output length of the digest function in bytes */
unsigned char size;
/** Block length of the digest function in bytes */
unsigned char block_size;
};
#if defined(MBEDTLS_MD2_C)
extern const mbedtls_md_info_t mbedtls_md2_info;
#endif
#if defined(MBEDTLS_MD4_C)
extern const mbedtls_md_info_t mbedtls_md4_info;
#endif
#if defined(MBEDTLS_MD5_C)
extern const mbedtls_md_info_t mbedtls_md5_info;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
extern const mbedtls_md_info_t mbedtls_ripemd160_info;
#endif
#if defined(MBEDTLS_SHA1_C)
extern const mbedtls_md_info_t mbedtls_sha1_info;
#endif
#if defined(MBEDTLS_SHA256_C)
extern const mbedtls_md_info_t mbedtls_sha224_info;
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif
#if defined(MBEDTLS_SHA512_C)
#if !defined(MBEDTLS_SHA512_NO_SHA384)
extern const mbedtls_md_info_t mbedtls_sha384_info;
#endif
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_WRAP_H */

View File

@ -0,0 +1,151 @@
/**
* \file memory_buffer_alloc.h
*
* \brief Buffer-based memory allocator
*/
/*
* Copyright (C) 2006-2015, 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_MEMORY_BUFFER_ALLOC_H
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE)
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_MEMORY_VERIFY_NONE 0
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0)
#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1)
#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize use of stack-based memory allocator.
* The stack-based allocator does memory management inside the
* presented buffer and does not call calloc() and free().
* It sets the global mbedtls_calloc() and mbedtls_free() pointers
* to its own functions.
* (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if
* MBEDTLS_THREADING_C is defined)
*
* \note This code is not optimized and provides a straight-forward
* implementation of a stack-based memory allocator.
*
* \param buf buffer to use as heap
* \param len size of the buffer
*/
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len );
/**
* \brief Free the mutex for thread-safety and clear remaining memory
*/
void mbedtls_memory_buffer_alloc_free( void );
/**
* \brief Determine when the allocator should automatically verify the state
* of the entire chain of headers / meta-data.
* (Default: MBEDTLS_MEMORY_VERIFY_NONE)
*
* \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC,
* MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS
*/
void mbedtls_memory_buffer_set_verify( int verify );
#if defined(MBEDTLS_MEMORY_DEBUG)
/**
* \brief Print out the status of the allocated memory (primarily for use
* after a program should have de-allocated all memory)
* Prints out a list of 'still allocated' blocks and their stack
* trace if MBEDTLS_MEMORY_BACKTRACE is defined.
*/
void mbedtls_memory_buffer_alloc_status( void );
/**
* \brief Get the peak heap usage so far
*
* \param max_used Peak number of bytes in use or committed. This
* includes bytes in allocated blocks too small to split
* into smaller blocks but larger than the requested size.
* \param max_blocks Peak number of blocks in use, including free and used
*/
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks );
/**
* \brief Reset peak statistics
*/
void mbedtls_memory_buffer_alloc_max_reset( void );
/**
* \brief Get the current heap usage
*
* \param cur_used Current number of bytes in use or committed. This
* includes bytes in allocated blocks too small to split
* into smaller blocks but larger than the requested size.
* \param cur_blocks Current number of blocks in use, including free and used
*/
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
#endif /* MBEDTLS_MEMORY_DEBUG */
/**
* \brief Verifies that all headers in the memory buffer are correct
* and contain sane values. Helps debug buffer-overflow errors.
*
* Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined.
* Prints out full header information if MBEDTLS_MEMORY_DEBUG
* is defined. (Includes stack trace information for each block if
* MBEDTLS_MEMORY_BACKTRACE is defined as well).
*
* \return 0 if verified, 1 otherwise
*/
int mbedtls_memory_buffer_alloc_verify( void );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_memory_buffer_alloc_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* memory_buffer_alloc.h */

184
include/mbedtls/nist_kw.h Normal file
View File

@ -0,0 +1,184 @@
/**
* \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
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/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 */

649
include/mbedtls/oid.h Normal file
View File

@ -0,0 +1,649 @@
/**
* \file oid.h
*
* \brief Object Identifier (OID) database
*/
/*
* Copyright (C) 2006-2015, 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_OID_H
#define MBEDTLS_OID_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/asn1.h"
#include "mbedtls/pk.h"
#include <stddef.h>
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#endif
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */
/* This is for the benefit of X.509, but defined here in order to avoid
* having a "backwards" include of x.509.h here */
/*
* X.509 extension types (internal, arbitrary values for bitsets)
*/
#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2)
#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4)
#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5)
#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6)
#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8)
#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9)
#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
/*
* Top level OID tuples
*/
#define MBEDTLS_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */
#define MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */
#define MBEDTLS_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */
#define MBEDTLS_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */
/*
* ISO Member bodies OID parts
*/
#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */
#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */
#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */
#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
MBEDTLS_OID_ORG_ANSI_X9_62
/*
* ISO Identified organization OID parts
*/
#define MBEDTLS_OID_ORG_DOD "\x06" /* {dod(6)} */
#define MBEDTLS_OID_ORG_OIW "\x0e"
#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03"
#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02"
#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a"
#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */
#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_CERTICOM
#define MBEDTLS_OID_ORG_TELETRUST "\x24" /* teletrust(36) */
#define MBEDTLS_OID_TELETRUST MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_TELETRUST
/*
* ISO ITU OID parts
*/
#define MBEDTLS_OID_ORGANIZATION "\x01" /* {organization(1)} */
#define MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */
#define MBEDTLS_OID_ORG_GOV "\x65" /* {gov(101)} */
#define MBEDTLS_OID_GOV MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */
#define MBEDTLS_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */
#define MBEDTLS_OID_NETSCAPE MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */
/* 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)
* security(5) mechanisms(5) pkix(7) }
*/
#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01"
#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07"
/*
* Arc for standard naming attributes
*/
#define MBEDTLS_OID_AT MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */
#define MBEDTLS_OID_AT_CN MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */
#define MBEDTLS_OID_AT_SUR_NAME MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */
#define MBEDTLS_OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */
#define MBEDTLS_OID_AT_COUNTRY MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */
#define MBEDTLS_OID_AT_LOCALITY MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */
#define MBEDTLS_OID_AT_STATE MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */
#define MBEDTLS_OID_AT_ORGANIZATION MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */
#define MBEDTLS_OID_AT_ORG_UNIT MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */
#define MBEDTLS_OID_AT_TITLE MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */
#define MBEDTLS_OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */
#define MBEDTLS_OID_AT_POSTAL_CODE MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */
#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
/*
* OIDs for standard certificate extensions
*/
#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */
#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */
#define MBEDTLS_OID_KEY_USAGE MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */
#define MBEDTLS_OID_CERTIFICATE_POLICIES MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */
#define MBEDTLS_OID_POLICY_MAPPINGS MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */
#define MBEDTLS_OID_SUBJECT_ALT_NAME MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */
#define MBEDTLS_OID_ISSUER_ALT_NAME MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */
#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */
#define MBEDTLS_OID_BASIC_CONSTRAINTS MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */
#define MBEDTLS_OID_NAME_CONSTRAINTS MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */
#define MBEDTLS_OID_POLICY_CONSTRAINTS MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */
#define MBEDTLS_OID_EXTENDED_KEY_USAGE MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */
#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
/*
* Certificate policies
*/
#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */
/*
* Netscape certificate extensions
*/
#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01"
#define MBEDTLS_OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT "\x01"
#define MBEDTLS_OID_NS_BASE_URL MBEDTLS_OID_NS_CERT "\x02"
#define MBEDTLS_OID_NS_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x03"
#define MBEDTLS_OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x04"
#define MBEDTLS_OID_NS_RENEWAL_URL MBEDTLS_OID_NS_CERT "\x07"
#define MBEDTLS_OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CERT "\x08"
#define MBEDTLS_OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_CERT "\x0C"
#define MBEDTLS_OID_NS_COMMENT MBEDTLS_OID_NS_CERT "\x0D"
#define MBEDTLS_OID_NS_DATA_TYPE MBEDTLS_OID_NETSCAPE "\x02"
#define MBEDTLS_OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_DATA_TYPE "\x05"
/*
* OIDs for CRL extensions
*/
#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_ID_CE "\x10"
#define MBEDTLS_OID_CRL_NUMBER MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
/*
* X.509 v3 Extended key usage OIDs
*/
#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
#define MBEDTLS_OID_KP MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
#define MBEDTLS_OID_SERVER_AUTH MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
#define MBEDTLS_OID_CLIENT_AUTH MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
#define MBEDTLS_OID_CODE_SIGNING MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
#define MBEDTLS_OID_EMAIL_PROTECTION MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
/**
* Wi-SUN Alliance Field Area Network
* { iso(1) identified-organization(3) dod(6) internet(1)
* private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
*/
#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */
#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */
/*
* PKCS definition OIDs
*/
#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
/*
* PKCS#1 OIDs
*/
#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
#define MBEDTLS_OID_PKCS1_MD2 MBEDTLS_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */
#define MBEDTLS_OID_PKCS1_MD4 MBEDTLS_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */
#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
#define MBEDTLS_OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */
#define MBEDTLS_OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */
#define MBEDTLS_OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */
#define MBEDTLS_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D"
#define MBEDTLS_OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */
/* RFC 4055 */
#define MBEDTLS_OID_RSASSA_PSS MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */
#define MBEDTLS_OID_MGF1 MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */
/*
* Digest algorithms
*/
#define MBEDTLS_OID_DIGEST_ALG_MD2 MBEDTLS_OID_RSA_COMPANY "\x02\x02" /**< id-mbedtls_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */
#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_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_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_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_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
/*
* Encryption algorithms
*/
#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
*/
#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
#define MBEDTLS_OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */
#define MBEDTLS_OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */
/*
* PKCS#5 PBES1 algorithms
*/
#define MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */
#define MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */
#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
/*
* PKCS#8 OIDs
*/
#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
/*
* PKCS#12 PBE OIDs
*/
#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */
/*
* EC key algorithms from RFC 5480
*/
/* id-ecPublicKey OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */
#define MBEDTLS_OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_ANSI_X9_62 "\x02\01"
/* id-ecDH OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132)
* schemes(1) ecdh(12) } */
#define MBEDTLS_OID_EC_ALG_ECDH MBEDTLS_OID_CERTICOM "\x01\x0c"
/*
* ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
*/
/* secp192r1 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */
#define MBEDTLS_OID_EC_GRP_SECP192R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01"
/* secp224r1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 33 } */
#define MBEDTLS_OID_EC_GRP_SECP224R1 MBEDTLS_OID_CERTICOM "\x00\x21"
/* secp256r1 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */
#define MBEDTLS_OID_EC_GRP_SECP256R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07"
/* secp384r1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 34 } */
#define MBEDTLS_OID_EC_GRP_SECP384R1 MBEDTLS_OID_CERTICOM "\x00\x22"
/* secp521r1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
#define MBEDTLS_OID_EC_GRP_SECP521R1 MBEDTLS_OID_CERTICOM "\x00\x23"
/* secp192k1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
#define MBEDTLS_OID_EC_GRP_SECP192K1 MBEDTLS_OID_CERTICOM "\x00\x1f"
/* secp224k1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
#define MBEDTLS_OID_EC_GRP_SECP224K1 MBEDTLS_OID_CERTICOM "\x00\x20"
/* secp256k1 OBJECT IDENTIFIER ::= {
* iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
#define MBEDTLS_OID_EC_GRP_SECP256K1 MBEDTLS_OID_CERTICOM "\x00\x0a"
/* RFC 5639 4.1
* ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
* identified-organization(3) teletrust(36) algorithm(3) signature-
* algorithm(3) ecSign(2) 8}
* ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1}
* versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */
#define MBEDTLS_OID_EC_BRAINPOOL_V1 MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01"
/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */
#define MBEDTLS_OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07"
/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */
#define MBEDTLS_OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B"
/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */
#define MBEDTLS_OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D"
/*
* SEC1 C.1
*
* prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
* id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)}
*/
#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62 "\x01"
#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01"
/*
* ECDSA signature identifiers, from RFC 5480
*/
#define MBEDTLS_OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */
#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */
/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */
#define MBEDTLS_OID_ECDSA_SHA1 MBEDTLS_OID_ANSI_X9_62_SIG "\x01"
/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
* ecdsa-with-SHA2(3) 1 } */
#define MBEDTLS_OID_ECDSA_SHA224 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01"
/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
* ecdsa-with-SHA2(3) 2 } */
#define MBEDTLS_OID_ECDSA_SHA256 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02"
/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
* ecdsa-with-SHA2(3) 3 } */
#define MBEDTLS_OID_ECDSA_SHA384 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03"
/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
* ecdsa-with-SHA2(3) 4 } */
#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Base OID descriptor structure
*/
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) */
const char *description; /*!< human friendly description */
} mbedtls_oid_descriptor_t;
/**
* \brief Translate an ASN.1 OID into its numeric representation
* (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549")
*
* \param buf buffer to put representation in
* \param size size of the buffer
* \param oid OID to translate
*
* \return Length of the string written (excluding final NULL) or
* MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
*/
int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid );
/**
* \brief Translate an X.509 extension OID into local values
*
* \param oid OID to use
* \param ext_type place to store the extension type
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
/**
* \brief Translate an X.509 attribute type OID into the short name
* (e.g. the OID for an X520 Common Name into "CN")
*
* \param oid OID to use
* \param short_name place to store the string pointer
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_attr_short_name( const mbedtls_asn1_buf *oid, const char **short_name );
/**
* \brief Translate PublicKeyAlgorithm OID into pk_type
*
* \param oid OID to use
* \param pk_alg place to store public key algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg );
/**
* \brief Translate pk_type into PublicKeyAlgorithm OID
*
* \param pk_alg Public key type to look for
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
const char **oid, size_t *olen );
#if defined(MBEDTLS_ECP_C)
/**
* \brief Translate NamedCurve OID into an EC group identifier
*
* \param oid OID to use
* \param grp_id place to store group id
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id );
/**
* \brief Translate EC group identifier into NamedCurve OID
*
* \param grp_id EC group identifier
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
const char **oid, size_t *olen );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
/**
* \brief Translate SignatureAlgorithm OID into md_type and pk_type
*
* \param oid OID to use
* \param md_alg place to store message digest algorithm
* \param pk_alg place to store public key algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_sig_alg( const mbedtls_asn1_buf *oid,
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg );
/**
* \brief Translate SignatureAlgorithm OID into description
*
* \param oid OID to use
* \param desc place to store string pointer
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_sig_alg_desc( const mbedtls_asn1_buf *oid, const char **desc );
/**
* \brief Translate md_type and pk_type into SignatureAlgorithm OID
*
* \param md_alg message digest algorithm
* \param pk_alg public key algorithm
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
const char **oid, size_t *olen );
/**
* \brief Translate hash algorithm OID into md_type
*
* \param oid OID to use
* \param md_alg place to store message digest algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
/**
* \brief Translate hmac algorithm OID into md_type
*
* \param oid OID to use
* \param md_hmac place to store message hmac algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */
/**
* \brief Translate Extended Key Usage OID into description
*
* \param oid OID to use
* \param desc place to store string pointer
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
/**
* \brief Translate certificate policies OID into description
*
* \param oid OID to use
* \param desc place to store string pointer
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_certificate_policies( const mbedtls_asn1_buf *oid, const char **desc );
/**
* \brief Translate md_type into hash algorithm OID
*
* \param md_alg message digest algorithm
* \param oid place to store ASN.1 OID string pointer
* \param olen length of the OID
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_oid_by_md( mbedtls_md_type_t md_alg, const char **oid, size_t *olen );
#if defined(MBEDTLS_CIPHER_C)
/**
* \brief Translate encryption algorithm OID into cipher_type
*
* \param oid OID to use
* \param cipher_alg place to store cipher algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_cipher_alg( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg );
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_PKCS12_C)
/**
* \brief Translate PKCS#12 PBE algorithm OID into md_type and
* cipher_type
*
* \param oid OID to use
* \param md_alg place to store message digest algorithm
* \param cipher_alg place to store cipher algorithm
*
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_pkcs12_pbe_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
mbedtls_cipher_type_t *cipher_alg );
#endif /* MBEDTLS_PKCS12_C */
#ifdef __cplusplus
}
#endif
#endif /* oid.h */

126
include/mbedtls/padlock.h Normal file
View File

@ -0,0 +1,126 @@
/**
* \file padlock.h
*
* \brief VIA PadLock ACE for HW encryption/decryption supported by some
* processors
*
* \warning These functions are only for internal use by other library
* functions; you must not call them directly.
*/
/*
* Copyright (C) 2006-2015, 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_PADLOCK_H
#define MBEDTLS_PADLOCK_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/aes.h"
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define MBEDTLS_HAVE_ASAN
#endif
#endif
/* Some versions of ASan result in errors about not enough registers */
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
!defined(MBEDTLS_HAVE_ASAN)
#ifndef MBEDTLS_HAVE_X86
#define MBEDTLS_HAVE_X86
#endif
#include <stdint.h>
#define MBEDTLS_PADLOCK_RNG 0x000C
#define MBEDTLS_PADLOCK_ACE 0x00C0
#define MBEDTLS_PADLOCK_PHE 0x0C00
#define MBEDTLS_PADLOCK_PMM 0x3000
#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15))
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Internal PadLock detection routine
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param feature The feature to detect
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int mbedtls_padlock_has_support( int feature );
/**
* \brief Internal PadLock AES-ECB block en(de)cryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if success, 1 if operation failed
*/
int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal PadLock AES-CBC buffer en(de)cryption
*
* \note This function is only for internal use by other library
* functions; you must not call it directly.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if success, 1 if operation failed
*/
int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* HAVE_X86 */
#endif /* padlock.h */

146
include/mbedtls/pem.h Normal file
View File

@ -0,0 +1,146 @@
/**
* \file pem.h
*
* \brief Privacy Enhanced Mail (PEM) decoding
*/
/*
* Copyright (C) 2006-2015, 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_PEM_H
#define MBEDTLS_PEM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/**
* \name PEM Error codes
* These error codes are returned in case of errors reading the
* PEM data.
* \{
*/
#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */
#define MBEDTLS_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */
#define MBEDTLS_ERR_PEM_ALLOC_FAILED -0x1180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */
#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */
#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */
#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */
#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */
#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */
/* \} name */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_PEM_PARSE_C)
/**
* \brief PEM context structure
*/
typedef struct mbedtls_pem_context
{
unsigned char *buf; /*!< buffer for decoded data */
size_t buflen; /*!< length of the buffer */
unsigned char *info; /*!< buffer for extra header information */
}
mbedtls_pem_context;
/**
* \brief PEM context setup
*
* \param ctx context to be initialized
*/
void mbedtls_pem_init( mbedtls_pem_context *ctx );
/**
* \brief Read a buffer for PEM information and store the resulting
* data into the specified context buffers.
*
* \param ctx context to use
* \param header header string to seek and expect
* \param footer footer string to seek and expect
* \param data source data to look in (must be nul-terminated)
* \param pwd password for decryption (can be NULL)
* \param pwdlen length of password
* \param use_len destination for total length used (set after header is
* correctly read, so unless you get
* MBEDTLS_ERR_PEM_BAD_INPUT_DATA or
* MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
* the length to skip)
*
* \note Attempts to check password correctness by verifying if
* the decrypted text starts with an ASN.1 sequence of
* appropriate length
*
* \return 0 on success, or a specific PEM error code
*/
int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
const unsigned char *data,
const unsigned char *pwd,
size_t pwdlen, size_t *use_len );
/**
* \brief PEM context memory freeing
*
* \param ctx context to be freed
*/
void mbedtls_pem_free( mbedtls_pem_context *ctx );
#endif /* MBEDTLS_PEM_PARSE_C */
#if defined(MBEDTLS_PEM_WRITE_C)
/**
* \brief Write a buffer of PEM information from a DER encoded
* buffer.
*
* \param header The header string to write.
* \param footer The footer string to write.
* \param der_data The DER data to encode.
* \param der_len The length of the DER data \p der_data in Bytes.
* \param buf The buffer to write to.
* \param buf_len The length of the output buffer \p buf in Bytes.
* \param olen The address at which to store the total length written
* or required (if \p buf_len is not enough).
*
* \note You may pass \c NULL for \p buf and \c 0 for \p buf_len
* to request the length of the resulting PEM buffer in
* `*olen`.
*
* \note This function may be called with overlapping \p der_data
* and \p buf buffers.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
* enough to hold the PEM buffer. In this case, `*olen` holds
* the required minimum size of \p buf.
* \return Another PEM or BASE64 error code on other kinds of failure.
*/
int mbedtls_pem_write_buffer( const char *header, const char *footer,
const unsigned char *der_data, size_t der_len,
unsigned char *buf, size_t buf_len, size_t *olen );
#endif /* MBEDTLS_PEM_WRITE_C */
#ifdef __cplusplus
}
#endif
#endif /* pem.h */

881
include/mbedtls/pk.h Normal file
View File

@ -0,0 +1,881 @@
/**
* \file pk.h
*
* \brief Public Key abstraction layer
*/
/*
* Copyright (C) 2006-2015, 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_PK_H
#define MBEDTLS_PK_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/md.h"
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "mbedtls/ecdsa.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */
#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_PK_FILE_IO_ERROR -0x3E00 /**< Read/write of file failed. */
#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80 /**< Unsupported key version */
#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -0x3D00 /**< Invalid key tag or value. */
#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -0x3C80 /**< Key algorithm is unsupported (only RSA and EC are supported). */
#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED -0x3C00 /**< Private key password can't be empty. */
#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH -0x3B80 /**< Given private key password does not allow for correct decryption. */
#define MBEDTLS_ERR_PK_INVALID_PUBKEY -0x3B00 /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 /**< The algorithm tag or value is invalid. */
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The buffer contains a valid signature followed by more data. */
/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 /**< PK hardware accelerator failed. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Public key types
*/
typedef enum {
MBEDTLS_PK_NONE=0,
MBEDTLS_PK_RSA,
MBEDTLS_PK_ECKEY,
MBEDTLS_PK_ECKEY_DH,
MBEDTLS_PK_ECDSA,
MBEDTLS_PK_RSA_ALT,
MBEDTLS_PK_RSASSA_PSS,
MBEDTLS_PK_OPAQUE,
} mbedtls_pk_type_t;
/**
* \brief Options for RSASSA-PSS signature verification.
* See \c mbedtls_rsa_rsassa_pss_verify_ext()
*/
typedef struct mbedtls_pk_rsassa_pss_options
{
mbedtls_md_type_t mgf1_hash_id;
int expected_salt_len;
} mbedtls_pk_rsassa_pss_options;
/**
* \brief Maximum size of a signature made by mbedtls_pk_sign().
*/
/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature
* size among the supported signature types. Do it by starting at 0,
* then incrementally increasing to be large enough for each supported
* signature mechanism.
*
* The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled
* (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C
* nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT).
*/
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0
#if ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) ) && \
MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
/* For RSA, the signature can be as large as the bignum module allows.
* For RSA_ALT, the signature size is not necessarily tied to what the
* bignum module can do, but in the absence of any specific setting,
* we use that (rsa_alt_sign_wrap in pk_wrap will check). */
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
#endif
#if defined(MBEDTLS_ECDSA_C) && \
MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE
/* For ECDSA, the ecdsa module exports a constant for the maximum
* signature size. */
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made
* through the PSA API in the PSA representation. */
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE
#endif
#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE
/* The Mbed TLS representation is different for ECDSA signatures:
* PSA uses the raw concatenation of r and s,
* whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs).
* Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the
* types, lengths (represented by up to 2 bytes), and potential leading
* zeros of the INTEGERs and the SEQUENCE. */
#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE ( PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 )
#endif
#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
/**
* \brief Types for interfacing with the debug module
*/
typedef enum
{
MBEDTLS_PK_DEBUG_NONE = 0,
MBEDTLS_PK_DEBUG_MPI,
MBEDTLS_PK_DEBUG_ECP,
} mbedtls_pk_debug_type;
/**
* \brief Item to send to the debug module
*/
typedef struct mbedtls_pk_debug_item
{
mbedtls_pk_debug_type type;
const char *name;
void *value;
} mbedtls_pk_debug_item;
/** Maximum number of item send for debugging, plus 1 */
#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3
/**
* \brief Public key information and operations
*/
typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
/**
* \brief Public key container
*/
typedef struct mbedtls_pk_context
{
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.
*
* \warning You must make sure the PK context actually holds an RSA context
* before using this function!
*/
static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
{
return( (mbedtls_rsa_context *) (pk).pk_ctx );
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
/**
* Quick access to an EC context inside a PK context.
*
* \warning You must make sure the PK context actually holds an EC context
* before using this function!
*/
static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
{
return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
}
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Types for RSA-alt abstraction
*/
typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len );
typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig );
typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
/**
* \brief Return information associated with the given PK type
*
* \param pk_type PK type to search for.
*
* \return The PK info associated with the type or NULL if not found.
*/
const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
/**
* \brief Initialize a #mbedtls_pk_context (as NONE).
*
* \param ctx The context to initialize.
* This must not be \c NULL.
*/
void mbedtls_pk_init( mbedtls_pk_context *ctx );
/**
* \brief Free the components of a #mbedtls_pk_context.
*
* \param ctx The context to clear. It must have been initialized.
* If this is \c NULL, this function does nothing.
*
* \note For contexts that have been set up with
* mbedtls_pk_setup_opaque(), this does not free the underlying
* PSA key and you still need to call psa_destroy_key()
* independently if you want to destroy that key.
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/**
* \brief Initialize a restart context
*
* \param ctx The context to initialize.
* This must not be \c NULL.
*/
void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
/**
* \brief Free the components of a restart context
*
* \param ctx The context to clear. It must have been initialized.
* If this is \c NULL, this function does nothing.
*/
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.
*
* \param ctx Context to initialize. It must not have been set
* up yet (type #MBEDTLS_PK_NONE).
* \param info Information to use
*
* \return 0 on success,
* MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input,
* MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
*
* \note For contexts holding an RSA-alt key, use
* \c mbedtls_pk_setup_rsa_alt() instead.
*/
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Initialize a PK context to wrap a PSA key.
*
* \note This function replaces mbedtls_pk_setup() for contexts
* that wrap a (possibly opaque) PSA key instead of
* storing and manipulating the key material directly.
*
* \param ctx The context to initialize. It must be empty (type NONE).
* \param key The PSA key to wrap, which must hold an ECC key pair
* (see notes below).
*
* \note The wrapped key must remain valid as long as the
* wrapping PK context is in use, that is at least between
* the point this function is called and the point
* mbedtls_pk_free() is called on this context. The wrapped
* key might then be independently used or destroyed.
*
* \note This function is currently only available for ECC key
* pairs (that is, ECC keys containing private key material).
* Support for other key types may be added later.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
* (context already used, invalid key handle).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
* ECC key pair.
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
*/
int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Initialize an RSA-alt context
*
* \param ctx Context to initialize. It must not have been set
* up yet (type #MBEDTLS_PK_NONE).
* \param key RSA key pointer
* \param decrypt_func Decryption function
* \param sign_func Signing function
* \param key_len_func Function returning key length in bytes
*
* \return 0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the
* context wasn't already initialized as RSA_ALT.
*
* \note This function replaces \c mbedtls_pk_setup() for RSA-alt.
*/
int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
mbedtls_pk_rsa_alt_sign_func sign_func,
mbedtls_pk_rsa_alt_key_len_func key_len_func );
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
/**
* \brief Get the size in bits of the underlying key
*
* \param ctx The context to query. It must have been initialized.
*
* \return Key size in bits, or 0 on error
*/
size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx );
/**
* \brief Get the length in bytes of the underlying key
*
* \param ctx The context to query. It must have been initialized.
*
* \return Key length in bytes, or 0 on error
*/
static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx )
{
return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 );
}
/**
* \brief Tell if a context can do the operation given by type
*
* \param ctx The context to query. It must have been initialized.
* \param type The desired type.
*
* \return 1 if the context can do operations on the given type.
* \return 0 if the context cannot do the operations on the given
* type. This is always the case for a context that has
* been initialized but not set up, or that has been
* cleared with mbedtls_pk_free().
*/
int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
/**
* \brief Verify signature (including padding if relevant).
*
* \param ctx The PK context to use. It must have been set up.
* \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
*
* \return 0 on success (signature is valid),
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen,
* or a specific error code.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
* to verify RSASSA_PSS signatures.
*
* \note If hash_len is 0, then the length associated with md_alg
* is used instead, or an error returned if it is invalid.
*
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
*/
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 The PK context to use. It must have been set up.
* \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.)
*
* \param type Signature type (inc. possible padding type) to verify
* \param options Pointer to type-specific options, or NULL
* \param ctx The PK context to use. It must have been set up.
* \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
*
* \return 0 on success (signature is valid),
* #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
* used for this type of signatures,
* #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
* signature in sig but its length is less than \p siglen,
* or a specific error code.
*
* \note If hash_len is 0, then the length associated with md_alg
* is used instead, or an error returned if it is invalid.
*
* \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
*
* \note If type is MBEDTLS_PK_RSASSA_PSS, then options must point
* to a mbedtls_pk_rsassa_pss_options structure,
* otherwise it must be NULL.
*/
int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
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 Make signature, including padding if relevant.
*
* \param ctx The PK context to use. It must have been set up
* with 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.
* It must have enough room for the signature.
* #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
* You may use a smaller buffer if it is large enough
* given the key type.
* \param sig_len On successful return,
* the number of bytes written to \p sig.
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 on success, or a specific error code.
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
* There is no interface in the PK module to make RSASSA-PSS
* signatures yet.
*
* \note If hash_len is 0, then the length associated with md_alg
* is used instead, or an error returned if it is invalid.
*
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
*/
int mbedtls_pk_sign( 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 );
/**
* \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 The PK context to use. It must have been set up
* with a private key.
* \param md_alg Hash algorithm used (see notes for mbedtls_pk_sign())
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes for mbedtls_pk_sign())
* \param sig Place to write the signature.
* It must have enough room for the signature.
* #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
* You may use a smaller buffer if it is large enough
* given the key type.
* \param sig_len On successful return,
* the number of bytes written to \p sig.
* \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().
* \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).
*
* \param ctx The PK context to use. It must have been set up
* with a private key.
* \param input Input to decrypt
* \param ilen Input size
* \param output Decrypted output
* \param olen Decrypted message length
* \param osize Size of the output buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
*
* \return 0 on success, or a specific error code.
*/
int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Encrypt message (including padding if relevant).
*
* \param ctx The PK context to use. It must have been set up.
* \param input Message to encrypt
* \param ilen Message size
* \param output Encrypted output
* \param olen Encrypted output length
* \param osize Size of the output buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note For RSA keys, the default padding type is PKCS#1 v1.5.
*
* \return 0 on success, or a specific error code.
*/
int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Check if a public-private pair of keys matches.
*
* \param pub Context holding a public key.
* \param prv Context holding a private (and public) key.
*
* \return \c 0 on success (keys were checked and match each other).
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
* be checked - in that case they may or may not match.
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
* \return Another non-zero value if the keys do not match.
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
/**
* \brief Export debug information
*
* \param ctx The PK context to use. It must have been initialized.
* \param items Place to write debug items
*
* \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
*/
int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items );
/**
* \brief Access the type name
*
* \param ctx The PK context to use. It must have been initialized.
*
* \return Type name on success, or "invalid PK"
*/
const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
/**
* \brief Get the key type
*
* \param ctx The PK context to use. It must have been initialized.
*
* \return Type on success.
* \return #MBEDTLS_PK_NONE for a context that has not been set up.
*/
mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
#if defined(MBEDTLS_PK_PARSE_C)
/** \ingroup pk_module */
/**
* \brief Parse a private key in PEM or DER format
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
* The buffer must contain the input exactly, with no
* extra trailing material. For PEM, the buffer must
* contain a null-terminated string.
* \param keylen Size of \b key in bytes.
* For PEM data, this includes the terminating null byte,
* so \p keylen must be equal to `strlen(key) + 1`.
* \param pwd Optional password for decryption.
* Pass \c NULL if expecting a non-encrypted key.
* Pass a string of \p pwdlen bytes if expecting an encrypted
* key; a non-encrypted key will also be accepted.
* The empty password is not supported.
* \param pwdlen Size of the password in bytes.
* Ignored if \p pwd is \c NULL.
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
* specific key type, check the result with mbedtls_pk_can_do().
*
* \note The key is also checked for correctness.
*
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
const unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen );
/** \ingroup pk_module */
/**
* \brief Parse a public key in PEM or DER format
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param key Input buffer to parse.
* The buffer must contain the input exactly, with no
* extra trailing material. For PEM, the buffer must
* contain a null-terminated string.
* \param keylen Size of \b key in bytes.
* For PEM data, this includes the terminating null byte,
* so \p keylen must be equal to `strlen(key) + 1`.
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
* specific key type, check the result with mbedtls_pk_can_do().
*
* \note The key is also checked for correctness.
*
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
const unsigned char *key, size_t keylen );
#if defined(MBEDTLS_FS_IO)
/** \ingroup pk_module */
/**
* \brief Load and parse a private key
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param path filename to read the private key from
* \param password Optional password to decrypt the file.
* Pass \c NULL if expecting a non-encrypted key.
* Pass a null-terminated string if expecting an encrypted
* key; a non-encrypted key will also be accepted.
* The empty password is not supported.
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
* specific key type, check the result with mbedtls_pk_can_do().
*
* \note The key is also checked for correctness.
*
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
const char *path, const char *password );
/** \ingroup pk_module */
/**
* \brief Load and parse a public key
*
* \param ctx The PK context to fill. It must have been initialized
* but not set up.
* \param path filename to read the public key from
*
* \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If
* you need a specific key type, check the result with
* mbedtls_pk_can_do().
*
* \note The key is also checked for correctness.
*
* \return 0 if successful, or a specific PK or PEM error code
*/
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#endif /* MBEDTLS_PK_PARSE_C */
#if defined(MBEDTLS_PK_WRITE_C)
/**
* \brief Write a private key to a PKCS#1 or SEC1 DER structure
* Note: data is written at the end of the buffer! Use the
* return value to determine where you should start
* using the buffer
*
* \param ctx PK context which must contain a valid private key.
* \param buf buffer to write to
* \param size size of the buffer
*
* \return length of data written if successful, or a specific
* error code
*/
int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
/**
* \brief Write a public key to a SubjectPublicKeyInfo DER structure
* Note: data is written at the end of the buffer! Use the
* return value to determine where you should start
* using the buffer
*
* \param ctx PK context which must contain a valid public or private key.
* \param buf buffer to write to
* \param size size of the buffer
*
* \return length of data written if successful, or a specific
* error code
*/
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
#if defined(MBEDTLS_PEM_WRITE_C)
/**
* \brief Write a public key to a PEM string
*
* \param ctx PK context which must contain a valid public or private key.
* \param buf Buffer to write to. The output includes a
* terminating null byte.
* \param size Size of the buffer in bytes.
*
* \return 0 if successful, or a specific error code
*/
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
/**
* \brief Write a private key to a PKCS#1 or SEC1 PEM string
*
* \param ctx PK context which must contain a valid private key.
* \param buf Buffer to write to. The output includes a
* terminating null byte.
* \param size Size of the buffer in bytes.
*
* \return 0 if successful, or a specific error code
*/
int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_PK_WRITE_C */
/*
* WARNING: Low-level functions. You probably do not want to use these unless
* you are certain you do ;)
*/
#if defined(MBEDTLS_PK_PARSE_C)
/**
* \brief Parse a SubjectPublicKeyInfo DER structure
*
* \param p the position in the ASN.1 data
* \param end end of the buffer
* \param pk The PK context to fill. It must have been initialized
* but not set up.
*
* \return 0 if successful, or a specific PK error code
*/
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
mbedtls_pk_context *pk );
#endif /* MBEDTLS_PK_PARSE_C */
#if defined(MBEDTLS_PK_WRITE_C)
/**
* \brief Write a subjectPublicKey to ASN.1 data
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param key PK context which must contain a valid public or private key.
*
* \return the length written or a negative error code
*/
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key );
#endif /* MBEDTLS_PK_WRITE_C */
/*
* Internal module functions. You probably do not want to use these unless you
* know you do.
*/
#if defined(MBEDTLS_FS_IO)
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Turn an EC key into an opaque one.
*
* \warning This is a temporary utility function for tests. It might
* change or be removed at any time without notice.
*
* \note Only ECDSA keys are supported so far. Signing with the
* specified hash is the only allowed use of that key.
*
* \param pk Input: the EC key to import to a PSA key.
* Output: a PK context wrapping that PSA key.
* \param handle Output: a PSA key handle.
* It's the caller's responsibility to call
* psa_destroy_key() on that handle after calling
* mbedtls_pk_free() on the PK context.
* \param hash_alg The hash algorithm to allow for use with that key.
*
* \return \c 0 if successful.
* \return An Mbed TLS error code otherwise.
*/
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
psa_key_handle_t *handle,
psa_algorithm_t hash_alg );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_PK_H */

View File

@ -0,0 +1,142 @@
/**
* \file pk_internal.h
*
* \brief Public Key abstraction layer: wrapper functions
*/
/*
* Copyright (C) 2006-2015, 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_PK_WRAP_H
#define MBEDTLS_PK_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/pk.h"
struct mbedtls_pk_info_t
{
/** Public key type */
mbedtls_pk_type_t type;
/** Type name */
const char *name;
/** Get key size in bits */
size_t (*get_bitlen)( const void * );
/** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
int (*can_do)( mbedtls_pk_type_t type );
/** Verify signature */
int (*verify_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 );
/** Make signature */
int (*sign_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 );
#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,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/** Encrypt message */
int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/** Check public-private key pair */
int (*check_pair_func)( const void *pub, const void *prv );
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** 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 );
};
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/* Container for RSA-alt */
typedef struct
{
void *key;
mbedtls_pk_rsa_alt_decrypt_func decrypt_func;
mbedtls_pk_rsa_alt_sign_func sign_func;
mbedtls_pk_rsa_alt_key_len_func key_len_func;
} mbedtls_rsa_alt_context;
#endif
#if defined(MBEDTLS_RSA_C)
extern const mbedtls_pk_info_t mbedtls_rsa_info;
#endif
#if defined(MBEDTLS_ECP_C)
extern const mbedtls_pk_info_t mbedtls_eckey_info;
extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
#endif
#if defined(MBEDTLS_ECDSA_C)
extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
#endif
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
extern const mbedtls_pk_info_t mbedtls_pk_opaque_info;
#endif
#endif /* MBEDTLS_PK_WRAP_H */

130
include/mbedtls/pkcs12.h Normal file
View File

@ -0,0 +1,130 @@
/**
* \file pkcs12.h
*
* \brief PKCS#12 Personal Information Exchange Syntax
*/
/*
* Copyright (C) 2006-2015, 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_PKCS12_H
#define MBEDTLS_PKCS12_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/md.h"
#include "mbedtls/cipher.h"
#include "mbedtls/asn1.h"
#include <stddef.h>
#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */
#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */
#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */
#define MBEDTLS_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */
#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */
#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */
#define MBEDTLS_PKCS12_PBE_DECRYPT 0
#define MBEDTLS_PKCS12_PBE_ENCRYPT 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_ASN1_PARSE_C)
/**
* \brief PKCS12 Password Based function (encryption / decryption)
* for pbeWithSHAAnd128BitRC4
*
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
* \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT
* \param pwd the password used (may be NULL if no password is used)
* \param pwdlen length of the password (may be 0)
* \param input the input data
* \param len data length
* \param output the output buffer
*
* \return 0 if successful, or a MBEDTLS_ERR_XXX code
*/
int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *input, size_t len,
unsigned char *output );
/**
* \brief PKCS12 Password Based function (encryption / decryption)
* for cipher-based and mbedtls_md-based PBE's
*
* \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
* \param mode either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT
* \param cipher_type the cipher used
* \param md_type the mbedtls_md used
* \param pwd the password used (may be NULL if no password is used)
* \param pwdlen length of the password (may be 0)
* \param input the input data
* \param len data length
* \param output the output buffer
*
* \return 0 if successful, or a MBEDTLS_ERR_XXX code
*/
int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *input, size_t len,
unsigned char *output );
#endif /* MBEDTLS_ASN1_PARSE_C */
/**
* \brief The PKCS#12 derivation function uses a password and a salt
* to produce pseudo-random bits for a particular "purpose".
*
* Depending on the given id, this function can produce an
* encryption/decryption key, an nitialization vector or an
* integrity key.
*
* \param data buffer to store the derived data in
* \param datalen length to fill
* \param pwd password to use (may be NULL if no password is used)
* \param pwdlen length of the password (may be 0)
* \param salt salt buffer to use
* \param saltlen length of the salt
* \param mbedtls_md mbedtls_md type to use during the derivation
* \param id id that describes the purpose (can be MBEDTLS_PKCS12_DERIVE_KEY,
* MBEDTLS_PKCS12_DERIVE_IV or MBEDTLS_PKCS12_DERIVE_MAC_KEY)
* \param iterations number of iterations
*
* \return 0 if successful, or a MD, BIGNUM type error.
*/
int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *salt, size_t saltlen,
mbedtls_md_type_t mbedtls_md, int id, int iterations );
#ifdef __cplusplus
}
#endif
#endif /* pkcs12.h */

109
include/mbedtls/pkcs5.h Normal file
View File

@ -0,0 +1,109 @@
/**
* \file pkcs5.h
*
* \brief PKCS#5 functions
*
* \author Mathias Olsson <mathias@kompetensum.com>
*/
/*
* Copyright (C) 2006-2015, 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_PKCS5_H
#define MBEDTLS_PKCS5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/asn1.h"
#include "mbedtls/md.h"
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00 /**< Unexpected ASN.1 data. */
#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80 /**< Requested encryption or digest alg not available. */
#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00 /**< Given private key password does not allow for correct decryption. */
#define MBEDTLS_PKCS5_DECRYPT 0
#define MBEDTLS_PKCS5_ENCRYPT 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_ASN1_PARSE_C)
/**
* \brief PKCS#5 PBES2 function
*
* \param pbe_params the ASN.1 algorithm parameters
* \param mode either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT
* \param pwd password to use when generating key
* \param pwdlen length of password
* \param data data to process
* \param datalen length of data
* \param output output buffer
*
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
*/
int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output );
#endif /* MBEDTLS_ASN1_PARSE_C */
/**
* \brief PKCS#5 PBKDF2 using HMAC
*
* \param ctx Generic HMAC context
* \param password Password to use when generating key
* \param plen Length of password
* \param salt Salt to use when generating key
* \param slen Length of salt
* \param iteration_count Iteration count
* \param key_length Length of generated key in bytes
* \param output Generated key. Must be at least as big as key_length
*
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
*/
int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
size_t plen, const unsigned char *salt, size_t slen,
unsigned int iteration_count,
uint32_t key_length, unsigned char *output );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_pkcs5_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* pkcs5.h */

419
include/mbedtls/platform.h Normal file
View File

@ -0,0 +1,419 @@
/**
* \file platform.h
*
* \brief This file contains the definitions and functions of the
* Mbed TLS platform abstraction layer.
*
* The platform abstraction layer removes the need for the library
* to directly link to standard C library functions or operating
* system services, making the library easier to port and embed.
* Application developers and users of the library can provide their own
* implementations of these functions, or implementations specific to
* their platform, which can be statically linked to the library or
* dynamically configured at runtime.
*/
/*
* 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_PLATFORM_H
#define MBEDTLS_PLATFORM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 /**< Hardware accelerator failed */
#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
/* The older Microsoft Windows common runtime provides non-conforming
* implementations of some standard library functions, including snprintf
* and vsnprintf. This affects MSVC and MinGW builds.
*/
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
#endif
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
#else
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
#endif
#endif
#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
#else
#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
#endif
#endif
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_TIME)
#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */
#endif
#if defined(MBEDTLS_FS_IO)
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read
#endif
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write
#endif
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile"
#endif
#endif /* MBEDTLS_FS_IO */
#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
#include MBEDTLS_PLATFORM_STD_MEM_HDR
#endif
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
/* \} name SECTION: Module settings */
/*
* The function pointers for calloc and free.
*/
#if defined(MBEDTLS_PLATFORM_MEMORY)
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
#else
/* For size_t */
#include <stddef.h>
extern void *mbedtls_calloc( size_t n, size_t size );
extern void mbedtls_free( void *ptr );
/**
* \brief This function dynamically sets the memory-management
* functions used by the library, during runtime.
*
* \param calloc_func The \c calloc function implementation.
* \param free_func The \c free function implementation.
*
* \return \c 0.
*/
int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) );
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
#else /* !MBEDTLS_PLATFORM_MEMORY */
#define mbedtls_free free
#define mbedtls_calloc calloc
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
/*
* The function pointers for fprintf
*/
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
/* We need FILE * */
#include <stdio.h>
extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
/**
* \brief This function dynamically configures the fprintf
* function that is called when the
* mbedtls_fprintf() function is invoked by the library.
*
* \param fprintf_func The \c fprintf function implementation.
*
* \return \c 0.
*/
int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
... ) );
#else
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
#else
#define mbedtls_fprintf fprintf
#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
/*
* The function pointers for printf
*/
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
extern int (*mbedtls_printf)( const char *format, ... );
/**
* \brief This function dynamically configures the snprintf
* function that is called when the mbedtls_snprintf()
* function is invoked by the library.
*
* \param printf_func The \c printf function implementation.
*
* \return \c 0 on success.
*/
int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
#else
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
/*
* The function pointers for snprintf
*
* The snprintf implementation should conform to C99:
* - it *must* always correctly zero-terminate the buffer
* (except when n == 0, then it must leave the buffer untouched)
* - however it is acceptable to return -1 instead of the required length when
* the destination buffer is too short.
*/
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
/**
* \brief This function allows configuring a custom
* \c snprintf function pointer.
*
* \param snprintf_func The \c snprintf function implementation.
*
* \return \c 0 on success.
*/
int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
const char * format, ... ) );
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
#else
#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF
#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
/*
* The function pointers for vsnprintf
*
* The vsnprintf implementation should conform to C99:
* - it *must* always correctly zero-terminate the buffer
* (except when n == 0, then it must leave the buffer untouched)
* - however it is acceptable to return -1 instead of the required length when
* the destination buffer is too short.
*/
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
#include <stdarg.h>
/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
#endif
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
#include <stdarg.h>
extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
/**
* \brief Set your own snprintf function pointer
*
* \param vsnprintf_func The \c vsnprintf function implementation
*
* \return \c 0
*/
int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
const char * format, va_list arg ) );
#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
#else
#define mbedtls_vsnprintf vsnprintf
#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
/*
* The function pointers for exit
*/
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
extern void (*mbedtls_exit)( int status );
/**
* \brief This function dynamically configures the exit
* function that is called when the mbedtls_exit()
* function is invoked by the library.
*
* \param exit_func The \c exit function implementation.
*
* \return \c 0 on success.
*/
int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
#else
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
#else
#define mbedtls_exit exit
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
/*
* The default exit values
*/
#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
#else
#define MBEDTLS_EXIT_SUCCESS 0
#endif
#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
#else
#define MBEDTLS_EXIT_FAILURE 1
#endif
/*
* The function pointers for reading from and writing a seed file to
* Non-Volatile storage (NV) in a platform-independent way
*
* Only enabled when the NV seed entropy source is enabled
*/
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
/* Internal standard platform definitions */
int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
/**
* \brief This function allows configuring custom seed file writing and
* reading functions.
*
* \param nv_seed_read_func The seed reading function implementation.
* \param nv_seed_write_func The seed writing function implementation.
*
* \return \c 0 on success.
*/
int mbedtls_platform_set_nv_seed(
int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
);
#else
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
#else
#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read
#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write
#endif
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
/**
* \brief The platform context structure.
*
* \note This structure may be used to assist platform-specific
* setup or teardown operations.
*/
typedef struct mbedtls_platform_context
{
char dummy; /**< A placeholder member, as empty structs are not portable. */
}
mbedtls_platform_context;
#else
#include "platform_alt.h"
#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
/**
* \brief This function performs any platform-specific initialization
* operations.
*
* \note This function should be called before any other library functions.
*
* Its implementation is platform-specific, and unless
* platform-specific code is provided, it does nothing.
*
* \note The usage and necessity of this function is dependent on the platform.
*
* \param ctx The platform context.
*
* \return \c 0 on success.
*/
int mbedtls_platform_setup( mbedtls_platform_context *ctx );
/**
* \brief This function performs any platform teardown operations.
*
* \note This function should be called after every other Mbed TLS module
* has been correctly freed using the appropriate free function.
*
* Its implementation is platform-specific, and unless
* platform-specific code is provided, it does nothing.
*
* \note The usage and necessity of this function is dependent on the platform.
*
* \param ctx The platform context.
*
*/
void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
#ifdef __cplusplus
}
#endif
#endif /* platform.h */

View File

@ -0,0 +1,82 @@
/**
* \file platform_time.h
*
* \brief mbed TLS Platform time abstraction
*/
/*
* 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)
*/
#ifndef MBEDTLS_PLATFORM_TIME_H
#define MBEDTLS_PLATFORM_TIME_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
/*
* The time_t datatype
*/
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
#else
/* For time_t */
#include <time.h>
typedef time_t mbedtls_time_t;
#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
/*
* The function pointers for time
*/
#if defined(MBEDTLS_PLATFORM_TIME_ALT)
extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
/**
* \brief Set your own time function pointer
*
* \param time_func the time function implementation
*
* \return 0
*/
int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
#else
#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO
#else
#define mbedtls_time time
#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
#endif /* MBEDTLS_PLATFORM_TIME_ALT */
#ifdef __cplusplus
}
#endif
#endif /* platform_time.h */

View File

@ -0,0 +1,196 @@
/**
* \file platform_util.h
*
* \brief Common and shared functions used by multiple modules in the Mbed TLS
* library.
*/
/*
* Copyright (C) 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_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" {
#endif
#if defined(MBEDTLS_CHECK_PARAMS)
#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
* (which is what our config.h suggests). */
#include <assert.h>
#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
#if defined(MBEDTLS_PARAM_FAILED)
/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
*
* This flag can be used to check whether it is safe to assume that
* MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
*/
#define MBEDTLS_PARAM_FAILED_ALT
#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
#define MBEDTLS_PARAM_FAILED_ALT
#else /* MBEDTLS_PARAM_FAILED */
#define MBEDTLS_PARAM_FAILED( cond ) \
mbedtls_param_failed( #cond, __FILE__, __LINE__ )
/**
* \brief User supplied callback function for parameter validation failure.
* See #MBEDTLS_CHECK_PARAMS for context.
*
* This function will be called unless an alternative treatement
* is defined through the #MBEDTLS_PARAM_FAILED macro.
*
* This function can return, and the operation will be aborted, or
* alternatively, through use of setjmp()/longjmp() can resume
* execution in the application code.
*
* \param failure_condition The assertion that didn't hold.
* \param file The file where the assertion failed.
* \param line The line in the file where the assertion failed.
*/
void mbedtls_param_failed( const char *failure_condition,
const char *file,
int line );
#endif /* MBEDTLS_PARAM_FAILED */
/* Internal macro meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \
do { \
if( !(cond) ) \
{ \
MBEDTLS_PARAM_FAILED( cond ); \
return( ret ); \
} \
} while( 0 )
/* Internal macro meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE( cond ) \
do { \
if( !(cond) ) \
{ \
MBEDTLS_PARAM_FAILED( cond ); \
return; \
} \
} while( 0 )
#else /* MBEDTLS_CHECK_PARAMS */
/* Internal macros meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
#endif /* MBEDTLS_CHECK_PARAMS */
/* Internal helper macros for deprecating API constants. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
* to avoid conflict with other headers which define and use
* it, too. We might want to move all these definitions here at
* some point for uniformity. */
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \
( (mbedtls_deprecated_string_constant_t) ( VAL ) )
MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \
( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
#undef MBEDTLS_DEPRECATED
#else /* MBEDTLS_DEPRECATED_WARNING */
#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
#endif /* MBEDTLS_DEPRECATED_WARNING */
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Securely zeroize a buffer
*
* The function is meant to wipe the data contained in a buffer so
* that it can no longer be recovered even if the program memory
* is later compromised. Call this function on sensitive data
* stored on the stack before returning from a function, and on
* sensitive data stored on the heap before freeing the heap
* object.
*
* It is extremely difficult to guarantee that calls to
* mbedtls_platform_zeroize() are not removed by aggressive
* compiler optimizations in a portable way. For this reason, Mbed
* TLS provides the configuration option
* MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
* mbedtls_platform_zeroize() to use a suitable implementation for
* their platform and needs
*
* \param buf Buffer to be zeroized
* \param len Length of the buffer in bytes
*
*/
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
#endif /* MBEDTLS_PLATFORM_UTIL_H */

192
include/mbedtls/poly1305.h Normal file
View File

@ -0,0 +1,192 @@
/**
* \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). */
/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be
* used. */
#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */
/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#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. This must
* not be \c NULL.
*/
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. This may be \c NULL, in which
* case this function is a no-op. If it is not \c NULL, it must
* point to an initialized Poly1305 context.
*/
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.
* This must be initialized.
* \param key The buffer containing the \c 32 Byte (\c 256 Bit) key.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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.
* This must be initialized and bound to a 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 \c NULL if `ilen == 0`.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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.
* This must be initialized and bound to a key.
* \param mac The buffer to where the MAC is written. This must
* be a writable buffer of length \c 16 Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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 \c 32 Byte (\c 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 \c NULL if `ilen == 0`.
* \param mac The buffer to where the MAC is written. This must be
* a writable buffer of length \c 16 Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
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 */

422
include/mbedtls/psa_util.h Normal file
View File

@ -0,0 +1,422 @@
/**
* \file psa_util.h
*
* \brief Utility functions for the use of the PSA Crypto library.
*
* \warning This function is not part of the public API and may
* change at any time.
*/
/*
* 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_PSA_UTIL_H
#define MBEDTLS_PSA_UTIL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "mbedtls/ecp.h"
#include "mbedtls/md.h"
#include "mbedtls/pk.h"
#include "mbedtls/oid.h"
#include <string.h>
/* Translations for symmetric crypto. */
static inline psa_key_type_t mbedtls_psa_translate_cipher_type(
mbedtls_cipher_type_t cipher )
{
switch( cipher )
{
case MBEDTLS_CIPHER_AES_128_CCM:
case MBEDTLS_CIPHER_AES_192_CCM:
case MBEDTLS_CIPHER_AES_256_CCM:
case MBEDTLS_CIPHER_AES_128_GCM:
case MBEDTLS_CIPHER_AES_192_GCM:
case MBEDTLS_CIPHER_AES_256_GCM:
case MBEDTLS_CIPHER_AES_128_CBC:
case MBEDTLS_CIPHER_AES_192_CBC:
case MBEDTLS_CIPHER_AES_256_CBC:
return( PSA_KEY_TYPE_AES );
/* ARIA not yet supported in PSA. */
/* case MBEDTLS_CIPHER_ARIA_128_CCM:
case MBEDTLS_CIPHER_ARIA_192_CCM:
case MBEDTLS_CIPHER_ARIA_256_CCM:
case MBEDTLS_CIPHER_ARIA_128_GCM:
case MBEDTLS_CIPHER_ARIA_192_GCM:
case MBEDTLS_CIPHER_ARIA_256_GCM:
case MBEDTLS_CIPHER_ARIA_128_CBC:
case MBEDTLS_CIPHER_ARIA_192_CBC:
case MBEDTLS_CIPHER_ARIA_256_CBC:
return( PSA_KEY_TYPE_ARIA ); */
default:
return( 0 );
}
}
static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode(
mbedtls_cipher_mode_t mode, size_t taglen )
{
switch( mode )
{
case MBEDTLS_MODE_GCM:
return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, taglen ) );
case MBEDTLS_MODE_CCM:
return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, taglen ) );
case MBEDTLS_MODE_CBC:
if( taglen == 0 )
return( PSA_ALG_CBC_NO_PADDING );
/* Intentional fallthrough for taglen != 0 */
/* fallthrough */
default:
return( 0 );
}
}
static inline psa_key_usage_t mbedtls_psa_translate_cipher_operation(
mbedtls_operation_t op )
{
switch( op )
{
case MBEDTLS_ENCRYPT:
return( PSA_KEY_USAGE_ENCRYPT );
case MBEDTLS_DECRYPT:
return( PSA_KEY_USAGE_DECRYPT );
default:
return( 0 );
}
}
/* Translations for hashing. */
static inline psa_algorithm_t mbedtls_psa_translate_md( mbedtls_md_type_t md_alg )
{
switch( md_alg )
{
#if defined(MBEDTLS_MD2_C)
case MBEDTLS_MD_MD2:
return( PSA_ALG_MD2 );
#endif
#if defined(MBEDTLS_MD4_C)
case MBEDTLS_MD_MD4:
return( PSA_ALG_MD4 );
#endif
#if defined(MBEDTLS_MD5_C)
case MBEDTLS_MD_MD5:
return( PSA_ALG_MD5 );
#endif
#if defined(MBEDTLS_SHA1_C)
case MBEDTLS_MD_SHA1:
return( PSA_ALG_SHA_1 );
#endif
#if defined(MBEDTLS_SHA256_C)
case MBEDTLS_MD_SHA224:
return( PSA_ALG_SHA_224 );
case MBEDTLS_MD_SHA256:
return( PSA_ALG_SHA_256 );
#endif
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA384:
return( PSA_ALG_SHA_384 );
case MBEDTLS_MD_SHA512:
return( PSA_ALG_SHA_512 );
#endif
#if defined(MBEDTLS_RIPEMD160_C)
case MBEDTLS_MD_RIPEMD160:
return( PSA_ALG_RIPEMD160 );
#endif
case MBEDTLS_MD_NONE: /* Intentional fallthrough */
default:
return( 0 );
}
}
/* Translations for ECC. */
static inline int mbedtls_psa_get_ecc_oid_from_id(
psa_ecc_curve_t curve, size_t bits,
char const **oid, size_t *oid_len )
{
switch( curve )
{
case PSA_ECC_CURVE_SECP_R1:
switch( bits )
{
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
case 192:
*oid = MBEDTLS_OID_EC_GRP_SECP192R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP192R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
case 224:
*oid = MBEDTLS_OID_EC_GRP_SECP224R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP224R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_SECP256R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP256R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
case 384:
*oid = MBEDTLS_OID_EC_GRP_SECP384R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP384R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
case 521:
*oid = MBEDTLS_OID_EC_GRP_SECP521R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP521R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
}
break;
case PSA_ECC_CURVE_SECP_K1:
switch( bits )
{
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
case 192:
*oid = MBEDTLS_OID_EC_GRP_SECP192K1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP192K1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
case 224:
*oid = MBEDTLS_OID_EC_GRP_SECP224K1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP224K1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_SECP256K1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_SECP256K1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
}
break;
case PSA_ECC_CURVE_BRAINPOOL_P_R1:
switch( bits )
{
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
case 256:
*oid = MBEDTLS_OID_EC_GRP_BP256R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP256R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
case 384:
*oid = MBEDTLS_OID_EC_GRP_BP384R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP384R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
case 512:
*oid = MBEDTLS_OID_EC_GRP_BP512R1;
*oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_EC_GRP_BP512R1 );
return( 0 );
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
}
break;
}
(void) oid;
(void) oid_len;
return( -1 );
}
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH 1
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 521 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 521 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 192 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 224 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 256 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 384 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
#if MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH < ( 2 * ( ( 512 + 7 ) / 8 ) + 1 )
#undef MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH
#define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH ( 2 * ( ( 512 + 7 ) / 8 ) + 1 )
#endif
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
/* Translations for PK layer */
static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
{
switch( status )
{
case PSA_SUCCESS:
return( 0 );
case PSA_ERROR_NOT_SUPPORTED:
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
case PSA_ERROR_INSUFFICIENT_MEMORY:
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
case PSA_ERROR_INSUFFICIENT_ENTROPY:
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
case PSA_ERROR_BAD_STATE:
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
/* All other failures */
case PSA_ERROR_COMMUNICATION_FAILURE:
case PSA_ERROR_HARDWARE_FAILURE:
case PSA_ERROR_CORRUPTION_DETECTED:
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
default: /* We return the same as for the 'other failures',
* but list them separately nonetheless to indicate
* which failure conditions we have considered. */
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
}
}
/* Translations for ECC */
/* This function transforms an ECC group identifier from
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
* into a PSA ECC group identifier. */
#if defined(MBEDTLS_ECP_C)
static inline psa_key_type_t mbedtls_psa_parse_tls_ecc_group(
uint16_t tls_ecc_grp_reg_id, size_t *bits )
{
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_tls_id( tls_ecc_grp_reg_id );
if( curve_info == NULL )
return( 0 );
return( PSA_KEY_TYPE_ECC_KEY_PAIR(
mbedtls_ecc_group_to_psa( curve_info->grp_id, bits ) ) );
}
#endif /* MBEDTLS_ECP_C */
/* This function takes a buffer holding an EC public key
* exported through psa_export_public_key(), and converts
* it into an ECPoint structure to be put into a ClientKeyExchange
* message in an ECDHE exchange.
*
* Both the present and the foreseeable future format of EC public keys
* used by PSA have the ECPoint structure contained in the exported key
* as a subbuffer, and the function merely selects this subbuffer instead
* of making a copy.
*/
static inline int mbedtls_psa_tls_psa_ec_to_ecpoint( unsigned char *src,
size_t srclen,
unsigned char **dst,
size_t *dstlen )
{
*dst = src;
*dstlen = srclen;
return( 0 );
}
/* This function takes a buffer holding an ECPoint structure
* (as contained in a TLS ServerKeyExchange message for ECDHE
* exchanges) and converts it into a format that the PSA key
* agreement API understands.
*/
static inline int mbedtls_psa_tls_ecpoint_to_psa_ec( unsigned char const *src,
size_t srclen,
unsigned char *dst,
size_t dstlen,
size_t *olen )
{
if( srclen > dstlen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
memcpy( dst, src, srclen );
*olen = srclen;
return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PSA_UTIL_H */

237
include/mbedtls/ripemd160.h Normal file
View File

@ -0,0 +1,237 @@
/**
* \file ripemd160.h
*
* \brief RIPE MD-160 message digest
*/
/*
* Copyright (C) 2006-2015, 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_RIPEMD160_H
#define MBEDTLS_RIPEMD160_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used.
*/
#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_RIPEMD160_ALT)
// Regular implementation
//
/**
* \brief RIPEMD-160 context structure
*/
typedef struct mbedtls_ripemd160_context
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[5]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_ripemd160_context;
#else /* MBEDTLS_RIPEMD160_ALT */
#include "ripemd160_alt.h"
#endif /* MBEDTLS_RIPEMD160_ALT */
/**
* \brief Initialize RIPEMD-160 context
*
* \param ctx RIPEMD-160 context to be initialized
*/
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx );
/**
* \brief Clear RIPEMD-160 context
*
* \param ctx RIPEMD-160 context to be cleared
*/
void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx );
/**
* \brief Clone (the state of) an RIPEMD-160 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
const mbedtls_ripemd160_context *src );
/**
* \brief RIPEMD-160 context setup
*
* \param ctx context to be initialized
*
* \return 0 if successful
*/
int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx );
/**
* \brief RIPEMD-160 process buffer
*
* \param ctx RIPEMD-160 context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \return 0 if successful
*/
int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief RIPEMD-160 final digest
*
* \param ctx RIPEMD-160 context
* \param output RIPEMD-160 checksum result
*
* \return 0 if successful
*/
int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
unsigned char output[20] );
/**
* \brief RIPEMD-160 process data block (internal use only)
*
* \param ctx RIPEMD-160 context
* \param data buffer holding one block of data
*
* \return 0 if successful
*/
int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief RIPEMD-160 context setup
*
* \deprecated Superseded by mbedtls_ripemd160_starts_ret() in 2.7.0
*
* \param ctx context to be initialized
*/
MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts(
mbedtls_ripemd160_context *ctx );
/**
* \brief RIPEMD-160 process buffer
*
* \deprecated Superseded by mbedtls_ripemd160_update_ret() in 2.7.0
*
* \param ctx RIPEMD-160 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
MBEDTLS_DEPRECATED void mbedtls_ripemd160_update(
mbedtls_ripemd160_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief RIPEMD-160 final digest
*
* \deprecated Superseded by mbedtls_ripemd160_finish_ret() in 2.7.0
*
* \param ctx RIPEMD-160 context
* \param output RIPEMD-160 checksum result
*/
MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish(
mbedtls_ripemd160_context *ctx,
unsigned char output[20] );
/**
* \brief RIPEMD-160 process data block (internal use only)
*
* \deprecated Superseded by mbedtls_internal_ripemd160_process() in 2.7.0
*
* \param ctx RIPEMD-160 context
* \param data buffer holding one block of data
*/
MBEDTLS_DEPRECATED void mbedtls_ripemd160_process(
mbedtls_ripemd160_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Output = RIPEMD-160( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output RIPEMD-160 checksum result
*
* \return 0 if successful
*/
int mbedtls_ripemd160_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Output = RIPEMD-160( input buffer )
*
* \deprecated Superseded by mbedtls_ripemd160_ret() in 2.7.0
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output RIPEMD-160 checksum result
*/
MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input,
size_t ilen,
unsigned char output[20] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_ripemd160_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_ripemd160.h */

1277
include/mbedtls/rsa.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,226 @@
/**
* \file rsa_internal.h
*
* \brief Context-independent RSA helper functions
*
* This module declares some RSA-related helper functions useful when
* implementing the RSA interface. These functions are provided in a separate
* compilation unit in order to make it easy for designers of alternative RSA
* implementations to use them in their own code, as it is conceived that the
* functionality they provide will be necessary for most complete
* implementations.
*
* End-users of Mbed TLS who are not providing their own alternative RSA
* implementations should not use these functions directly, and should instead
* use only the functions declared in rsa.h.
*
* The interface provided by this module will be maintained through LTS (Long
* Term Support) branches of Mbed TLS, but may otherwise be subject to change,
* and must be considered an internal interface of the library.
*
* There are two classes of helper functions:
*
* (1) Parameter-generating helpers. These are:
* - mbedtls_rsa_deduce_primes
* - mbedtls_rsa_deduce_private_exponent
* - mbedtls_rsa_deduce_crt
* Each of these functions takes a set of core RSA parameters and
* generates some other, or CRT related parameters.
*
* (2) Parameter-checking helpers. These are:
* - mbedtls_rsa_validate_params
* - mbedtls_rsa_validate_crt
* They take a set of core or CRT related RSA parameters and check their
* validity.
*
*/
/*
* Copyright (C) 2006-2017, 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_RSA_INTERNAL_H
#define MBEDTLS_RSA_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/bignum.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Compute RSA prime moduli P, Q from public modulus N=PQ
* and a pair of private and public key.
*
* \note This is a 'static' helper function not operating on
* an RSA context. Alternative implementations need not
* overwrite it.
*
* \param N RSA modulus N = PQ, with P, Q to be found
* \param E RSA public exponent
* \param D RSA private exponent
* \param P Pointer to MPI holding first prime factor of N on success
* \param Q Pointer to MPI holding second prime factor of N on success
*
* \return
* - 0 if successful. In this case, P and Q constitute a
* factorization of N.
* - A non-zero error code otherwise.
*
* \note It is neither checked that P, Q are prime nor that
* D, E are modular inverses wrt. P-1 and Q-1. For that,
* use the helper function \c mbedtls_rsa_validate_params.
*
*/
int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E,
mbedtls_mpi const *D,
mbedtls_mpi *P, mbedtls_mpi *Q );
/**
* \brief Compute RSA private exponent from
* prime moduli and public key.
*
* \note This is a 'static' helper function not operating on
* an RSA context. Alternative implementations need not
* overwrite it.
*
* \param P First prime factor of RSA modulus
* \param Q Second prime factor of RSA modulus
* \param E RSA public exponent
* \param D Pointer to MPI holding the private exponent on success.
*
* \return
* - 0 if successful. In this case, D is set to a simultaneous
* modular inverse of E modulo both P-1 and Q-1.
* - A non-zero error code otherwise.
*
* \note This function does not check whether P and Q are primes.
*
*/
int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
mbedtls_mpi const *Q,
mbedtls_mpi const *E,
mbedtls_mpi *D );
/**
* \brief Generate RSA-CRT parameters
*
* \note This is a 'static' helper function not operating on
* an RSA context. Alternative implementations need not
* overwrite it.
*
* \param P First prime factor of N
* \param Q Second prime factor of N
* \param D RSA private exponent
* \param DP Output variable for D modulo P-1
* \param DQ Output variable for D modulo Q-1
* \param QP Output variable for the modular inverse of Q modulo P.
*
* \return 0 on success, non-zero error code otherwise.
*
* \note This function does not check whether P, Q are
* prime and whether D is a valid private exponent.
*
*/
int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, mbedtls_mpi *DP,
mbedtls_mpi *DQ, mbedtls_mpi *QP );
/**
* \brief Check validity of core RSA parameters
*
* \note This is a 'static' helper function not operating on
* an RSA context. Alternative implementations need not
* overwrite it.
*
* \param N RSA modulus N = PQ
* \param P First prime factor of N
* \param Q Second prime factor of N
* \param D RSA private exponent
* \param E RSA public exponent
* \param f_rng PRNG to be used for primality check, or NULL
* \param p_rng PRNG context for f_rng, or NULL
*
* \return
* - 0 if the following conditions are satisfied
* if all relevant parameters are provided:
* - P prime if f_rng != NULL (%)
* - Q prime if f_rng != NULL (%)
* - 1 < N = P * Q
* - 1 < D, E < N
* - D and E are modular inverses modulo P-1 and Q-1
* (%) This is only done if MBEDTLS_GENPRIME is defined.
* - A non-zero error code otherwise.
*
* \note The function can be used with a restricted set of arguments
* to perform specific checks only. E.g., calling it with
* (-,P,-,-,-) and a PRNG amounts to a primality check for P.
*/
int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
const mbedtls_mpi *Q, const mbedtls_mpi *D,
const mbedtls_mpi *E,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Check validity of RSA CRT parameters
*
* \note This is a 'static' helper function not operating on
* an RSA context. Alternative implementations need not
* overwrite it.
*
* \param P First prime factor of RSA modulus
* \param Q Second prime factor of RSA modulus
* \param D RSA private exponent
* \param DP MPI to check for D modulo P-1
* \param DQ MPI to check for D modulo P-1
* \param QP MPI to check for the modular inverse of Q modulo P.
*
* \return
* - 0 if the following conditions are satisfied:
* - D = DP mod P-1 if P, D, DP != NULL
* - Q = DQ mod P-1 if P, D, DQ != NULL
* - QP = Q^-1 mod P if P, Q, QP != NULL
* - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed,
* potentially including \c MBEDTLS_ERR_MPI_XXX if some
* MPI calculations failed.
* - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient
* data was provided to check DP, DQ or QP.
*
* \note The function can be used with a restricted set of arguments
* to perform specific checks only. E.g., calling it with the
* parameters (P, -, D, DP, -, -) will check DP = D mod P-1.
*/
int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, const mbedtls_mpi *DP,
const mbedtls_mpi *DQ, const mbedtls_mpi *QP );
#ifdef __cplusplus
}
#endif
#endif /* rsa_internal.h */

352
include/mbedtls/sha1.h Normal file
View File

@ -0,0 +1,352 @@
/**
* \file sha1.h
*
* \brief This file contains SHA-1 definitions and functions.
*
* The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
* <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
*
* \warning SHA-1 is considered a weak message digest and its use constitutes
* a security risk. We recommend considering stronger message
* digests instead.
*/
/*
* 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_SHA1_H
#define MBEDTLS_SHA1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */
#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */
#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073 /**< SHA-1 input data was malformed. */
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(MBEDTLS_SHA1_ALT)
// Regular implementation
//
/**
* \brief The SHA-1 context structure.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
*/
typedef struct mbedtls_sha1_context
{
uint32_t total[2]; /*!< The number of Bytes processed. */
uint32_t state[5]; /*!< The intermediate digest state. */
unsigned char buffer[64]; /*!< The data block being processed. */
}
mbedtls_sha1_context;
#else /* MBEDTLS_SHA1_ALT */
#include "sha1_alt.h"
#endif /* MBEDTLS_SHA1_ALT */
/**
* \brief This function initializes a SHA-1 context.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context to initialize.
* This must not be \c NULL.
*
*/
void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
/**
* \brief This function clears a SHA-1 context.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context to clear. This may be \c NULL,
* in which case this function does nothing. If it is
* not \c NULL, it must point to an initialized
* SHA-1 context.
*
*/
void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
/**
* \brief This function clones the state of a SHA-1 context.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param dst The SHA-1 context to clone to. This must be initialized.
* \param src The SHA-1 context to clone from. This must be initialized.
*
*/
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src );
/**
* \brief This function starts a SHA-1 checksum calculation.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context to initialize. This must be initialized.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*
*/
int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
/**
* \brief This function feeds an input buffer into an ongoing SHA-1
* checksum calculation.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context. This must be initialized
* and have a hash operation started.
* \param input The buffer holding the input data.
* This must be a readable buffer of length \p ilen Bytes.
* \param ilen The length of the input data \p input in Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief This function finishes the SHA-1 operation, and writes
* the result to the output buffer.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context to use. This must be initialized and
* have a hash operation started.
* \param output The SHA-1 checksum result. This must be a writable
* buffer of length \c 20 Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
unsigned char output[20] );
/**
* \brief SHA-1 process data block (internal use only).
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param ctx The SHA-1 context to use. This must be initialized.
* \param data The data block being processed. This must be a
* readable buffer of length \c 64 Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*
*/
int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function starts a SHA-1 checksum calculation.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0.
*
* \param ctx The SHA-1 context to initialize. This must be initialized.
*
*/
MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
/**
* \brief This function feeds an input buffer into an ongoing SHA-1
* checksum calculation.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0.
*
* \param ctx The SHA-1 context. This must be initialized and
* have a hash operation started.
* \param input The buffer holding the input data.
* This must be a readable buffer of length \p ilen Bytes.
* \param ilen The length of the input data \p input in Bytes.
*
*/
MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen );
/**
* \brief This function finishes the SHA-1 operation, and writes
* the result to the output buffer.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0.
*
* \param ctx The SHA-1 context. This must be initialized and
* have a hash operation started.
* \param output The SHA-1 checksum result.
* This must be a writable buffer of length \c 20 Bytes.
*/
MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
unsigned char output[20] );
/**
* \brief SHA-1 process data block (internal use only).
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0.
*
* \param ctx The SHA-1 context. This must be initialized.
* \param data The data block being processed.
* This must be a readable buffer of length \c 64 bytes.
*
*/
MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
const unsigned char data[64] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief This function calculates the SHA-1 checksum of a buffer.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The SHA-1 result is calculated as
* output = SHA-1(input buffer).
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \param input The buffer holding the input data.
* This must be a readable buffer of length \p ilen Bytes.
* \param ilen The length of the input data \p input in Bytes.
* \param output The SHA-1 checksum result.
* This must be a writable buffer of length \c 20 Bytes.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*
*/
int mbedtls_sha1_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] );
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief This function calculates the SHA-1 checksum of a buffer.
*
* The function allocates the context, performs the
* calculation, and frees the context.
*
* The SHA-1 result is calculated as
* output = SHA-1(input buffer).
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \deprecated Superseded by mbedtls_sha1_ret() in 2.7.0
*
* \param input The buffer holding the input data.
* This must be a readable buffer of length \p ilen Bytes.
* \param ilen The length of the input data \p input in Bytes.
* \param output The SHA-1 checksum result. This must be a writable
* buffer of size \c 20 Bytes.
*
*/
MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
size_t ilen,
unsigned char output[20] );
#undef MBEDTLS_DEPRECATED
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The SHA-1 checkup routine.
*
* \warning SHA-1 is considered a weak message digest and its use
* constitutes a security risk. We recommend considering
* stronger message digests instead.
*
* \return \c 0 on success.
* \return \c 1 on failure.
*
*/
int mbedtls_sha1_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_sha1.h */

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