Merge remote-tracking branch 'crypto/development' into development-restricted
* crypto/development: (863 commits) crypto_platform: Fix typo des: Reduce number of self-test iterations Fix -O0 build for Aarch64 bignum multiplication. Make GNUC-compatible compilers use the right mbedtls_t_udbl again on Aarch64 builds. Add optimized bignum multiplication for Aarch64. Enable 64-bit limbs for all Aarch64 builds. HMAC DRBG: Split entropy-gathering requests to reduce request sizes psa: Use application key ID where necessary psa: Adapt set_key_id() for when owner is included psa: Add PSA_KEY_ID_INIT psa: Don't duplicate policy initializer crypto_extra: Use const seed for entropy injection getting_started: Update for PSA Crypto API 1.0b3 Editorial fixes. Cross reference 'key handles' from INVALID_HANDLE Update documentation for psa_destroy_key Update documentation for psa_close_key Update psa_open_key documentation Remove duplicated information in psa_open_key Initialize key bits to max size + 1 in psa_import_key ...
This commit is contained in:
commit
c04305f036
11
.gitignore
vendored
11
.gitignore
vendored
@ -31,6 +31,17 @@ massif-*
|
||||
# Python build artifacts:
|
||||
*.pyc
|
||||
|
||||
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
|
||||
*.dir/
|
||||
|
||||
# Visual Studio artifacts
|
||||
/visualc/VS2010/.localhistory/
|
||||
/visualc/VS2010/.vs/
|
||||
/visualc/VS2010/Debug/
|
||||
/visualc/VS2010/Release/
|
||||
/visualc/VS2010/*.vcxproj.filters
|
||||
/visualc/VS2010/*.vcxproj.user
|
||||
|
||||
# Generated documentation:
|
||||
/apidoc
|
||||
|
||||
|
1
3rdparty/.gitignore
vendored
Normal file
1
3rdparty/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/Makefile
|
11
3rdparty/CMakeLists.txt
vendored
Normal file
11
3rdparty/CMakeLists.txt
vendored
Normal 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
5
3rdparty/Makefile.inc
vendored
Normal 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
2
3rdparty/everest/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
Makefile
|
31
3rdparty/everest/CMakeLists.txt
vendored
Normal file
31
3rdparty/everest/CMakeLists.txt
vendored
Normal 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 ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/config.pl -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
6
3rdparty/everest/Makefile.inc
vendored
Normal 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
5
3rdparty/everest/README.md
vendored
Normal 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).
|
21
3rdparty/everest/include/everest/Hacl_Curve25519.h
vendored
Normal file
21
3rdparty/everest/include/everest/Hacl_Curve25519.h
vendored
Normal 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
|
234
3rdparty/everest/include/everest/everest.h
vendored
Normal file
234
3rdparty/everest/include/everest/everest.h
vendored
Normal 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 */
|
29
3rdparty/everest/include/everest/kremlib.h
vendored
Normal file
29
3rdparty/everest/include/everest/kremlib.h
vendored
Normal 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 */
|
124
3rdparty/everest/include/everest/kremlib/FStar_UInt128.h
vendored
Normal file
124
3rdparty/everest/include/everest/kremlib/FStar_UInt128.h
vendored
Normal 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
|
280
3rdparty/everest/include/everest/kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h
vendored
Normal file
280
3rdparty/everest/include/everest/kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.h
vendored
Normal 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
|
204
3rdparty/everest/include/everest/kremlin/c_endianness.h
vendored
Normal file
204
3rdparty/everest/include/everest/kremlin/c_endianness.h
vendored
Normal 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
|
16
3rdparty/everest/include/everest/kremlin/internal/builtin.h
vendored
Normal file
16
3rdparty/everest/include/everest/kremlin/internal/builtin.h
vendored
Normal 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
|
46
3rdparty/everest/include/everest/kremlin/internal/callconv.h
vendored
Normal file
46
3rdparty/everest/include/everest/kremlin/internal/callconv.h
vendored
Normal 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
|
34
3rdparty/everest/include/everest/kremlin/internal/compat.h
vendored
Normal file
34
3rdparty/everest/include/everest/kremlin/internal/compat.h
vendored
Normal 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
|
57
3rdparty/everest/include/everest/kremlin/internal/debug.h
vendored
Normal file
57
3rdparty/everest/include/everest/kremlin/internal/debug.h
vendored
Normal 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
|
102
3rdparty/everest/include/everest/kremlin/internal/target.h
vendored
Normal file
102
3rdparty/everest/include/everest/kremlin/internal/target.h
vendored
Normal 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
|
61
3rdparty/everest/include/everest/kremlin/internal/types.h
vendored
Normal file
61
3rdparty/everest/include/everest/kremlin/internal/types.h
vendored
Normal 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
|
5
3rdparty/everest/include/everest/kremlin/internal/wasmsupport.h
vendored
Normal file
5
3rdparty/everest/include/everest/kremlin/internal/wasmsupport.h
vendored
Normal 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)
|
21
3rdparty/everest/include/everest/vs2010/Hacl_Curve25519.h
vendored
Normal file
21
3rdparty/everest/include/everest/vs2010/Hacl_Curve25519.h
vendored
Normal 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
|
36
3rdparty/everest/include/everest/vs2010/inttypes.h
vendored
Normal file
36
3rdparty/everest/include/everest/vs2010/inttypes.h
vendored
Normal 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
|
31
3rdparty/everest/include/everest/vs2010/stdbool.h
vendored
Normal file
31
3rdparty/everest/include/everest/vs2010/stdbool.h
vendored
Normal 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
|
190
3rdparty/everest/include/everest/x25519.h
vendored
Normal file
190
3rdparty/everest/include/everest/x25519.h
vendored
Normal 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 */
|
760
3rdparty/everest/library/Hacl_Curve25519.c
vendored
Normal file
760
3rdparty/everest/library/Hacl_Curve25519.c
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
3rdparty/everest/library/Hacl_Curve25519_joined.c
vendored
Normal file
45
3rdparty/everest/library/Hacl_Curve25519_joined.c
vendored
Normal 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
111
3rdparty/everest/library/everest.c
vendored
Normal 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 */
|
||||
|
413
3rdparty/everest/library/kremlib/FStar_UInt128_extracted.c
vendored
Normal file
413
3rdparty/everest/library/kremlib/FStar_UInt128_extracted.c
vendored
Normal 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);
|
||||
}
|
||||
|
100
3rdparty/everest/library/kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.c
vendored
Normal file
100
3rdparty/everest/library/kremlib/FStar_UInt64_FStar_UInt32_FStar_UInt16_FStar_UInt8.c
vendored
Normal 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;
|
||||
}
|
||||
|
805
3rdparty/everest/library/legacy/Hacl_Curve25519.c
vendored
Normal file
805
3rdparty/everest/library/legacy/Hacl_Curve25519.c
vendored
Normal 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
190
3rdparty/everest/library/x25519.c
vendored
Normal 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 */
|
@ -124,7 +124,10 @@ if(CMAKE_COMPILER_IS_GNU)
|
||||
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings")
|
||||
if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wvla")
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
|
||||
endif()
|
||||
@ -141,7 +144,7 @@ if(CMAKE_COMPILER_IS_GNU)
|
||||
endif(CMAKE_COMPILER_IS_GNU)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
|
||||
@ -176,9 +179,15 @@ endif()
|
||||
include_directories(include/)
|
||||
include_directories(library/)
|
||||
|
||||
add_subdirectory(library)
|
||||
add_subdirectory(include)
|
||||
|
||||
add_subdirectory(3rdparty)
|
||||
include_directories(${thirdparty_inc})
|
||||
list(APPEND libs ${thirdparty_lib})
|
||||
add_definitions(${thirdparty_def})
|
||||
|
||||
add_subdirectory(library)
|
||||
|
||||
if(ENABLE_PROGRAMS)
|
||||
add_subdirectory(programs)
|
||||
endif()
|
||||
@ -219,13 +228,13 @@ if(ENABLE_TESTING)
|
||||
COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
|
||||
)
|
||||
endif(UNIX)
|
||||
endif()
|
||||
|
||||
# Make scripts needed for testing available in an out-of-source build.
|
||||
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_to_source(scripts)
|
||||
# Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
|
||||
# keep things simple with the sed commands in the memcheck target.
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
|
||||
# Make scripts needed for testing available in an out-of-source build.
|
||||
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_to_source(scripts)
|
||||
# Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
|
||||
# keep things simple with the sed commands in the memcheck target.
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -161,21 +161,21 @@ The library integration and the PSA platform integration use different sets of f
|
||||
|
||||
It would simplify things to always have a 32-bit owner, with a nonzero value, and thus reserve the range 0–0xffffffff for internal library use.
|
||||
|
||||
Mbed Crypto 1.0.1
|
||||
Mbed Crypto 1.1.0
|
||||
-----------------
|
||||
|
||||
Tags: TBD
|
||||
Tags: mbedcrypto-1.1.0
|
||||
|
||||
Released in May 2019. <br>
|
||||
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.0.1
|
||||
### 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.0.1] below.
|
||||
* 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.
|
||||
@ -189,7 +189,96 @@ The layout of a key file is:
|
||||
* 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.0.1]
|
||||
* 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.
|
||||
|
@ -63,35 +63,50 @@ To use the Mbed Crypto APIs, call `psa_crypto_init()` before calling any other A
|
||||
|
||||
### Importing a key
|
||||
|
||||
To use a key for cryptography operations in Mbed Crypto, you need to first import it into a key slot. Each slot can store only one key at a time. The slot where the key is stored must be unoccupied, and valid for a key of the chosen type.
|
||||
To use a key for cryptography operations in Mbed Crypto, you need to first
|
||||
import it. Upon importing, you'll be given a handle to refer to the key for use
|
||||
with other function calls.
|
||||
|
||||
Prerequisites to importing keys:
|
||||
Prerequisites for importing keys:
|
||||
* Initialize the library with a successful call to `psa_crypto_init`.
|
||||
|
||||
Importing a key and checking key information:
|
||||
1. Import a key pair into key slot `1`.
|
||||
1. Test the information stored in this slot:
|
||||
Importing a key:
|
||||
```C
|
||||
int key_slot = 1;
|
||||
uint8_t *data = "KEYPAIR_KEY_DATA";
|
||||
size_t data_size;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
|
||||
size_t got_bits;
|
||||
psa_key_type_t got_type;
|
||||
size_t expected_bits = data_size;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA;
|
||||
size_t export_size = data_size;
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t data[] = AES_KEY;
|
||||
psa_key_handle_t handle;
|
||||
|
||||
psa_crypto_init();
|
||||
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(key_slot, type, data, data_size);
|
||||
status = psa_import_key(&attributes, data, sizeof(data), &handle);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Failed to import key\n");
|
||||
return;
|
||||
}
|
||||
printf("Imported a key\n");
|
||||
|
||||
/* Test the key information */
|
||||
status = psa_get_key_information(slot, &got_type, &got_bits);
|
||||
/* Free the attributes */
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(key_slot);
|
||||
psa_destroy_key(handle);
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
@ -99,48 +114,70 @@ Importing a key and checking key information:
|
||||
|
||||
Mbed Crypto provides support for encrypting, decrypting, signing and verifying messages using public key signature algorithms (such as RSA or ECDSA).
|
||||
|
||||
Prerequisites to working with the asymmetric cipher API:
|
||||
Prerequisites for performing asymmetric signature operations:
|
||||
* Initialize the library with a successful call to `psa_crypto_init`.
|
||||
* Configure the key policy accordingly:
|
||||
* `PSA_KEY_USAGE_SIGN` to allow signing.
|
||||
* `PSA_KEY_USAGE_VERIFY` to allow signature verification.
|
||||
* Have a valid key in the key slot.
|
||||
* Have a valid key with appropriate attributes set:
|
||||
* Usage flag `PSA_KEY_USAGE_SIGN` to allow signing.
|
||||
* Usage flag `PSA_KEY_USAGE_VERIFY` to allow signature verification.
|
||||
* Algorithm set to desired signature algorithm.
|
||||
|
||||
To sign a given message `payload` using RSA:
|
||||
1. Set the key policy of the chosen key slot by calling `psa_key_policy_set_usage()` with the `PSA_KEY_USAGE_SIGN` parameter and the algorithm `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`.
|
||||
This allows the key in the key slot to be used for RSA signing.
|
||||
1. Import the key into the key slot by calling `psa_import_key()`. You can use an already imported key instead of importing a new one.
|
||||
1. Call `psa_asymmetric_sign()` and get the output buffer that contains the signature:
|
||||
To sign a given `hash` using RSA:
|
||||
1. Call `psa_asymmetric_sign()` and get the output buffer that contains the
|
||||
signature:
|
||||
```C
|
||||
psa_status_t status;
|
||||
int key_slot = 1;
|
||||
unsigned char key[] = "RSA_KEY";
|
||||
unsigned char payload[] = "ASYMMETRIC_INPUT_FOR_SIGN";
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t key[] = RSA_KEY;
|
||||
uint8_t hash[] = "INPUT_FOR_SIGN";
|
||||
uint8_t signature[PSA_ASYMMETRIC_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);
|
||||
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 */
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN,
|
||||
PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
|
||||
status = psa_set_key_policy(key_slot, &policy);
|
||||
status = psa_import_key(&attributes, key, sizeof(key), &handle);
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Failed to import key\n");
|
||||
return;
|
||||
}
|
||||
|
||||
status = psa_import_key(key_slot, PSA_KEY_TYPE_RSA_KEYPAIR,
|
||||
key, sizeof(key));
|
||||
|
||||
/* Sing message using the key */
|
||||
status = psa_asymmetric_sign(key_slot, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
|
||||
payload, sizeof(payload),
|
||||
/* Sign message using the key */
|
||||
status = psa_asymmetric_sign(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(key_slot);
|
||||
psa_destroy_key(handle);
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
### Encrypting or decrypting using symmetric ciphers
|
||||
### Using symmetric ciphers
|
||||
|
||||
Mbed Crypto provides support for encrypting and decrypting messages using various symmetric cipher algorithms (both block and stream ciphers).
|
||||
|
||||
@ -156,32 +193,78 @@ Encrypting a message with a symmetric cipher:
|
||||
1. Call `psa_cipher_update` one or more times, passing either the whole or only a fragment of the message each time.
|
||||
1. Call `psa_cipher_finish` to end the operation and output the encrypted message.
|
||||
|
||||
Encrypting random data using an AES key in cipher block chain (CBC) mode with no padding (assuming all prerequisites have been fulfilled):
|
||||
Encrypting data using an AES key in cipher block chain (CBC) mode with no padding (assuming all prerequisites have been fulfilled):
|
||||
```c
|
||||
psa_key_slot_t key_slot = 1;
|
||||
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;
|
||||
size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
|
||||
unsigned char input[block_size];
|
||||
unsigned char iv[block_size];
|
||||
uint8_t plaintext[block_size] = SOME_PLAINTEXT;
|
||||
uint8_t iv[block_size];
|
||||
size_t iv_len;
|
||||
unsigned char output[block_size];
|
||||
uint8_t key[] = AES_KEY;
|
||||
uint8_t output[block_size];
|
||||
size_t output_len;
|
||||
psa_key_handle_t handle;
|
||||
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||
|
||||
/* generate some random data to be encrypted */
|
||||
psa_generate_random(input, sizeof(input));
|
||||
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, sizeof(key), &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");
|
||||
|
||||
/* encrypt the key */
|
||||
psa_cipher_encrypt_setup(&operation, key_slot, alg);
|
||||
psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_len);
|
||||
psa_cipher_update(&operation, input, sizeof(input),
|
||||
output, sizeof(output),
|
||||
&output_len);
|
||||
psa_cipher_finish(&operation,
|
||||
output + output_len, sizeof(output) - output_len,
|
||||
&output_len);
|
||||
/* Clean up cipher operation context */
|
||||
psa_cipher_abort(&operation);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(handle);
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
Decrypting a message with a symmetric cipher:
|
||||
@ -194,31 +277,75 @@ Decrypting a message with a symmetric cipher:
|
||||
Decrypting encrypted data using an AES key in CBC mode with no padding
|
||||
(assuming all prerequisites have been fulfilled):
|
||||
```c
|
||||
psa_key_slot_t key_slot = 1;
|
||||
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;
|
||||
size_t block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES);
|
||||
unsigned char input[block_size];
|
||||
unsigned char iv[block_size];
|
||||
size_t iv_len;
|
||||
unsigned char output[block_size];
|
||||
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 key[] = AES_KEY;
|
||||
uint8_t output[block_size];
|
||||
size_t output_len;
|
||||
psa_key_handle_t handle;
|
||||
|
||||
/* setup input data */
|
||||
fetch_iv(iv, sizeof(iv)); /* fetch the IV used when the data was encrypted */
|
||||
fetch_input(input, sizeof(input)); /* fetch the data to be decrypted */
|
||||
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, sizeof(key), &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");
|
||||
|
||||
/* encrypt the encrypted data */
|
||||
psa_cipher_decrypt_setup(&operation, key_slot, alg);
|
||||
psa_cipher_set_iv(&operation, iv, sizeof(iv));
|
||||
psa_cipher_update(&operation, input, sizeof(input),
|
||||
output, sizeof(output),
|
||||
&output_len);
|
||||
psa_cipher_finish(&operation,
|
||||
output + output_len, sizeof(output) - output_len,
|
||||
&output_len);
|
||||
/* Clean up cipher operation context */
|
||||
psa_cipher_abort(&operation);
|
||||
|
||||
/* Destroy the key */
|
||||
psa_destroy_key(handle);
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
#### Handling cipher operation contexts
|
||||
@ -237,9 +364,8 @@ Multiple sequential calls to `psa_cipher_abort` on an operation that has already
|
||||
|
||||
### Hashing a message
|
||||
|
||||
Mbed Crypto lets you compute and verify hashes using various hashing algorithms.
|
||||
|
||||
The current implementation supports the following hash algorithms: `MD2`, `MD4`, `MD5`, `RIPEMD160`, `SHA-1`, `SHA-224`, `SHA-256`, `SHA-384`, and `SHA-512`.
|
||||
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`.
|
||||
@ -252,25 +378,54 @@ To calculate a hash:
|
||||
|
||||
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_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 */
|
||||
psa_hash_setup(&operation, alg);
|
||||
psa_hash_update(&operation, input, sizeof(input));
|
||||
psa_hash_finish(&operation, actual_hash, sizeof(actual_hash), &actual_hash_len);
|
||||
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();
|
||||
```
|
||||
|
||||
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_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,
|
||||
@ -279,10 +434,39 @@ Verify the `SHA-256` hash of a message:
|
||||
};
|
||||
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 */
|
||||
psa_hash_setup(&operation, alg);
|
||||
psa_hash_update(&operation, input, sizeof(input));
|
||||
psa_hash_verify(&operation, expected_hash, expected_hash_len);
|
||||
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.
|
||||
@ -304,86 +488,172 @@ Multiple sequential calls to `psa_hash_abort` on an operation that has already b
|
||||
|
||||
### Generating a random value
|
||||
|
||||
Mbed Crypto can generate random data.
|
||||
Mbed Crypto can generate random data. To generate a random key, use
|
||||
`psa_generate_key()` instead of `psa_generate_random()`
|
||||
|
||||
Prerequisites to random generation:
|
||||
* Initialize the library with a successful call to `psa_crypto_init`.
|
||||
* Initialize the library with a successful call to `psa_crypto_init()`.
|
||||
|
||||
Generate a random, ten-byte piece of data:
|
||||
1. Generate random bytes by calling `psa_generate_random()`:
|
||||
```C
|
||||
psa_status_t status;
|
||||
uint8_t random[10] = { 0 };
|
||||
psa_crypto_init();
|
||||
status = psa_generate_random(random, sizeof(random));
|
||||
|
||||
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. Key derivation is based upon the generator abstraction. A generator must first be initialized and set up (provided with a key and optionally other data) and then derived data can be read from it either to a buffer or directly imported into a key slot.
|
||||
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. A key derivation context must first be initialized and set up,
|
||||
provided with a key and optionally other data, and then derived data can be
|
||||
read from it either to a buffer or directly sent to a key slot. Refer to the
|
||||
documentation for the particular algorithm (such as HKDF or the TLS1.2 PRF) for
|
||||
information on 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`.
|
||||
* Configure the key policy for the key used for derivation (`PSA_KEY_USAGE_DERIVE`)
|
||||
* The key type must be `PSA_KEY_TYPE_DERIVE`.
|
||||
* 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
|
||||
(`PSA_ALG_HKDF(PSA_ALG_SHA_256)`).
|
||||
|
||||
Deriving a new AES-CTR 128-bit encryption key into a given key slot using HKDF with a given key, salt and label:
|
||||
1. Set the key policy for key derivation by calling `psa_key_policy_set_usage()` with `PSA_KEY_USAGE_DERIVE` parameter, and the algorithm `PSA_ALG_HKDF(PSA_ALG_SHA_256)`.
|
||||
1. Import the key into the key slot by calling `psa_import_key()`. You can skip this step and the previous one if the key has already been imported into a known key slot.
|
||||
1. Set up the generator using the `psa_key_derivation` function providing a key slot containing a key that can be used for key derivation and a salt and label (Note: salt and label are optional).
|
||||
1. Initiate a key policy to for the derived key by calling `psa_key_policy_set_usage()` with `PSA_KEY_USAGE_ENCRYPT` parameter and the algorithm `PSA_ALG_CTR`.
|
||||
1. Set the key policy to the derived key slot.
|
||||
1. Import a key from generator into the desired key slot using (`psa_generator_import_key`).
|
||||
1. Clean up generator.
|
||||
Deriving 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 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
|
||||
`PSA_KEY_USAGE_ENCRYPT` parameter and the algorithm `PSA_ALG_CTR` 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 label provided:
|
||||
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_key_slot_t base_key = 1;
|
||||
psa_key_slot_t derived_key = 2;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
|
||||
unsigned char key[] = {
|
||||
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 };
|
||||
|
||||
unsigned char salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
|
||||
|
||||
unsigned char label[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||
0xf7, 0xf8, 0xf9 };
|
||||
|
||||
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_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
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 imported you can skip this part */
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DERIVE, alg);
|
||||
status = psa_set_key_policy(base_key, &policy);
|
||||
/* 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);
|
||||
|
||||
status = psa_import_key(base_key, PSA_KEY_TYPE_DERIVE, key, sizeof(key));
|
||||
/* 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);
|
||||
|
||||
/* Derive a key into a key slot*/
|
||||
status = psa_key_derivation(&generator, base_key, alg, salt, sizeof(salt),
|
||||
label, sizeof(label), capacity);
|
||||
printf("Derived key\n");
|
||||
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CTR);
|
||||
/* Clean up key derivation operation */
|
||||
psa_key_derivation_abort(&operation);
|
||||
|
||||
psa_set_key_policy(derived_key, &policy);
|
||||
/* Destroy the keys */
|
||||
psa_destroy_key(derived_key);
|
||||
psa_destroy_key(base_key);
|
||||
|
||||
psa_generator_import_key(derived_key, PSA_KEY_TYPE_AES, derived_bits, &generator);
|
||||
|
||||
/* Clean up generator and key */
|
||||
psa_generator_abort(&generator);
|
||||
/* as part of clean up you may want to clean up the keys used by calling:
|
||||
* psa_destroy_key( base_key ); or psa_destroy_key( derived_key ); */
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
@ -393,95 +663,152 @@ Mbed Crypto provides a simple way for authenticate and encrypt with associated d
|
||||
|
||||
Prerequisites to working with the AEAD ciphers APIs:
|
||||
* Initialize the library with a successful call to `psa_crypto_init`.
|
||||
* The key policy for the key used for derivation must be configured accordingly (`PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT`).
|
||||
* The key attributes for the key used for derivation must have usage flags
|
||||
`PSA_KEY_USAGE_ENCRYPT` or `PSA_KEY_USAGE_DECRYPT`.
|
||||
|
||||
To authenticate and encrypt a message:
|
||||
```C
|
||||
int slot = 1;
|
||||
psa_status_t status;
|
||||
unsigned char key[] = { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
|
||||
|
||||
unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B };
|
||||
|
||||
unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
|
||||
0xC3, 0x3C, 0x49, 0xFD, 0x70 };
|
||||
|
||||
unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
|
||||
0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
|
||||
0xD2, 0xD7, 0xC2 };
|
||||
unsigned char *output_data = NULL;
|
||||
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_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
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 = malloc(output_size);
|
||||
status = psa_crypto_init();
|
||||
output_data = (uint8_t *)malloc(output_size);
|
||||
if (!output_data) {
|
||||
printf("Out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CCM);
|
||||
status = psa_set_key_policy(slot, &policy);
|
||||
/* 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);
|
||||
|
||||
status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
|
||||
|
||||
status = psa_aead_encrypt(slot, PSA_ALG_CCM,
|
||||
/* 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);
|
||||
|
||||
psa_destroy_key(slot);
|
||||
mbedtls_free(output_data);
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
To authenticate and decrypt a message:
|
||||
|
||||
```C
|
||||
int slot = 1;
|
||||
psa_status_t status;
|
||||
unsigned char key[] = {
|
||||
static const uint8_t key[] = {
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF
|
||||
};
|
||||
|
||||
unsigned char nonce[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3,
|
||||
0x3C, 0x49, 0xFD, 0x70
|
||||
};
|
||||
|
||||
unsigned char additional_data[] = { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20,
|
||||
0xC3, 0x3C, 0x49, 0xFD, 0x70
|
||||
};
|
||||
unsigned char input_data[] = { 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41,
|
||||
0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43,
|
||||
0xD2, 0xD7, 0xC2
|
||||
};
|
||||
unsigned char *output_data = NULL;
|
||||
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_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
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 = malloc(output_size);
|
||||
status = psa_crypto_init();
|
||||
output_data = (uint8_t *)malloc(output_size);
|
||||
if (!output_data) {
|
||||
printf("Out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DECRYPT, PSA_ALG_CCM);
|
||||
status = psa_set_key_policy(slot, &policy);
|
||||
/* 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);
|
||||
|
||||
status = psa_import_key(slot, PSA_KEY_TYPE_AES, key, sizeof(key));
|
||||
|
||||
status = psa_aead_decrypt(slot, PSA_ALG_CCM,
|
||||
/* 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);
|
||||
|
||||
psa_destroy_key(slot);
|
||||
mbedtls_free(output_data);
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
@ -492,29 +819,61 @@ 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`.
|
||||
|
||||
Generate a piece of random 128-bit AES data:
|
||||
1. Set the key policy for key generation by calling `psa_key_policy_set_usage()` with the `PSA_KEY_USAGE_EXPORT` parameter and the algorithm `PSA_ALG_GCM`.
|
||||
1. Generate a random AES key by calling `psa_generate_key()`.
|
||||
1. Export the generated key by calling `psa_export_key()`:
|
||||
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)`). We don't set
|
||||
`PSA_KEY_USAGE_EXPORT` as we only want to export the public key, not the key
|
||||
pair (or private key).
|
||||
1. Generate a key by calling `psa_generate_key()`.
|
||||
1. Export the generated public key by calling `psa_export_public_key()`
|
||||
:
|
||||
```C
|
||||
int slot = 1;
|
||||
size_t bits = 128;
|
||||
size_t exported_size = bits;
|
||||
enum {
|
||||
key_bits = 256,
|
||||
};
|
||||
psa_status_t status;
|
||||
size_t exported_length = 0;
|
||||
uint8_t *exported = malloc(exported_size);
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
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;
|
||||
|
||||
psa_crypto_init();
|
||||
printf("Generate a key pair...\t");
|
||||
fflush(stdout);
|
||||
|
||||
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_GCM);
|
||||
psa_set_key_policy(slot, &policy);
|
||||
/* Initialize PSA Crypto */
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Failed to initialize PSA Crypto\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Generate a key */
|
||||
psa_generate_key(slot, PSA_KEY_TYPE_AES, bits, NULL, 0);
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN);
|
||||
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_SECP256R1));
|
||||
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);
|
||||
|
||||
psa_export_key(slot, exported, exported_size, &exported_length)
|
||||
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);
|
||||
|
||||
psa_destroy_key(slot);
|
||||
mbedtls_psa_crypto_free();
|
||||
```
|
||||
|
||||
|
@ -16,7 +16,7 @@ if(INSTALL_MBEDTLS_HEADERS)
|
||||
endif(INSTALL_MBEDTLS_HEADERS)
|
||||
|
||||
# Make config.h available in an out-of-source build.
|
||||
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if (ENABLE_TESTING AND NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_to_source(mbedtls)
|
||||
link_to_source(psa)
|
||||
endif()
|
||||
|
@ -129,7 +129,8 @@
|
||||
defined(__ppc64__) || defined(__powerpc64__) || \
|
||||
defined(__ia64__) || defined(__alpha__) || \
|
||||
( defined(__sparc__) && defined(__arch64__) ) || \
|
||||
defined(__s390x__) || defined(__mips64) )
|
||||
defined(__s390x__) || defined(__mips64) || \
|
||||
defined(__aarch64__) )
|
||||
#if !defined(MBEDTLS_HAVE_INT64)
|
||||
#define MBEDTLS_HAVE_INT64
|
||||
#endif /* MBEDTLS_HAVE_INT64 */
|
||||
|
@ -198,6 +198,30 @@
|
||||
|
||||
#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 \
|
||||
@ -642,7 +666,8 @@
|
||||
"r6", "r7", "r8", "r9", "cc" \
|
||||
);
|
||||
|
||||
#elif defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
|
||||
#elif (__ARM_ARCH >= 6) && \
|
||||
defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm(
|
||||
|
@ -125,6 +125,11 @@
|
||||
#error "MBEDTLS_ECP_RESTARTABLE defined, but not MBEDTLS_ECDH_LEGACY_CONTEXT"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) && \
|
||||
defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
#error "MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED defined, but MBEDTLS_ECDH_LEGACY_CONTEXT not disabled"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
|
||||
#endif
|
||||
@ -458,6 +463,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"
|
||||
|
@ -124,14 +124,13 @@ 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 */
|
||||
/* into a allocated key slot, and which */
|
||||
/* hence need to destroy that key slot */
|
||||
/* when they are no longer needed. */
|
||||
/* 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 from a key slot */
|
||||
/* provided by the user, and which */
|
||||
/* hence should not be destroyed when */
|
||||
/* the context is no longer needed. */
|
||||
/* 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
|
||||
|
@ -277,28 +277,52 @@
|
||||
* For example, when a function accepts as input a pointer to a buffer that may
|
||||
* contain untrusted data, and its documentation mentions that this pointer
|
||||
* must not be NULL:
|
||||
* - the pointer is checked to be non-NULL only if this option is enabled
|
||||
* - the content of the buffer is always validated
|
||||
* - The pointer is checked to be non-NULL only if this option is enabled.
|
||||
* - The content of the buffer is always validated.
|
||||
*
|
||||
* When this flag is defined, if a library function receives a parameter that
|
||||
* is invalid, it will:
|
||||
* - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
|
||||
* call to the function mbedtls_param_failed()
|
||||
* - immediately return (with a specific error code unless the function
|
||||
* returns void and can't communicate an error).
|
||||
* is invalid:
|
||||
* 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
|
||||
* 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
|
||||
* will immediately return. If the function returns an Mbed TLS error code,
|
||||
* the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
|
||||
*
|
||||
* When defining this flag, you also need to:
|
||||
* - either provide a definition of the function mbedtls_param_failed() in
|
||||
* your application (see platform_util.h for its prototype) as the library
|
||||
* calls that function, but does not provide a default definition for it,
|
||||
* - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
|
||||
* below if the above mechanism is not flexible enough to suit your needs.
|
||||
* See the documentation of this macro later in this file.
|
||||
* When defining this flag, you also need to arrange a definition for
|
||||
* MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
|
||||
* - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
|
||||
* function mbedtls_param_failed(), but the library does not define this
|
||||
* function. If you do not make any other arrangements, you must provide
|
||||
* the function mbedtls_param_failed() in your application.
|
||||
* See `platform_util.h` for its prototype.
|
||||
* - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
|
||||
* library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
|
||||
* You can still supply an alternative definition of
|
||||
* MBEDTLS_PARAM_FAILED(), which may call `assert`.
|
||||
* - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
|
||||
* or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
|
||||
* the library will call the macro that you defined and will not supply
|
||||
* its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
|
||||
* you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
|
||||
* files include `<assert.h>`.
|
||||
*
|
||||
* Uncomment to enable validation of application-controlled parameters.
|
||||
*/
|
||||
//#define MBEDTLS_CHECK_PARAMS
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CHECK_PARAMS_ASSERT
|
||||
*
|
||||
* Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
|
||||
* `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
|
||||
*
|
||||
* If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
|
||||
* calling a function mbedtls_param_failed(). See the documentation of
|
||||
* #MBEDTLS_CHECK_PARAMS for details.
|
||||
*
|
||||
* Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
|
||||
*/
|
||||
//#define MBEDTLS_CHECK_PARAMS_ASSERT
|
||||
|
||||
/* \} name SECTION: System support */
|
||||
|
||||
/**
|
||||
@ -982,6 +1006,16 @@
|
||||
*/
|
||||
//#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_THREADING_ALT
|
||||
*
|
||||
@ -1007,18 +1041,27 @@
|
||||
/**
|
||||
* \def MBEDTLS_USE_PSA_CRYPTO
|
||||
*
|
||||
* Make the X.509 and TLS library use PSA for cryptographic operations, see
|
||||
* #MBEDTLS_PSA_CRYPTO_C.
|
||||
* Make the X.509 and TLS library use PSA for cryptographic operations, and
|
||||
* enable new APIs for using keys handled by PSA Crypto.
|
||||
*
|
||||
* Note: this option is still in progress, the full X.509 and TLS modules are
|
||||
* not covered yet, but parts that are not ported to PSA yet will still work
|
||||
* as usual, so enabling this option should not break backwards compatibility.
|
||||
* \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 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 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
|
||||
* rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
|
||||
* now, access to these APIs is opt-in (via enabling the present option), in
|
||||
* order to clearly differentiate them from the stable Mbed TLS APIs.
|
||||
*
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C.
|
||||
*
|
||||
* Uncomment this to enable internal use of PSA Crypto and new associated APIs.
|
||||
*/
|
||||
//#define MBEDTLS_USE_PSA_CRYPTO
|
||||
|
||||
@ -1702,6 +1745,10 @@
|
||||
*
|
||||
* Enable the Platform Security Architecture cryptography API.
|
||||
*
|
||||
* \warning The PSA Crypto API is still beta status. 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.
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
*
|
||||
* Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
|
||||
@ -1709,6 +1756,22 @@
|
||||
*/
|
||||
#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
|
||||
*
|
||||
@ -1950,6 +2013,42 @@
|
||||
//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
|
||||
|
||||
/**
|
||||
* \brief This macro is invoked by the library when an invalid parameter
|
||||
* is detected that is only checked with #MBEDTLS_CHECK_PARAMS
|
||||
* (see the documentation of that option for context).
|
||||
*
|
||||
* When you leave this undefined here, the library provides
|
||||
* a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
|
||||
* is defined, the default definition is `assert(cond)`,
|
||||
* otherwise the default definition calls a function
|
||||
* mbedtls_param_failed(). This function is declared in
|
||||
* `platform_util.h` for the benefit of the library, but
|
||||
* you need to define in your application.
|
||||
*
|
||||
* When you define this here, this replaces the default
|
||||
* definition in platform_util.h (which no longer declares the
|
||||
* function mbedtls_param_failed()) and it is your responsibility
|
||||
* to make sure this macro expands to something suitable (in
|
||||
* particular, that all the necessary declarations are visible
|
||||
* from within the library - you can ensure that by providing
|
||||
* them in this file next to the macro definition).
|
||||
* If you define this macro to call `assert`, also define
|
||||
* #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
|
||||
* include `<assert.h>`.
|
||||
*
|
||||
* Note that you may define this macro to expand to nothing, in
|
||||
* which case you don't have to worry about declarations or
|
||||
* definitions. However, you will then be notified about invalid
|
||||
* parameters only in non-void functions, and void function will
|
||||
* just silently return early on invalid parameters, which
|
||||
* partially negates the benefits of enabling
|
||||
* #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
|
||||
*
|
||||
* \param cond The expression that should evaluate to true, but doesn't.
|
||||
*/
|
||||
//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
|
||||
|
||||
/**
|
||||
* Uncomment the macro to let mbed TLS use your alternate implementation of
|
||||
* mbedtls_platform_zeroize(). This replaces the default implementation in
|
||||
@ -1989,6 +2088,15 @@
|
||||
*/
|
||||
//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
|
||||
|
||||
/**
|
||||
* Enable the verified implementations of ECDH primitives from Project Everest
|
||||
* (currently only Curve25519). This feature changes the layout of ECDH
|
||||
* contexts and therefore is a compatibility break for applications that access
|
||||
* fields of a mbedtls_ecdh_context structure directly. See also
|
||||
* MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h.
|
||||
*/
|
||||
//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
|
||||
|
||||
/* \} name SECTION: Customisation configuration options */
|
||||
|
||||
/* Target and application specific configurations
|
||||
|
@ -42,6 +42,11 @@
|
||||
|
||||
#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
|
||||
@ -66,6 +71,9 @@ 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;
|
||||
|
||||
/**
|
||||
@ -119,6 +127,9 @@ typedef struct mbedtls_ecdh_context
|
||||
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. */
|
||||
@ -133,6 +144,15 @@ typedef struct mbedtls_ecdh_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.
|
||||
|
@ -125,6 +125,16 @@ 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.
|
||||
|
@ -437,6 +437,12 @@ mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp );
|
||||
* mbedtls_ecp_curve_info() for all supported curves in order
|
||||
* of preference.
|
||||
*
|
||||
* \note This function returns information about all curves
|
||||
* supported by the library. Some curves may not be
|
||||
* supported for all algorithms. Call mbedtls_ecdh_can_do()
|
||||
* or mbedtls_ecdsa_can_do() to check if a curve is
|
||||
* supported for ECDH or ECDSA.
|
||||
*
|
||||
* \return A statically allocated array. The last entry is 0.
|
||||
*/
|
||||
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
|
||||
@ -446,6 +452,12 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
|
||||
* identifiers of all supported curves in the order of
|
||||
* preference.
|
||||
*
|
||||
* \note This function returns information about all curves
|
||||
* supported by the library. Some curves may not be
|
||||
* supported for all algorithms. Call mbedtls_ecdh_can_do()
|
||||
* or mbedtls_ecdsa_can_do() to check if a curve is
|
||||
* supported for ECDH or ECDSA.
|
||||
*
|
||||
* \return A statically allocated array,
|
||||
* terminated with MBEDTLS_ECP_DP_NONE.
|
||||
*/
|
||||
|
@ -100,8 +100,8 @@
|
||||
* ECP 4 10 (Started from top)
|
||||
* MD 5 5
|
||||
* HKDF 5 1 (Started from top)
|
||||
* CIPHER 6 8
|
||||
* SSL 6 23 (Started from top)
|
||||
* CIPHER 6 8 (Started from 0x6080)
|
||||
* SSL 6 24 (Started from top, plus 0x6000)
|
||||
* SSL 7 32
|
||||
*
|
||||
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
||||
|
@ -7,22 +7,22 @@
|
||||
* specified by RFC 5869.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
* 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)
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
#ifndef MBEDTLS_HKDF_H
|
||||
#define MBEDTLS_HKDF_H
|
||||
|
@ -112,17 +112,27 @@ void mbedtls_pem_free( mbedtls_pem_context *ctx );
|
||||
* \brief Write a buffer of PEM information from a DER encoded
|
||||
* buffer.
|
||||
*
|
||||
* \param header header string to write
|
||||
* \param footer footer string to write
|
||||
* \param der_data DER data to write
|
||||
* \param der_len length of the DER data
|
||||
* \param buf buffer to write to
|
||||
* \param buf_len length of output buffer
|
||||
* \param olen total length written / required (if buf_len is not enough)
|
||||
* \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).
|
||||
*
|
||||
* \return 0 on success, or a specific PEM or BASE64 error code. On
|
||||
* MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
|
||||
* size.
|
||||
* \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,
|
||||
|
@ -217,7 +217,7 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx );
|
||||
*
|
||||
* \note For contexts that have been set up with
|
||||
* mbedtls_pk_setup_opaque(), this does not free the underlying
|
||||
* key slot and you still need to call psa_destroy_key()
|
||||
* 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 );
|
||||
@ -259,21 +259,21 @@ 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 slot.
|
||||
* \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 slot instead of
|
||||
* 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 slot to wrap, which must hold an ECC key pair
|
||||
* \param key The PSA key to wrap, which must hold an ECC key pair
|
||||
* (see notes below).
|
||||
*
|
||||
* \note The wrapped key slot must remain valid as long as the
|
||||
* \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 slot might then be independently used or destroyed.
|
||||
* 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).
|
||||
@ -281,7 +281,7 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
|
||||
* (context already used, invalid key slot).
|
||||
* (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.
|
||||
@ -788,7 +788,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/**
|
||||
* \brief Turn an EC key into an Opaque one
|
||||
* \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.
|
||||
@ -796,18 +796,19 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
|
||||
* \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 transfer to a PSA key slot.
|
||||
* Output: a PK context wrapping that PSA key slot.
|
||||
* \param slot Output: the chosen slot for storing the key.
|
||||
* It's the caller's responsibility to destroy that slot
|
||||
* after calling mbedtls_pk_free() on the PK context.
|
||||
* \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 *slot,
|
||||
psa_key_handle_t *handle,
|
||||
psa_algorithm_t hash_alg );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
|
@ -256,6 +256,7 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
|
||||
* 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
|
||||
|
@ -43,6 +43,12 @@ extern "C" {
|
||||
|
||||
#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.
|
||||
*
|
||||
@ -50,6 +56,11 @@ extern "C" {
|
||||
* 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__ )
|
||||
|
@ -413,7 +413,7 @@ static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
|
||||
/* All other failures */
|
||||
case PSA_ERROR_COMMUNICATION_FAILURE:
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
case PSA_ERROR_TAMPERING_DETECTED:
|
||||
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
|
||||
|
2278
include/psa/crypto.h
2278
include/psa/crypto.h
File diff suppressed because it is too large
Load Diff
@ -62,21 +62,19 @@ extern "C" {
|
||||
MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA )
|
||||
#endif
|
||||
|
||||
/** \addtogroup policy
|
||||
/** \addtogroup attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Set the enrollment algorithm in a key policy.
|
||||
/** \brief Declare the enrollment algorithm for a key.
|
||||
*
|
||||
* An operation on a key may indifferently use the algorithm set with
|
||||
* psa_key_policy_set_usage() or with this function.
|
||||
* psa_set_key_algorithm() or with this function.
|
||||
*
|
||||
* \param[in,out] policy The key policy to modify. It must have been
|
||||
* initialized as per the documentation for
|
||||
* #psa_key_policy_t.
|
||||
* \param alg2 A second algorithm that the key may be used for,
|
||||
* in addition to the algorithm set with
|
||||
* psa_key_policy_set_usage().
|
||||
* \param[out] attributes The attribute structure to write to.
|
||||
* \param alg2 A second algorithm that the key may be used
|
||||
* for, in addition to the algorithm set with
|
||||
* psa_set_key_algorithm().
|
||||
*
|
||||
* \warning Setting an enrollment algorithm is not recommended, because
|
||||
* using the same key with different algorithms can allow some
|
||||
@ -87,17 +85,135 @@ extern "C" {
|
||||
* verified that the usage of the key with multiple algorithms
|
||||
* is safe.
|
||||
*/
|
||||
void psa_key_policy_set_enrollment_algorithm(psa_key_policy_t *policy,
|
||||
psa_algorithm_t alg2);
|
||||
static inline void psa_set_key_enrollment_algorithm(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg2)
|
||||
{
|
||||
attributes->core.policy.alg2 = alg2;
|
||||
}
|
||||
|
||||
/** \brief Retrieve the enrollment algorithm field of a policy structure.
|
||||
/** Retrieve the enrollment algorithm policy from key attributes.
|
||||
*
|
||||
* \param[in] policy The policy object to query.
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
*
|
||||
* \return The enrollment algorithm for a key with this policy.
|
||||
* \return The enrollment algorithm stored in the attribute structure.
|
||||
*/
|
||||
psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
|
||||
const psa_key_policy_t *policy);
|
||||
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.alg2 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
||||
/** Retrieve the slot number where a key is stored.
|
||||
*
|
||||
* A slot number is only defined for keys that are stored in a secure
|
||||
* element.
|
||||
*
|
||||
* This information is only useful if the secure element is not entirely
|
||||
* managed through the PSA Cryptography API. It is up to the secure
|
||||
* element driver to decide how PSA slot numbers map to any other interface
|
||||
* that the secure element may have.
|
||||
*
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
* \param[out] slot_number On success, the slot number containing the key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key is located in a secure element, and \p *slot_number
|
||||
* indicates the slot number that contains it.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The caller is not permitted to query the slot number.
|
||||
* Mbed Crypto currently does not return this error.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key is not located in a secure element.
|
||||
*/
|
||||
psa_status_t psa_get_key_slot_number(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t *slot_number );
|
||||
|
||||
/** Choose the slot number where a key is stored.
|
||||
*
|
||||
* This function declares a slot number in the specified attribute
|
||||
* structure.
|
||||
*
|
||||
* A slot number is only meaningful for keys that are stored in a secure
|
||||
* element. It is up to the secure element driver to decide how PSA slot
|
||||
* numbers map to any other interface that the secure element may have.
|
||||
*
|
||||
* \note Setting a slot number in key attributes for a key creation can
|
||||
* cause the following errors when creating the key:
|
||||
* - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does
|
||||
* not support choosing a specific slot number.
|
||||
* - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to
|
||||
* choose slot numbers in general or to choose this specific slot.
|
||||
* - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not
|
||||
* valid in general or not valid for this specific key.
|
||||
* - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the
|
||||
* selected slot.
|
||||
*
|
||||
* \param[out] attributes The attribute structure to write to.
|
||||
* \param slot_number The slot number to set.
|
||||
*/
|
||||
static inline void psa_set_key_slot_number(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t slot_number )
|
||||
{
|
||||
attributes->core.flags |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
|
||||
attributes->slot_number = slot_number;
|
||||
}
|
||||
|
||||
/** Remove the slot number attribute from a key attribute structure.
|
||||
*
|
||||
* This function undoes the action of psa_set_key_slot_number().
|
||||
*
|
||||
* \param[out] attributes The attribute structure to write to.
|
||||
*/
|
||||
static inline void psa_clear_key_slot_number(
|
||||
psa_key_attributes_t *attributes )
|
||||
{
|
||||
attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
|
||||
}
|
||||
|
||||
/** Register a key that is already present in a secure element.
|
||||
*
|
||||
* The key must be located in a secure element designated by the
|
||||
* lifetime field in \p attributes, in the slot set with
|
||||
* psa_set_key_slot_number() in the attribute structure.
|
||||
* This function makes the key available through the key identifier
|
||||
* specified in \p attributes.
|
||||
*
|
||||
* \param[in] attributes The attributes of the existing key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully registered.
|
||||
* Note that depending on the design of the driver, this may or may
|
||||
* not guarantee that a key actually exists in the designated slot
|
||||
* and is compatible with the specified attributes.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* There is already a key with the identifier specified in
|
||||
* \p attributes.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p attributes specifies a lifetime which is not located
|
||||
* in a secure element.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* No slot number is specified in \p attributes,
|
||||
* or the specified slot number is not valid.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The caller is not authorized to register the specified key slot.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been previously initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_register_se_key(
|
||||
const psa_key_attributes_t *attributes);
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
/**@}*/
|
||||
|
||||
@ -111,6 +227,43 @@ psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
|
||||
*/
|
||||
void mbedtls_psa_crypto_free( void );
|
||||
|
||||
/** \brief Statistics about
|
||||
* resource consumption related to the PSA keystore.
|
||||
*
|
||||
* \note The content of this structure is not part of the stable API and ABI
|
||||
* of Mbed Crypto and may change arbitrarily from version to version.
|
||||
*/
|
||||
typedef struct mbedtls_psa_stats_s
|
||||
{
|
||||
/** Number of slots containing key material for a volatile key. */
|
||||
size_t volatile_slots;
|
||||
/** Number of slots containing key material for a key which is in
|
||||
* internal persistent storage. */
|
||||
size_t persistent_slots;
|
||||
/** Number of slots containing a reference to a key in a
|
||||
* secure element. */
|
||||
size_t external_slots;
|
||||
/** Number of slots which are occupied, but do not contain
|
||||
* key material yet. */
|
||||
size_t half_filled_slots;
|
||||
/** Number of slots that contain cache data. */
|
||||
size_t cache_slots;
|
||||
/** Number of slots that are not used for anything. */
|
||||
size_t empty_slots;
|
||||
/** Largest key id value among open keys in internal persistent storage. */
|
||||
psa_app_key_id_t max_open_internal_key_id;
|
||||
/** Largest key id value among open keys in secure elements. */
|
||||
psa_app_key_id_t max_open_external_key_id;
|
||||
} mbedtls_psa_stats_t;
|
||||
|
||||
/** \brief Get statistics about
|
||||
* resource consumption related to the PSA keystore.
|
||||
*
|
||||
* \note When Mbed Crypto is built as part of a service, with isolation
|
||||
* between the application and the keystore, the service may or
|
||||
* may not expose this function.
|
||||
*/
|
||||
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats );
|
||||
|
||||
/**
|
||||
* \brief Inject an initial entropy seed for the random generator into
|
||||
@ -179,9 +332,249 @@ void mbedtls_psa_crypto_free( void );
|
||||
* The library has already been initialized. It is no longer
|
||||
* possible to call this function.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
|
||||
psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
|
||||
size_t seed_size);
|
||||
|
||||
/** \addtogroup crypto_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** DSA public key.
|
||||
*
|
||||
* The import and export format is the
|
||||
* representation of the public key `y = g^x mod p` as a big-endian byte
|
||||
* string. The length of the byte string is the length of the base prime `p`
|
||||
* in bytes.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
|
||||
|
||||
/** DSA key pair (private and public key).
|
||||
*
|
||||
* The import and export format is the
|
||||
* representation of the private key `x` as a big-endian byte string. The
|
||||
* length of the byte string is the private key size in bytes (leading zeroes
|
||||
* are not stripped).
|
||||
*
|
||||
* Determinstic DSA key derivation with psa_generate_derived_key follows
|
||||
* FIPS 186-4 §B.1.2: interpret the byte string as integer
|
||||
* in big-endian order. Discard it if it is not in the range
|
||||
* [0, *N* - 2] where *N* is the boundary of the private key domain
|
||||
* (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
|
||||
* or the order of the curve's base point for ECC).
|
||||
* Add 1 to the resulting integer and use this as the private key *x*.
|
||||
*
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t)0x70020000)
|
||||
|
||||
/** Whether a key type is an DSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
|
||||
|
||||
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
|
||||
/** DSA signature with hashing.
|
||||
*
|
||||
* This is the signature scheme defined by FIPS 186-4,
|
||||
* with a random per-message secret number (*k*).
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DSA(hash_alg) \
|
||||
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
|
||||
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
|
||||
/** Deterministic DSA signature with hashing.
|
||||
*
|
||||
* This is the deterministic variant defined by RFC 6979 of
|
||||
* the signature scheme defined by FIPS 186-4.
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
|
||||
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_IS_DSA(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
|
||||
PSA_ALG_DSA_BASE)
|
||||
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
|
||||
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
|
||||
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
|
||||
|
||||
/* We need to expand the sample definition of this macro from
|
||||
* the API definition. */
|
||||
#undef PSA_ALG_IS_HASH_AND_SIGN
|
||||
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
|
||||
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
|
||||
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \addtogroup attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Custom Diffie-Hellman group.
|
||||
*
|
||||
* For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM), the group data comes
|
||||
* from domain parameters set by psa_set_key_domain_parameters().
|
||||
*/
|
||||
/* This value is reserved for private use in the TLS named group registry. */
|
||||
#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0x01fc)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set domain parameters for a key.
|
||||
*
|
||||
* Some key types require additional domain parameters in addition to
|
||||
* the key type identifier and the key size. Use this function instead
|
||||
* of psa_set_key_type() when you need to specify domain parameters.
|
||||
*
|
||||
* The format for the required domain parameters varies based on the key type.
|
||||
*
|
||||
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
|
||||
* the domain parameter data consists of the public exponent,
|
||||
* represented as a big-endian integer with no leading zeros.
|
||||
* This information is used when generating an RSA key pair.
|
||||
* When importing a key, the public exponent is read from the imported
|
||||
* key data and the exponent recorded in the attribute structure is ignored.
|
||||
* As an exception, the public exponent 65537 is represented by an empty
|
||||
* byte string.
|
||||
* - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR),
|
||||
* the `Dss-Parms` format as defined by RFC 3279 §2.3.2.
|
||||
* ```
|
||||
* Dss-Parms ::= SEQUENCE {
|
||||
* p INTEGER,
|
||||
* q INTEGER,
|
||||
* g INTEGER
|
||||
* }
|
||||
* ```
|
||||
* - For Diffie-Hellman key exchange keys
|
||||
* (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM)), the
|
||||
* `DomainParameters` format as defined by RFC 3279 §2.3.3.
|
||||
* ```
|
||||
* DomainParameters ::= SEQUENCE {
|
||||
* p INTEGER, -- odd prime, p=jq +1
|
||||
* g INTEGER, -- generator, g
|
||||
* q INTEGER, -- factor of p-1
|
||||
* j INTEGER OPTIONAL, -- subgroup factor
|
||||
* validationParms ValidationParms OPTIONAL
|
||||
* }
|
||||
* ValidationParms ::= SEQUENCE {
|
||||
* seed BIT STRING,
|
||||
* pgenCounter INTEGER
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \note This function may allocate memory or other resources.
|
||||
* Once you have called this function on an attribute structure,
|
||||
* you must call psa_reset_key_attributes() to free these resources.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param[in,out] attributes Attribute structure where the specified domain
|
||||
* parameters will be stored.
|
||||
* If this function fails, the content of
|
||||
* \p attributes is not modified.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[in] data Buffer containing the key domain parameters.
|
||||
* The content of this buffer is interpreted
|
||||
* according to \p type as described above.
|
||||
* \param data_length Size of the \p data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
*/
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
/**
|
||||
* \brief Get domain parameters for a key.
|
||||
*
|
||||
* Get the domain parameters for a key with this function, if any. The format
|
||||
* of the domain parameters written to \p data is specified in the
|
||||
* documentation for psa_set_key_domain_parameters().
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
* \param[out] data On success, the key domain parameters.
|
||||
* \param data_size Size of the \p data buffer in bytes.
|
||||
* The buffer is guaranteed to be large
|
||||
* enough if its size in bytes is at least
|
||||
* the value given by
|
||||
* PSA_KEY_DOMAIN_PARAMETERS_SIZE().
|
||||
* \param[out] data_length On success, the number of bytes
|
||||
* that make up the key domain parameters data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
*/
|
||||
psa_status_t psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Safe output buffer size for psa_get_key_domain_parameters().
|
||||
*
|
||||
* This macro returns a compile-time constant if its arguments are
|
||||
* compile-time constants.
|
||||
*
|
||||
* \warning This function may call its arguments multiple times or
|
||||
* zero times, so you should not pass arguments that contain
|
||||
* side effects.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param key_type A supported key type.
|
||||
* \param key_bits The size of the key in bits.
|
||||
*
|
||||
* \return If the parameters are valid and supported, return
|
||||
* a buffer size in bytes that guarantees that
|
||||
* psa_get_key_domain_parameters() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
*/
|
||||
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \
|
||||
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
0)
|
||||
#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/)
|
||||
#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/)
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* \file psa/crypto_platform.h
|
||||
*
|
||||
* \brief PSA cryptography module: Mbed TLS platfom definitions
|
||||
* \brief PSA cryptography module: Mbed TLS platform definitions
|
||||
*
|
||||
* \note This file may not be included directly. Applications must
|
||||
* include psa/crypto.h.
|
||||
@ -89,6 +89,7 @@ typedef struct
|
||||
* `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an
|
||||
* alias for `psa_key_file_id_t` when building for a multi-client service. */
|
||||
typedef psa_key_file_id_t psa_key_id_t;
|
||||
#define PSA_KEY_ID_INIT {0, 0}
|
||||
|
||||
#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
|
||||
|
||||
|
@ -8,11 +8,11 @@
|
||||
* space in which the PSA Crypto implementation runs, typically secure
|
||||
* elements (SEs).
|
||||
*
|
||||
* This file is part of the PSA Crypto Driver Model, containing functions for
|
||||
* driver developers to implement to enable hardware to be called in a
|
||||
* standardized way by a PSA Cryptographic API implementation. The functions
|
||||
* comprising the driver model, which driver authors implement, are not
|
||||
* intended to be called by application developers.
|
||||
* This file is part of the PSA Crypto Driver HAL (hardware abstraction layer),
|
||||
* containing functions for driver developers to implement to enable hardware
|
||||
* to be called in a standardized way by a PSA Cryptography API
|
||||
* implementation. The functions comprising the driver HAL, which driver
|
||||
* authors implement, are not intended to be called by application developers.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -40,10 +40,113 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup se_init Secure element driver initialization
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/** \brief Driver context structure
|
||||
*
|
||||
* Driver functions receive a pointer to this structure.
|
||||
* Each registered driver has one instance of this structure.
|
||||
*
|
||||
* Implementations must include the fields specified here and
|
||||
* may include other fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/** A read-only pointer to the driver's persistent data.
|
||||
*
|
||||
* Drivers typically use this persistent data to keep track of
|
||||
* which slot numbers are available. This is only a guideline:
|
||||
* drivers may use the persistent data for any purpose, keeping
|
||||
* in mind the restrictions on when the persistent data is saved
|
||||
* to storage: the persistent data is only saved after calling
|
||||
* certain functions that receive a writable pointer to the
|
||||
* persistent data.
|
||||
*
|
||||
* The core allocates a memory buffer for the persistent data.
|
||||
* The pointer is guaranteed to be suitably aligned for any data type,
|
||||
* like a pointer returned by `malloc` (but the core can use any
|
||||
* method to allocate the buffer, not necessarily `malloc`).
|
||||
*
|
||||
* The size of this buffer is in the \c persistent_data_size field of
|
||||
* this structure.
|
||||
*
|
||||
* Before the driver is initialized for the first time, the content of
|
||||
* the persistent data is all-bits-zero. After a driver upgrade, if the
|
||||
* size of the persistent data has increased, the original data is padded
|
||||
* on the right with zeros; if the size has decreased, the original data
|
||||
* is truncated to the new size.
|
||||
*
|
||||
* This pointer is to read-only data. Only a few driver functions are
|
||||
* allowed to modify the persistent data. These functions receive a
|
||||
* writable pointer. These functions are:
|
||||
* - psa_drv_se_t::p_init
|
||||
* - psa_drv_se_key_management_t::p_allocate
|
||||
* - psa_drv_se_key_management_t::p_destroy
|
||||
*
|
||||
* The PSA Cryptography core saves the persistent data from one
|
||||
* session to the next. It does this before returning from API functions
|
||||
* that call a driver method that is allowed to modify the persistent
|
||||
* data, specifically:
|
||||
* - psa_crypto_init() causes a call to psa_drv_se_t::p_init, and may call
|
||||
* psa_drv_se_key_management_t::p_destroy to complete an action
|
||||
* that was interrupted by a power failure.
|
||||
* - Key creation functions cause a call to
|
||||
* psa_drv_se_key_management_t::p_allocate, and may cause a call to
|
||||
* psa_drv_se_key_management_t::p_destroy in case an error occurs.
|
||||
* - psa_destroy_key() causes a call to
|
||||
* psa_drv_se_key_management_t::p_destroy.
|
||||
*/
|
||||
const void *const persistent_data;
|
||||
|
||||
/** The size of \c persistent_data in bytes.
|
||||
*
|
||||
* This is always equal to the value of the `persistent_data_size` field
|
||||
* of the ::psa_drv_se_t structure when the driver is registered.
|
||||
*/
|
||||
const size_t persistent_data_size;
|
||||
|
||||
/** Driver transient data.
|
||||
*
|
||||
* The core initializes this value to 0 and does not read or modify it
|
||||
* afterwards. The driver may store whatever it wants in this field.
|
||||
*/
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_context_t;
|
||||
|
||||
/** \brief A driver initialization function.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param lifetime The lifetime value for which this driver
|
||||
* is registered.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The driver is operational.
|
||||
* The core will update the persistent data in storage.
|
||||
* \return
|
||||
* Any other return value prevents the driver from being used in
|
||||
* this session.
|
||||
* The core will NOT update the persistent data in storage.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
psa_key_lifetime_t lifetime);
|
||||
|
||||
#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* Mbed Crypto with secure element support enabled defines this type in
|
||||
* crypto_types.h because it is also visible to applications through an
|
||||
* implementation-specific extension.
|
||||
* For the PSA Cryptography specification, this type is only visible
|
||||
* via crypto_se_driver.h. */
|
||||
/** An internal designation of a key slot between the core part of the
|
||||
* PSA Crypto implementation and the driver. The meaning of this value
|
||||
* is driver-dependent. */
|
||||
typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after psa_key_slot_t is removed from Mbed crypto
|
||||
typedef uint64_t psa_key_slot_number_t;
|
||||
#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup se_mac Secure Element Message Authentication Codes
|
||||
* Generation and authentication of Message Authentication Codes (MACs) using
|
||||
@ -65,7 +168,8 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
|
||||
/** \brief A function that starts a secure element MAC operation for a PSA
|
||||
* Crypto Driver implementation
|
||||
*
|
||||
* \param[in,out] p_context A structure that will contain the
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A structure that will contain the
|
||||
* hardware-specific MAC context
|
||||
* \param[in] key_slot The slot of the key to be used for the
|
||||
* operation
|
||||
@ -75,28 +179,29 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
|
||||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm);
|
||||
|
||||
/** \brief A function that continues a previously started secure element MAC
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously-established MAC operation to be
|
||||
* updated
|
||||
* \param[in] p_input A buffer containing the message to be appended
|
||||
* to the MAC operation
|
||||
* \param[in] input_length The size in bytes of the input message buffer
|
||||
* \param[in] input_length The size in bytes of the input message buffer
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *op_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length);
|
||||
|
||||
/** \brief a function that completes a previously started secure element MAC
|
||||
* operation by returning the resulting MAC.
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started MAC operation to be
|
||||
* finished
|
||||
* \param[out] p_mac A buffer where the generated MAC will be
|
||||
@ -109,7 +214,7 @@ typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
|
||||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context,
|
||||
uint8_t *p_mac,
|
||||
size_t mac_size,
|
||||
size_t *p_mac_length);
|
||||
@ -117,11 +222,11 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
||||
/** \brief A function that completes a previously started secure element MAC
|
||||
* operation by comparing the resulting MAC against a provided value
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be fiinished
|
||||
* \param[in] p_mac The MAC value against which the resulting MAC will
|
||||
* be compared against
|
||||
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
|
||||
* \param[in,out] op_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be fiinished
|
||||
* \param[in] p_mac The MAC value against which the resulting MAC
|
||||
* will be compared against
|
||||
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* The operation completed successfully and the MACs matched each
|
||||
@ -130,21 +235,22 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
||||
* The operation completed successfully, but the calculated MAC did
|
||||
* not match the provided MAC
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *op_context,
|
||||
const uint8_t *p_mac,
|
||||
size_t mac_length);
|
||||
|
||||
/** \brief A function that aborts a previous started secure element MAC
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be aborted
|
||||
* \param[in,out] op_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be aborted
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
|
||||
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context);
|
||||
|
||||
/** \brief A function that performs a secure element MAC operation in one
|
||||
* command and returns the calculated MAC
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] p_input A buffer containing the message to be MACed
|
||||
* \param[in] input_length The size in bytes of `p_input`
|
||||
* \param[in] key_slot The slot of the key to be used
|
||||
@ -159,7 +265,8 @@ typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
|
||||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
||||
typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
@ -170,6 +277,7 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
||||
/** \brief A function that performs a secure element MAC operation in one
|
||||
* command and compares the resulting MAC against a provided value
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] p_input A buffer containing the message to be MACed
|
||||
* \param[in] input_length The size in bytes of `input`
|
||||
* \param[in] key_slot The slot of the key to be used
|
||||
@ -186,7 +294,8 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
||||
* The operation completed successfully, but the calculated MAC did
|
||||
* not match the provided MAC
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_verify_t)(const uint8_t *p_input,
|
||||
typedef psa_status_t (*psa_drv_se_mac_verify_t)(psa_drv_se_context_t *drv_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
@ -263,7 +372,8 @@ typedef struct {
|
||||
/** \brief A function that provides the cipher setup function for a
|
||||
* secure element driver
|
||||
*
|
||||
* \param[in,out] p_context A structure that will contain the
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A structure that will contain the
|
||||
* hardware-specific cipher context.
|
||||
* \param[in] key_slot The slot of the key to be used for the
|
||||
* operation
|
||||
@ -275,7 +385,8 @@ typedef struct {
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction);
|
||||
@ -288,21 +399,21 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
|
||||
* generate function is not necessary for the drivers to implement as the PSA
|
||||
* Crypto implementation can do the generation using its RNG features.
|
||||
*
|
||||
* \param[in,out] p_context A structure that contains the previously set up
|
||||
* \param[in,out] op_context A structure that contains the previously set up
|
||||
* hardware-specific cipher context
|
||||
* \param[in] p_iv A buffer containing the initialization vector
|
||||
* \param[in] iv_length The size (in bytes) of the `p_iv` buffer
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context,
|
||||
const uint8_t *p_iv,
|
||||
size_t iv_length);
|
||||
|
||||
/** \brief A function that continues a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
@ -317,7 +428,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_size,
|
||||
uint8_t *p_output,
|
||||
@ -327,7 +438,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
||||
/** \brief A function that completes a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
* \param[out] p_output The caller-allocated buffer where the output
|
||||
* will be placed
|
||||
@ -338,7 +449,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length);
|
||||
@ -346,10 +457,10 @@ typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
|
||||
/** \brief A function that aborts a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
|
||||
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context);
|
||||
|
||||
/** \brief A function that performs the ECB block mode for secure element
|
||||
* cipher operations
|
||||
@ -357,23 +468,25 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
|
||||
* Note: this function should only be used with implementations that do not
|
||||
* provide a needed higher-level operation.
|
||||
*
|
||||
* \param[in] key_slot The slot of the key to be used for the operation
|
||||
* \param[in] algorithm The algorithm to be used in the cipher operation
|
||||
* \param[in] direction Indicates whether the operation is an encrypt or
|
||||
* decrypt
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
* \param[in] input_size The size in bytes of the buffer pointed to by
|
||||
* `p_input`
|
||||
* \param[out] p_output The caller-allocated buffer where the output will
|
||||
* be placed
|
||||
* \param[in] output_size The allocated size in bytes of the `p_output`
|
||||
* buffer
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot The slot of the key to be used for the operation
|
||||
* \param[in] algorithm The algorithm to be used in the cipher operation
|
||||
* \param[in] direction Indicates whether the operation is an encrypt or
|
||||
* decrypt
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
* \param[in] input_size The size in bytes of the buffer pointed to by
|
||||
* `p_input`
|
||||
* \param[out] p_output The caller-allocated buffer where the output
|
||||
* will be placed
|
||||
* \param[in] output_size The allocated size in bytes of the `p_output`
|
||||
* buffer
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction,
|
||||
const uint8_t *p_input,
|
||||
@ -427,6 +540,7 @@ typedef struct {
|
||||
* \brief A function that signs a hash or short message with a private key in
|
||||
* a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of an asymmetric key pair
|
||||
* \param[in] alg A signature algorithm that is compatible
|
||||
* with the type of `key`
|
||||
@ -439,7 +553,8 @@ typedef struct {
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
@ -451,6 +566,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
|
||||
* \brief A function that verifies the signature a hash or short message using
|
||||
* an asymmetric public key in a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of a public key or an asymmetric key
|
||||
* pair
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
@ -463,7 +579,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
|
||||
* \retval PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
@ -474,6 +591,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
|
||||
* \brief A function that encrypts a short message with an asymmetric public
|
||||
* key in a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of a public key or an asymmetric key
|
||||
* pair
|
||||
* \param[in] alg An asymmetric encryption algorithm that is
|
||||
@ -499,7 +617,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
@ -513,6 +632,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
|
||||
* \brief A function that decrypts a short message with an asymmetric private
|
||||
* key in a secure element.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of an asymmetric key pair
|
||||
* \param[in] alg An asymmetric encryption algorithm that is
|
||||
* compatible with the type of `key`
|
||||
@ -537,7 +657,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
@ -581,6 +702,7 @@ typedef struct {
|
||||
/** \brief A function that performs a secure element authenticated encryption
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot containing the key to use.
|
||||
* \param[in] algorithm The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
@ -608,7 +730,8 @@ typedef struct {
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
const uint8_t *p_nonce,
|
||||
size_t nonce_length,
|
||||
@ -622,6 +745,7 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
|
||||
|
||||
/** A function that peforms a secure element authenticated decryption operation
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot containing the key to use
|
||||
* \param[in] algorithm The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
@ -648,7 +772,8 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
const uint8_t *p_nonce,
|
||||
size_t nonce_length,
|
||||
@ -685,31 +810,182 @@ typedef struct {
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/** An enumeration indicating how a key is created.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PSA_KEY_CREATION_IMPORT, /**< During psa_import_key() */
|
||||
PSA_KEY_CREATION_GENERATE, /**< During psa_generate_key() */
|
||||
PSA_KEY_CREATION_DERIVE, /**< During psa_key_derivation_output_key() */
|
||||
PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */
|
||||
|
||||
#ifndef __DOXYGEN_ONLY__
|
||||
/** A key is being registered with mbedtls_psa_register_se_key().
|
||||
*
|
||||
* The core only passes this value to
|
||||
* psa_drv_se_key_management_t::p_validate_slot_number, not to
|
||||
* psa_drv_se_key_management_t::p_allocate. The call to
|
||||
* `p_validate_slot_number` is not followed by any other call to the
|
||||
* driver: the key is considered successfully registered if the call to
|
||||
* `p_validate_slot_number` succeeds, or if `p_validate_slot_number` is
|
||||
* null.
|
||||
*
|
||||
* With this creation method, the driver must return #PSA_SUCCESS if
|
||||
* the given attributes are compatible with the existing key in the slot,
|
||||
* and #PSA_ERROR_DOES_NOT_EXIST if the driver can determine that there
|
||||
* is no key with the specified slot number.
|
||||
*
|
||||
* This is an Mbed Crypto extension.
|
||||
*/
|
||||
PSA_KEY_CREATION_REGISTER,
|
||||
#endif
|
||||
} psa_key_creation_method_t;
|
||||
|
||||
/** \brief A function that allocates a slot for a key.
|
||||
*
|
||||
* To create a key in a specific slot in a secure element, the core
|
||||
* first calls this function to determine a valid slot number,
|
||||
* then calls a function to create the key material in that slot.
|
||||
* In nominal conditions (that is, if no error occurs),
|
||||
* the effect of a call to a key creation function in the PSA Cryptography
|
||||
* API with a lifetime that places the key in a secure element is the
|
||||
* following:
|
||||
* -# The core calls psa_drv_se_key_management_t::p_allocate
|
||||
* (or in some implementations
|
||||
* psa_drv_se_key_management_t::p_validate_slot_number). The driver
|
||||
* selects (or validates) a suitable slot number given the key attributes
|
||||
* and the state of the secure element.
|
||||
* -# The core calls a key creation function in the driver.
|
||||
*
|
||||
* The key creation functions in the PSA Cryptography API are:
|
||||
* - psa_import_key(), which causes
|
||||
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_IMPORT
|
||||
* then a call to psa_drv_se_key_management_t::p_import.
|
||||
* - psa_generate_key(), which causes
|
||||
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_GENERATE
|
||||
* then a call to psa_drv_se_key_management_t::p_import.
|
||||
* - psa_key_derivation_output_key(), which causes
|
||||
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_DERIVE
|
||||
* then a call to psa_drv_se_key_derivation_t::p_derive.
|
||||
* - psa_copy_key(), which causes
|
||||
* a call to `p_allocate` with \p method = #PSA_KEY_CREATION_COPY
|
||||
* then a call to psa_drv_se_key_management_t::p_export.
|
||||
*
|
||||
* In case of errors, other behaviors are possible.
|
||||
* - If the PSA Cryptography subsystem dies after the first step,
|
||||
* for example because the device has lost power abruptly,
|
||||
* the second step may never happen, or may happen after a reset
|
||||
* and re-initialization. Alternatively, after a reset and
|
||||
* re-initialization, the core may call
|
||||
* psa_drv_se_key_management_t::p_destroy on the slot number that
|
||||
* was allocated (or validated) instead of calling a key creation function.
|
||||
* - If an error occurs, the core may call
|
||||
* psa_drv_se_key_management_t::p_destroy on the slot number that
|
||||
* was allocated (or validated) instead of calling a key creation function.
|
||||
*
|
||||
* Errors and system resets also have an impact on the driver's persistent
|
||||
* data. If a reset happens before the overall key creation process is
|
||||
* completed (before or after the second step above), it is unspecified
|
||||
* whether the persistent data after the reset is identical to what it
|
||||
* was before or after the call to `p_allocate` (or `p_validate_slot_number`).
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param[in] attributes Attributes of the key.
|
||||
* \param method The way in which the key is being created.
|
||||
* \param[out] key_slot Slot where the key will be stored.
|
||||
* This must be a valid slot for a key of the
|
||||
* chosen type. It must be unoccupied.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* The core will record \c *key_slot as the key slot where the key
|
||||
* is stored and will update the persistent data in storage.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_allocate_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_key_slot_number_t *key_slot);
|
||||
|
||||
/** \brief A function that determines whether a slot number is valid
|
||||
* for a key.
|
||||
*
|
||||
* To create a key in a specific slot in a secure element, the core
|
||||
* first calls this function to validate the choice of slot number,
|
||||
* then calls a function to create the key material in that slot.
|
||||
* See the documentation of #psa_drv_se_allocate_key_t for more details.
|
||||
*
|
||||
* As of the PSA Cryptography API specification version 1.0, there is no way
|
||||
* for applications to trigger a call to this function. However some
|
||||
* implementations offer the capability to create or declare a key in
|
||||
* a specific slot via implementation-specific means, generally for the
|
||||
* sake of initial device provisioning or onboarding. Such a mechanism may
|
||||
* be added to a future version of the PSA Cryptography API specification.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] attributes Attributes of the key.
|
||||
* \param method The way in which the key is being created.
|
||||
* \param[in] key_slot Slot where the key is to be stored.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The given slot number is valid for a key with the given
|
||||
* attributes.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The given slot number is not valid for a key with the
|
||||
* given attributes. This includes the case where the slot
|
||||
* number is not valid at all.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* There is already a key with the specified slot number.
|
||||
* Drivers may choose to return this error from the key
|
||||
* creation function instead.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_key_slot_number_t key_slot);
|
||||
|
||||
/** \brief A function that imports a key into a secure element in binary format
|
||||
*
|
||||
* This function can support any output from psa_export_key(). Refer to the
|
||||
* documentation of psa_export_key() for the format for each key type.
|
||||
*
|
||||
* \param[in] key_slot Slot where the key will be stored
|
||||
* This must be a valid slot for a key of the chosen
|
||||
* type. It must be unoccupied.
|
||||
* \param[in] lifetime The required lifetime of the key storage
|
||||
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
|
||||
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
|
||||
* \param[in] usage The allowed uses of the key
|
||||
* \param[in] p_data Buffer containing the key data
|
||||
* \param[in] data_length Size of the `data` buffer in bytes
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param key_slot Slot where the key will be stored.
|
||||
* This must be a valid slot for a key of the
|
||||
* chosen type. It must be unoccupied.
|
||||
* \param[in] attributes The key attributes, including the lifetime,
|
||||
* the key type and the usage policy.
|
||||
* Drivers should not access the key size stored
|
||||
* in the attributes: it may not match the
|
||||
* data passed in \p data.
|
||||
* Drivers can call psa_get_key_lifetime(),
|
||||
* psa_get_key_type(),
|
||||
* psa_get_key_usage_flags() and
|
||||
* psa_get_key_algorithm() to access this
|
||||
* information.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param[in] data_length Size of the \p data buffer in bytes.
|
||||
* \param[out] bits On success, the key size in bits. The driver
|
||||
* must determine this value after parsing the
|
||||
* key according to the key type.
|
||||
* This value is not used if the function fails.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_type_t type,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_usage_t usage,
|
||||
const uint8_t *p_data,
|
||||
size_t data_length);
|
||||
typedef psa_status_t (*psa_drv_se_import_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
size_t *bits);
|
||||
|
||||
/**
|
||||
* \brief A function that destroys a secure element key and restore the slot to
|
||||
@ -721,12 +997,18 @@ typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
|
||||
*
|
||||
* This function returns the specified slot to its default state.
|
||||
*
|
||||
* \param[in] key_slot The key slot to erase.
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param key_slot The key slot to erase.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The slot's content, if any, has been erased.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
||||
typedef psa_status_t (*psa_drv_se_destroy_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
psa_key_slot_number_t key_slot);
|
||||
|
||||
/**
|
||||
* \brief A function that exports a secure element key in binary format
|
||||
@ -743,6 +1025,7 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
||||
* `psa_export_key()` does. Refer to the
|
||||
* documentation of `psa_export_key()` for the format for each key type.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key Slot whose content is to be exported. This must
|
||||
* be an occupied key slot.
|
||||
* \param[out] p_data Buffer where the key data is to be written.
|
||||
@ -756,9 +1039,10 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
|
||||
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key,
|
||||
uint8_t *p_data,
|
||||
size_t data_size,
|
||||
size_t *p_data_length);
|
||||
@ -767,39 +1051,52 @@ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
|
||||
* \brief A function that generates a symmetric or asymmetric key on a secure
|
||||
* element
|
||||
*
|
||||
* If \p type is asymmetric (`#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) == 1`),
|
||||
* the public component of the generated key will be placed in `p_pubkey_out`.
|
||||
* The format of the public key information will match the format specified for
|
||||
* the psa_export_key() function for the key type.
|
||||
* If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1),
|
||||
* the driver may export the public key at the time of generation,
|
||||
* in the format documented for psa_export_public_key() by writing it
|
||||
* to the \p pubkey buffer.
|
||||
* This is optional, intended for secure elements that output the
|
||||
* public key at generation time and that cannot export the public key
|
||||
* later. Drivers that do not need this feature should leave
|
||||
* \p *pubkey_length set to 0 and should
|
||||
* implement the psa_drv_key_management_t::p_export_public function.
|
||||
* Some implementations do not support this feature, in which case
|
||||
* \p pubkey is \c NULL and \p pubkey_size is 0.
|
||||
*
|
||||
* \param[in] key_slot Slot where the generated key will be placed
|
||||
* \param[in] type The type of the key to be generated
|
||||
* \param[in] usage The prescribed usage of the generated key
|
||||
* Note: Not all Secure Elements support the same
|
||||
* restrictions that PSA Crypto does (and vice versa).
|
||||
* Driver developers should endeavor to match the
|
||||
* usages as close as possible.
|
||||
* \param[in] bits The size in bits of the key to be generated.
|
||||
* \param[in] extra Extra parameters for key generation. The
|
||||
* interpretation of this parameter should match the
|
||||
* interpretation in the `extra` parameter is the
|
||||
* `psa_generate_key` function
|
||||
* \param[in] extra_size The size in bytes of the \p extra buffer
|
||||
* \param[out] p_pubkey_out The buffer where the public key information will
|
||||
* be placed
|
||||
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer
|
||||
* \param[out] p_pubkey_length Upon successful completion, will contain the
|
||||
* size of the data placed in `p_pubkey_out`.
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param key_slot Slot where the key will be stored.
|
||||
* This must be a valid slot for a key of the
|
||||
* chosen type. It must be unoccupied.
|
||||
* \param[in] attributes The key attributes, including the lifetime,
|
||||
* the key type and size, and the usage policy.
|
||||
* Drivers can call psa_get_key_lifetime(),
|
||||
* psa_get_key_type(), psa_get_key_bits(),
|
||||
* psa_get_key_usage_flags() and
|
||||
* psa_get_key_algorithm() to access this
|
||||
* information.
|
||||
* \param[out] pubkey A buffer where the driver can write the
|
||||
* public key, when generating an asymmetric
|
||||
* key pair.
|
||||
* This is \c NULL when generating a symmetric
|
||||
* key or if the core does not support
|
||||
* exporting the public key at generation time.
|
||||
* \param pubkey_size The size of the `pubkey` buffer in bytes.
|
||||
* This is 0 when generating a symmetric
|
||||
* key or if the core does not support
|
||||
* exporting the public key at generation time.
|
||||
* \param[out] pubkey_length On entry, this is always 0.
|
||||
* On success, the number of bytes written to
|
||||
* \p pubkey. If this is 0 or unchanged on return,
|
||||
* the core will not read the \p pubkey buffer,
|
||||
* and will instead call the driver's
|
||||
* psa_drv_key_management_t::p_export_public
|
||||
* function to export the public key when needed.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot,
|
||||
psa_key_type_t type,
|
||||
psa_key_usage_t usage,
|
||||
size_t bits,
|
||||
const void *extra,
|
||||
size_t extra_size,
|
||||
uint8_t *p_pubkey_out,
|
||||
size_t pubkey_out_size,
|
||||
size_t *p_pubkey_length);
|
||||
typedef psa_status_t (*psa_drv_se_generate_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length);
|
||||
|
||||
/**
|
||||
* \brief A struct containing all of the function pointers needed to for secure
|
||||
@ -811,6 +1108,10 @@ typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot
|
||||
* If one of the functions is not implemented, it should be set to NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Function that allocates a slot for a key. */
|
||||
psa_drv_se_allocate_key_t p_allocate;
|
||||
/** Function that checks the validity of a slot for a key. */
|
||||
psa_drv_se_validate_slot_number_t p_validate_slot_number;
|
||||
/** Function that performs a key import operation */
|
||||
psa_drv_se_import_key_t p_import;
|
||||
/** Function that performs a generation */
|
||||
@ -819,6 +1120,8 @@ typedef struct {
|
||||
psa_drv_se_destroy_key_t p_destroy;
|
||||
/** Function that performs a key export operation */
|
||||
psa_drv_se_export_key_t p_export;
|
||||
/** Function that performs a public key export operation */
|
||||
psa_drv_se_export_key_t p_export_public;
|
||||
} psa_drv_se_key_management_t;
|
||||
|
||||
/**@}*/
|
||||
@ -875,15 +1178,17 @@ typedef struct {
|
||||
/** \brief A function that Sets up a secure element key derivation operation by
|
||||
* specifying the algorithm and the source key sot
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] kdf_alg The algorithm to be used for the key derivation
|
||||
* \param[in] souce_key The key to be used as the source material for the
|
||||
* key derivation
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] kdf_alg The algorithm to be used for the key derivation
|
||||
* \param[in] source_key The key to be used as the source material for
|
||||
* the key derivation
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_algorithm_t kdf_alg,
|
||||
psa_key_slot_number_t source_key);
|
||||
|
||||
@ -894,7 +1199,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
||||
* expeced that this function may be called multiple times for the same
|
||||
* operation, each with a different algorithm-specific `collateral_id`
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] collateral_id An ID for the collateral being provided
|
||||
* \param[in] p_collateral A buffer containing the collateral data
|
||||
@ -902,7 +1207,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context,
|
||||
uint32_t collateral_id,
|
||||
const uint8_t *p_collateral,
|
||||
size_t collateral_size);
|
||||
@ -910,14 +1215,14 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
|
||||
/** \brief A function that performs the final secure element key derivation
|
||||
* step and place the generated key material in a slot
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] dest_key The slot where the generated key material
|
||||
* should be placed
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context,
|
||||
psa_key_slot_number_t dest_key);
|
||||
|
||||
/** \brief A function that performs the final step of a secure element key
|
||||
@ -931,7 +1236,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length);
|
||||
@ -961,6 +1266,113 @@ typedef struct {
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup se_registration Secure element driver registration
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/** A structure containing pointers to all the entry points of a
|
||||
* secure element driver.
|
||||
*
|
||||
* Future versions of this specification may add extra substructures at
|
||||
* the end of this structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The version of the driver HAL that this driver implements.
|
||||
* This is a protection against loading driver binaries built against
|
||||
* a different version of this specification.
|
||||
* Use #PSA_DRV_SE_HAL_VERSION.
|
||||
*/
|
||||
uint32_t hal_version;
|
||||
|
||||
/** The size of the driver's persistent data in bytes.
|
||||
*
|
||||
* This can be 0 if the driver does not need persistent data.
|
||||
*
|
||||
* See the documentation of psa_drv_se_context_t::persistent_data
|
||||
* for more information about why and how a driver can use
|
||||
* persistent data.
|
||||
*/
|
||||
size_t persistent_data_size;
|
||||
|
||||
/** The driver initialization function.
|
||||
*
|
||||
* This function is called once during the initialization of the
|
||||
* PSA Cryptography subsystem, before any other function of the
|
||||
* driver is called. If this function returns a failure status,
|
||||
* the driver will be unusable, at least until the next system reset.
|
||||
*
|
||||
* If this field is \c NULL, it is equivalent to a function that does
|
||||
* nothing and returns #PSA_SUCCESS.
|
||||
*/
|
||||
psa_drv_se_init_t p_init;
|
||||
|
||||
const psa_drv_se_key_management_t *key_management;
|
||||
const psa_drv_se_mac_t *mac;
|
||||
const psa_drv_se_cipher_t *cipher;
|
||||
const psa_drv_se_aead_t *aead;
|
||||
const psa_drv_se_asymmetric_t *asymmetric;
|
||||
const psa_drv_se_key_derivation_t *derivation;
|
||||
} psa_drv_se_t;
|
||||
|
||||
/** The current version of the secure element driver HAL.
|
||||
*/
|
||||
/* 0.0.0 patchlevel 5 */
|
||||
#define PSA_DRV_SE_HAL_VERSION 0x00000005
|
||||
|
||||
/** Register an external cryptoprocessor (secure element) driver.
|
||||
*
|
||||
* This function is only intended to be used by driver code, not by
|
||||
* application code. In implementations with separation between the
|
||||
* PSA cryptography module and applications, this function should
|
||||
* only be available to callers that run in the same memory space as
|
||||
* the cryptography module, and should not be exposed to applications
|
||||
* running in a different memory space.
|
||||
*
|
||||
* This function may be called before psa_crypto_init(). It is
|
||||
* implementation-defined whether this function may be called
|
||||
* after psa_crypto_init().
|
||||
*
|
||||
* \note Implementations store metadata about keys including the lifetime
|
||||
* value. Therefore, from one instantiation of the PSA Cryptography
|
||||
* library to the next one, if there is a key in storage with a certain
|
||||
* lifetime value, you must always register the same driver (or an
|
||||
* updated version that communicates with the same secure element)
|
||||
* with the same lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value through which this driver will
|
||||
* be exposed to applications.
|
||||
* The values #PSA_KEY_LIFETIME_VOLATILE and
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT are reserved and
|
||||
* may not be used for drivers. Implementations
|
||||
* may reserve other values.
|
||||
* \param[in] methods The method table of the driver. This structure must
|
||||
* remain valid for as long as the cryptography
|
||||
* module keeps running. It is typically a global
|
||||
* constant.
|
||||
*
|
||||
* \return PSA_SUCCESS
|
||||
* The driver was successfully registered. Applications can now
|
||||
* use \p lifetime to access keys through the methods passed to
|
||||
* this function.
|
||||
* \return PSA_ERROR_BAD_STATE
|
||||
* This function was called after the initialization of the
|
||||
* cryptography module, and this implementation does not support
|
||||
* driver registration at this stage.
|
||||
* \return PSA_ERROR_ALREADY_EXISTS
|
||||
* There is already a registered driver for this value of \p lifetime.
|
||||
* \return PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p lifetime is a reserved value.
|
||||
* \return PSA_ERROR_NOT_SUPPORTED
|
||||
* `methods->hal_version` is not supported by this implementation.
|
||||
* \return PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \return PSA_ERROR_NOT_PERMITTED
|
||||
*/
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t *methods);
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -53,6 +53,9 @@
|
||||
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
|
||||
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
|
||||
|
||||
#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
|
||||
(((length) + (block_size) - 1) / (block_size) * (block_size))
|
||||
|
||||
/** The size of the output of psa_hash_finish(), in bytes.
|
||||
*
|
||||
* This is also the hash size that psa_hash_verify() expects.
|
||||
@ -269,7 +272,7 @@
|
||||
* \param key_type The type of the MAC key.
|
||||
* \param key_bits The size of the MAC key in bits.
|
||||
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_MAC(alg) is true).
|
||||
* #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
*
|
||||
* \return The MAC size for the specified algorithm with
|
||||
* the specified key parameters.
|
||||
@ -294,7 +297,7 @@
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(alg) is true).
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param plaintext_length Size of the plaintext in bytes.
|
||||
*
|
||||
* \return The AEAD ciphertext size for the specified
|
||||
@ -318,7 +321,7 @@
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(alg) is true).
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param ciphertext_length Size of the plaintext in bytes.
|
||||
*
|
||||
* \return The AEAD ciphertext size for the specified
|
||||
@ -330,7 +333,81 @@
|
||||
*/
|
||||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
|
||||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
|
||||
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
0)
|
||||
|
||||
/** A sufficient output buffer size for psa_aead_update().
|
||||
*
|
||||
* If the size of the output buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_update() will not fail due to an
|
||||
* insufficient buffer size. The actual size of the output may be smaller
|
||||
* in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param input_length Size of the input in bytes.
|
||||
*
|
||||
* \return A sufficient output buffer size for the specified
|
||||
* algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
/* For all the AEAD modes defined in this specification, it is possible
|
||||
* to emit output without delay. However, hardware may not always be
|
||||
* capable of this. So for modes based on a block cipher, allow the
|
||||
* implementation to delay the output until it has a full block. */
|
||||
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
|
||||
(input_length))
|
||||
|
||||
/** A sufficient ciphertext buffer size for psa_aead_finish().
|
||||
*
|
||||
* If the size of the ciphertext buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_finish() will not fail due to an
|
||||
* insufficient ciphertext buffer size. The actual size of the output may
|
||||
* be smaller in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \return A sufficient ciphertext buffer size for the
|
||||
* specified algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
|
||||
0)
|
||||
|
||||
/** A sufficient plaintext buffer size for psa_aead_verify().
|
||||
*
|
||||
* If the size of the plaintext buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_verify() will not fail due to an
|
||||
* insufficient plaintext buffer size. The actual size of the output may
|
||||
* be smaller in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \return A sufficient plaintext buffer size for the
|
||||
* specified algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
|
||||
0)
|
||||
|
||||
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
|
||||
@ -349,9 +426,9 @@
|
||||
#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
|
||||
(PSA_BITS_TO_BYTES(curve_bits) * 2)
|
||||
|
||||
/** Safe signature buffer size for psa_asymmetric_sign().
|
||||
/** Sufficient signature buffer size for psa_asymmetric_sign().
|
||||
*
|
||||
* This macro returns a safe buffer size for a signature using a key
|
||||
* This macro returns a sufficient buffer size for a signature using a key
|
||||
* of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the signature may be smaller
|
||||
* (some algorithms produce a variable-size signature).
|
||||
@ -370,7 +447,7 @@
|
||||
* psa_asymmetric_sign() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
@ -380,9 +457,9 @@
|
||||
PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
|
||||
((void)alg, 0))
|
||||
|
||||
/** Safe output buffer size for psa_asymmetric_encrypt().
|
||||
/** Sufficient output buffer size for psa_asymmetric_encrypt().
|
||||
*
|
||||
* This macro returns a safe buffer size for a ciphertext produced using
|
||||
* This macro returns a sufficient buffer size for a ciphertext produced using
|
||||
* a key of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the ciphertext may be smaller, depending
|
||||
* on the algorithm.
|
||||
@ -401,7 +478,7 @@
|
||||
* psa_asymmetric_encrypt() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
@ -411,9 +488,9 @@
|
||||
((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
|
||||
0)
|
||||
|
||||
/** Safe output buffer size for psa_asymmetric_decrypt().
|
||||
/** Sufficient output buffer size for psa_asymmetric_decrypt().
|
||||
*
|
||||
* This macro returns a safe buffer size for a ciphertext produced using
|
||||
* This macro returns a sufficient buffer size for a ciphertext produced using
|
||||
* a key of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the ciphertext may be smaller, depending
|
||||
* on the algorithm.
|
||||
@ -432,7 +509,7 @@
|
||||
* psa_asymmetric_decrypt() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
@ -491,7 +568,7 @@
|
||||
* overapproximated as 9 half-size INTEGERS;
|
||||
* - 7 bytes for the public exponent.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14)
|
||||
|
||||
/* Maximum size of the export encoding of a DSA public key.
|
||||
@ -529,7 +606,7 @@
|
||||
* - 3 full-size INTEGERs (p, g, y);
|
||||
* - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75)
|
||||
|
||||
/* Maximum size of the export encoding of an ECC public key.
|
||||
@ -549,10 +626,10 @@
|
||||
*
|
||||
* An ECC key pair is represented by the secret value.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_BITS_TO_BYTES(key_bits))
|
||||
|
||||
/** Safe output buffer size for psa_export_key() or psa_export_public_key().
|
||||
/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
|
||||
*
|
||||
* This macro returns a compile-time constant if its arguments are
|
||||
* compile-time constants.
|
||||
@ -564,32 +641,36 @@
|
||||
* The following code illustrates how to allocate enough memory to export
|
||||
* a key by querying the key type and size at runtime.
|
||||
* \code{c}
|
||||
* psa_key_type_t key_type;
|
||||
* size_t key_bits;
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* psa_status_t status;
|
||||
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||
* status = psa_get_key_attributes(key, &attributes);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* psa_key_type_t key_type = psa_get_key_type(&attributes);
|
||||
* size_t key_bits = psa_get_key_bits(&attributes);
|
||||
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
|
||||
* unsigned char *buffer = malloc(buffer_size);
|
||||
* if (buffer != NULL) handle_error(...);
|
||||
* psa_reset_key_attributes(&attributes);
|
||||
* uint8_t *buffer = malloc(buffer_size);
|
||||
* if (buffer == NULL) handle_error(...);
|
||||
* size_t buffer_length;
|
||||
* status = psa_export_key(key, buffer, buffer_size, &buffer_length);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* \endcode
|
||||
*
|
||||
* For psa_export_public_key(), calculate the buffer size from the
|
||||
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR
|
||||
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
|
||||
* to convert a key pair type to the corresponding public key type.
|
||||
* \code{c}
|
||||
* psa_key_type_t key_type;
|
||||
* size_t key_bits;
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* psa_status_t status;
|
||||
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||
* status = psa_get_key_attributes(key, &attributes);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(key_type);
|
||||
* psa_key_type_t key_type = psa_get_key_type(&attributes);
|
||||
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
|
||||
* size_t key_bits = psa_get_key_bits(&attributes);
|
||||
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
|
||||
* unsigned char *buffer = malloc(buffer_size);
|
||||
* if (buffer != NULL) handle_error(...);
|
||||
* psa_reset_key_attributes(&attributes);
|
||||
* uint8_t *buffer = malloc(buffer_size);
|
||||
* if (buffer == NULL) handle_error(...);
|
||||
* size_t buffer_length;
|
||||
* status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
@ -603,18 +684,18 @@
|
||||
* psa_asymmetric_sign() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_KEYPAIR ? PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_KEYPAIR ? PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_KEYPAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
0)
|
||||
|
||||
|
@ -12,6 +12,26 @@
|
||||
* In implementations with isolation between the application and the
|
||||
* cryptography module, it is expected that the front-end and the back-end
|
||||
* would have different versions of this file.
|
||||
*
|
||||
* <h3>Design notes about multipart operation structures</h3>
|
||||
*
|
||||
* Each multipart operation structure contains a `psa_algorithm_t alg`
|
||||
* field which indicates which specific algorithm the structure is for.
|
||||
* When the structure is not in use, `alg` is 0. Most of the structure
|
||||
* consists of a union which is discriminated by `alg`.
|
||||
*
|
||||
* Note that when `alg` is 0, the content of other fields is undefined.
|
||||
* In particular, it is not guaranteed that a freshly-initialized structure
|
||||
* is all-zero: we initialize structures to something like `{0, 0}`, which
|
||||
* is only guaranteed to initializes the first member of the union;
|
||||
* GCC and Clang initialize the whole structure to 0 (at the time of writing),
|
||||
* but MSVC and CompCert don't.
|
||||
*
|
||||
* In Mbed Crypto, multipart operation structures live independently from
|
||||
* the key. This allows Mbed Crypto to free the key objects when destroying
|
||||
* a key slot. If a multipart operation needs to remember the key after
|
||||
* the setup function returns, the operation structure needs to contain a
|
||||
* copy of the key.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2018, ARM Limited, All Rights Reserved
|
||||
@ -35,6 +55,10 @@
|
||||
#ifndef PSA_CRYPTO_STRUCT_H
|
||||
#define PSA_CRYPTO_STRUCT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
|
||||
* in each of its header files. */
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
@ -152,6 +176,27 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
|
||||
return( v );
|
||||
}
|
||||
|
||||
struct psa_aead_operation_s
|
||||
{
|
||||
psa_algorithm_t alg;
|
||||
unsigned int key_set : 1;
|
||||
unsigned int iv_set : 1;
|
||||
uint8_t iv_size;
|
||||
uint8_t block_size;
|
||||
union
|
||||
{
|
||||
unsigned dummy; /* Enable easier initializing of the union. */
|
||||
mbedtls_cipher_context_t cipher;
|
||||
} ctx;
|
||||
};
|
||||
|
||||
#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, {0}}
|
||||
static inline struct psa_aead_operation_s psa_aead_operation_init( void )
|
||||
{
|
||||
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
typedef struct
|
||||
{
|
||||
@ -165,62 +210,68 @@ typedef struct
|
||||
#endif
|
||||
uint8_t offset_in_block;
|
||||
uint8_t block_number;
|
||||
} psa_hkdf_generator_t;
|
||||
unsigned int state : 2;
|
||||
unsigned int info_set : 1;
|
||||
} psa_hkdf_key_derivation_t;
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
typedef struct psa_tls12_prf_generator_s
|
||||
typedef enum
|
||||
{
|
||||
/* The TLS 1.2 PRF uses the key for each HMAC iteration,
|
||||
* hence we must store it for the lifetime of the generator.
|
||||
* This is different from HKDF, where the key is only used
|
||||
* in the extraction phase, but not during expansion. */
|
||||
unsigned char *key;
|
||||
size_t key_len;
|
||||
|
||||
/* `A(i) + seed` in the notation of RFC 5246, Sect. 5 */
|
||||
uint8_t *Ai_with_seed;
|
||||
size_t Ai_with_seed_len;
|
||||
|
||||
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
|
||||
uint8_t output_block[PSA_HASH_MAX_SIZE];
|
||||
TLS12_PRF_STATE_INIT, /* no input provided */
|
||||
TLS12_PRF_STATE_SEED_SET, /* seed has been set */
|
||||
TLS12_PRF_STATE_KEY_SET, /* key has been set */
|
||||
TLS12_PRF_STATE_LABEL_SET, /* label has been set */
|
||||
TLS12_PRF_STATE_OUTPUT /* output has been started */
|
||||
} psa_tls12_prf_key_derivation_state_t;
|
||||
|
||||
typedef struct psa_tls12_prf_key_derivation_s
|
||||
{
|
||||
#if PSA_HASH_MAX_SIZE > 0xff
|
||||
#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
|
||||
#endif
|
||||
|
||||
/* Indicates how many bytes in the current HMAC block have
|
||||
* already been read by the user. */
|
||||
uint8_t offset_in_block;
|
||||
* not yet been read by the user. */
|
||||
uint8_t left_in_block;
|
||||
|
||||
/* The 1-based number of the block. */
|
||||
uint8_t block_number;
|
||||
|
||||
} psa_tls12_prf_generator_t;
|
||||
psa_tls12_prf_key_derivation_state_t state;
|
||||
|
||||
uint8_t *seed;
|
||||
size_t seed_length;
|
||||
uint8_t *label;
|
||||
size_t label_length;
|
||||
psa_hmac_internal_data hmac;
|
||||
uint8_t Ai[PSA_HASH_MAX_SIZE];
|
||||
|
||||
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
|
||||
uint8_t output_block[PSA_HASH_MAX_SIZE];
|
||||
} psa_tls12_prf_key_derivation_t;
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
|
||||
struct psa_crypto_generator_s
|
||||
struct psa_key_derivation_s
|
||||
{
|
||||
psa_algorithm_t alg;
|
||||
size_t capacity;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
} buffer;
|
||||
/* Make the union non-empty even with no supported algorithms. */
|
||||
uint8_t dummy;
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
psa_hkdf_generator_t hkdf;
|
||||
psa_tls12_prf_generator_t tls12_prf;
|
||||
psa_hkdf_key_derivation_t hkdf;
|
||||
psa_tls12_prf_key_derivation_t tls12_prf;
|
||||
#endif
|
||||
} ctx;
|
||||
};
|
||||
|
||||
#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
|
||||
static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
|
||||
/* This only zeroes out the first byte in the union, the rest is unspecified. */
|
||||
#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}}
|
||||
static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
|
||||
{
|
||||
const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
|
||||
const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
@ -230,6 +281,7 @@ struct psa_key_policy_s
|
||||
psa_algorithm_t alg;
|
||||
psa_algorithm_t alg2;
|
||||
};
|
||||
typedef struct psa_key_policy_s psa_key_policy_t;
|
||||
|
||||
#define PSA_KEY_POLICY_INIT {0, 0, 0}
|
||||
static inline struct psa_key_policy_s psa_key_policy_init( void )
|
||||
@ -238,4 +290,183 @@ static inline struct psa_key_policy_s psa_key_policy_init( void )
|
||||
return( v );
|
||||
}
|
||||
|
||||
/* The type used internally for key sizes.
|
||||
* Public interfaces use size_t, but internally we use a smaller type. */
|
||||
typedef uint16_t psa_key_bits_t;
|
||||
/* The maximum value of the type used to represent bit-sizes.
|
||||
* This is used to mark an invalid key size. */
|
||||
#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
|
||||
/* The maximum size of a key in bits.
|
||||
* Currently defined as the maximum that can be represented, rounded down
|
||||
* to a whole number of bytes.
|
||||
* This is an uncast value so that it can be used in preprocessor
|
||||
* conditionals. */
|
||||
#define PSA_MAX_KEY_BITS 0xfff8
|
||||
|
||||
/** A mask of flags that can be stored in key attributes.
|
||||
*
|
||||
* This type is also used internally to store flags in slots. Internal
|
||||
* flags are defined in library/psa_crypto_core.h. Internal flags may have
|
||||
* the same value as external flags if they are properly handled during
|
||||
* key creation and in psa_get_key_attributes.
|
||||
*/
|
||||
typedef uint16_t psa_key_attributes_flag_t;
|
||||
|
||||
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
|
||||
( (psa_key_attributes_flag_t) 0x0001 )
|
||||
|
||||
/* A mask of key attribute flags used externally only.
|
||||
* Only meant for internal checks inside the library. */
|
||||
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
|
||||
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
|
||||
0 )
|
||||
|
||||
/* A mask of key attribute flags used both internally and externally.
|
||||
* Currently there aren't any. */
|
||||
#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
|
||||
0 )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
psa_key_type_t type;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_id_t id;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_bits_t bits;
|
||||
psa_key_attributes_flag_t flags;
|
||||
} psa_core_key_attributes_t;
|
||||
|
||||
#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, PSA_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0, 0}
|
||||
|
||||
struct psa_key_attributes_s
|
||||
{
|
||||
psa_core_key_attributes_t core;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
psa_key_slot_number_t slot_number;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
void *domain_parameters;
|
||||
size_t domain_parameters_size;
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
|
||||
#else
|
||||
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
|
||||
#endif
|
||||
|
||||
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
|
||||
{
|
||||
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
|
||||
psa_key_id_t id)
|
||||
{
|
||||
attributes->core.id = id;
|
||||
if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
|
||||
}
|
||||
|
||||
static inline psa_key_id_t psa_get_key_id(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.id );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
attributes->core.lifetime = lifetime;
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
{
|
||||
#ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
|
||||
attributes->core.id.key_id = 0;
|
||||
attributes->core.id.owner = 0;
|
||||
#else
|
||||
attributes->core.id = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline psa_key_lifetime_t psa_get_key_lifetime(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.lifetime );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
|
||||
psa_key_usage_t usage_flags)
|
||||
{
|
||||
attributes->core.policy.usage = usage_flags;
|
||||
}
|
||||
|
||||
static inline psa_key_usage_t psa_get_key_usage_flags(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.usage );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
attributes->core.policy.alg = alg;
|
||||
}
|
||||
|
||||
static inline psa_algorithm_t psa_get_key_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.alg );
|
||||
}
|
||||
|
||||
/* This function is declared in crypto_extra.h, which comes after this
|
||||
* header file, but we need the function here, so repeat the declaration. */
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type)
|
||||
{
|
||||
if( attributes->domain_parameters == NULL )
|
||||
{
|
||||
/* Common case: quick path */
|
||||
attributes->core.type = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the bigger function to free the old domain paramteres.
|
||||
* Ignore any errors which may arise due to type requiring
|
||||
* non-default domain parameters, since this function can't
|
||||
* report errors. */
|
||||
(void) psa_set_key_domain_parameters( attributes, type, NULL, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static inline psa_key_type_t psa_get_key_type(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.type );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
|
||||
size_t bits)
|
||||
{
|
||||
if( bits > PSA_MAX_KEY_BITS )
|
||||
attributes->core.bits = PSA_KEY_BITS_TOO_LARGE;
|
||||
else
|
||||
attributes->core.bits = (psa_key_bits_t) bits;
|
||||
}
|
||||
|
||||
static inline size_t psa_get_key_bits(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.bits );
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_STRUCT_H */
|
||||
|
@ -45,9 +45,9 @@
|
||||
* \brief Function return status.
|
||||
*
|
||||
* This is either #PSA_SUCCESS (which is zero), indicating success,
|
||||
* or a nonzero value indicating that an error occurred. Errors are
|
||||
* encoded as one of the \c PSA_ERROR_xxx values defined here.
|
||||
* If #PSA_SUCCESS is already defined, it means that #psa_status_t
|
||||
* or a small negative value indicating that an error occurred. Errors are
|
||||
* encoded as one of the \c PSA_ERROR_xxx values defined here. */
|
||||
/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
|
||||
* is also defined in an external header, so prevent its multiple
|
||||
* definition.
|
||||
*/
|
||||
@ -68,6 +68,9 @@ typedef uint32_t psa_key_type_t;
|
||||
/** The type of PSA elliptic curve identifiers. */
|
||||
typedef uint16_t psa_ecc_curve_t;
|
||||
|
||||
/** The type of PSA Diffie-Hellman group identifiers. */
|
||||
typedef uint16_t psa_dh_group_t;
|
||||
|
||||
/** \brief Encoding of a cryptographic algorithm.
|
||||
*
|
||||
* For algorithms that can be applied to multiple key types, this type
|
||||
@ -85,10 +88,30 @@ typedef uint32_t psa_algorithm_t;
|
||||
*/
|
||||
|
||||
/** Encoding of key lifetimes.
|
||||
*
|
||||
* The lifetime of a key indicates where it is stored and what system actions
|
||||
* may create and destroy it.
|
||||
*
|
||||
* Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are automatically
|
||||
* destroyed when the application terminates or on a power reset.
|
||||
*
|
||||
* Keys with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE are said
|
||||
* to be _persistent_.
|
||||
* Persistent keys are preserved if the application or the system restarts.
|
||||
* Persistent keys have a key identifier of type #psa_key_id_t.
|
||||
* The application can call psa_open_key() to open a persistent key that
|
||||
* it created previously.
|
||||
*/
|
||||
typedef uint32_t psa_key_lifetime_t;
|
||||
|
||||
/** Encoding of identifiers of persistent keys.
|
||||
*
|
||||
* - Applications may freely choose key identifiers in the range
|
||||
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
|
||||
* - Implementations may define additional key identifiers in the range
|
||||
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
|
||||
* - 0 is reserved as an invalid key identifier.
|
||||
* - Key identifiers outside these ranges are reserved for future use.
|
||||
*/
|
||||
/* Implementation-specific quirk: The Mbed Crypto library can be built as
|
||||
* part of a multi-client service that exposes the PSA Crypto API in each
|
||||
@ -97,6 +120,7 @@ typedef uint32_t psa_key_lifetime_t;
|
||||
* psa_key_id_t in crypto_platform.h instead of here. */
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
|
||||
typedef uint32_t psa_key_id_t;
|
||||
#define PSA_KEY_ID_INIT 0
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
@ -110,4 +134,137 @@ typedef uint32_t psa_key_usage_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup attributes Key attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The type of a structure containing key attributes.
|
||||
*
|
||||
* This is an opaque structure that can represent the metadata of a key
|
||||
* object. Metadata that can be stored in attributes includes:
|
||||
* - The location of the key in storage, indicated by its key identifier
|
||||
* and its lifetime.
|
||||
* - The key's policy, comprising usage flags and a specification of
|
||||
* the permitted algorithm(s).
|
||||
* - Information about the key itself: the key type and its size.
|
||||
* - Implementations may define additional attributes.
|
||||
*
|
||||
* The actual key material is not considered an attribute of a key.
|
||||
* Key attributes do not contain information that is generally considered
|
||||
* highly confidential.
|
||||
*
|
||||
* An attribute structure can be a simple data structure where each function
|
||||
* `psa_set_key_xxx` sets a field and the corresponding function
|
||||
* `psa_get_key_xxx` retrieves the value of the corresponding field.
|
||||
* However, implementations may report values that are equivalent to the
|
||||
* original one, but have a different encoding. For example, an
|
||||
* implementation may use a more compact representation for types where
|
||||
* many bit-patterns are invalid or not supported, and store all values
|
||||
* that it does not support as a special marker value. In such an
|
||||
* implementation, after setting an invalid value, the corresponding
|
||||
* get function returns an invalid value which may not be the one that
|
||||
* was originally stored.
|
||||
*
|
||||
* An attribute structure may contain references to auxiliary resources,
|
||||
* for example pointers to allocated memory or indirect references to
|
||||
* pre-calculated values. In order to free such resources, the application
|
||||
* must call psa_reset_key_attributes(). As an exception, calling
|
||||
* psa_reset_key_attributes() on an attribute structure is optional if
|
||||
* the structure has only been modified by the following functions
|
||||
* since it was initialized or last reset with psa_reset_key_attributes():
|
||||
* - psa_set_key_id()
|
||||
* - psa_set_key_lifetime()
|
||||
* - psa_set_key_type()
|
||||
* - psa_set_key_bits()
|
||||
* - psa_set_key_usage_flags()
|
||||
* - psa_set_key_algorithm()
|
||||
*
|
||||
* Before calling any function on a key attribute structure, the application
|
||||
* must initialize it by any of the following means:
|
||||
* - Set the structure to all-bits-zero, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes;
|
||||
* memset(&attributes, 0, sizeof(attributes));
|
||||
* \endcode
|
||||
* - Initialize the structure to logical zero values, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes = {0};
|
||||
* \endcode
|
||||
* - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
|
||||
* for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* \endcode
|
||||
* - Assign the result of the function psa_key_attributes_init()
|
||||
* to the structure, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes;
|
||||
* attributes = psa_key_attributes_init();
|
||||
* \endcode
|
||||
*
|
||||
* A freshly initialized attribute structure contains the following
|
||||
* values:
|
||||
*
|
||||
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
|
||||
* - key identifier: unspecified.
|
||||
* - type: \c 0.
|
||||
* - key size: \c 0.
|
||||
* - usage flags: \c 0.
|
||||
* - algorithm: \c 0.
|
||||
*
|
||||
* A typical sequence to create a key is as follows:
|
||||
* -# Create and initialize an attribute structure.
|
||||
* -# If the key is persistent, call psa_set_key_id().
|
||||
* Also call psa_set_key_lifetime() to place the key in a non-default
|
||||
* location.
|
||||
* -# Set the key policy with psa_set_key_usage_flags() and
|
||||
* psa_set_key_algorithm().
|
||||
* -# Set the key type with psa_set_key_type().
|
||||
* Skip this step if copying an existing key with psa_copy_key().
|
||||
* -# When generating a random key with psa_generate_key() or deriving a key
|
||||
* with psa_key_derivation_output_key(), set the desired key size with
|
||||
* psa_set_key_bits().
|
||||
* -# Call a key creation function: psa_import_key(), psa_generate_key(),
|
||||
* psa_key_derivation_output_key() or psa_copy_key(). This function reads
|
||||
* the attribute structure, creates a key with these attributes, and
|
||||
* outputs a handle to the newly created key.
|
||||
* -# The attribute structure is now no longer necessary.
|
||||
* You may call psa_reset_key_attributes(), although this is optional
|
||||
* with the workflow presented here because the attributes currently
|
||||
* defined in this specification do not require any additional resources
|
||||
* beyond the structure itself.
|
||||
*
|
||||
* A typical sequence to query a key's attributes is as follows:
|
||||
* -# Call psa_get_key_attributes().
|
||||
* -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
|
||||
* you are interested in.
|
||||
* -# Call psa_reset_key_attributes() to free any resources that may be
|
||||
* used by the attribute structure.
|
||||
*
|
||||
* Once a key has been created, it is impossible to change its attributes.
|
||||
*/
|
||||
typedef struct psa_key_attributes_s psa_key_attributes_t;
|
||||
|
||||
|
||||
#ifndef __DOXYGEN_ONLY__
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* Mbed Crypto defines this type in crypto_types.h because it is also
|
||||
* visible to applications through an implementation-specific extension.
|
||||
* For the PSA Cryptography specification, this type is only visible
|
||||
* via crypto_se_driver.h. */
|
||||
typedef uint64_t psa_key_slot_number_t;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
#endif /* !__DOXYGEN_ONLY__ */
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup derivation Key derivation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Encoding of the step of a key derivation. */
|
||||
typedef uint16_t psa_key_derivation_step_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* PSA_CRYPTO_TYPES_H */
|
||||
|
@ -105,9 +105,13 @@
|
||||
* descriptions for permitted sequencing of functions.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate
|
||||
* that a key slot is occupied when it needs to be free or vice versa,
|
||||
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable. */
|
||||
* that a key either exists or not,
|
||||
* but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate that a
|
||||
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
|
||||
* instead. */
|
||||
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
|
||||
|
||||
/** The parameters passed to the function are invalid.
|
||||
@ -115,12 +119,7 @@
|
||||
* Implementations may return this error any time a parameter or
|
||||
* combination of parameters are recognized as invalid.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate
|
||||
* that a key slot is occupied when it needs to be free or vice versa,
|
||||
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable.
|
||||
*
|
||||
* Implementation shall not return this error code to indicate that a
|
||||
* Implementations shall not return this error code to indicate that a
|
||||
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
|
||||
* instead.
|
||||
*/
|
||||
@ -162,7 +161,7 @@
|
||||
*
|
||||
* This error indicates that some persistent storage is corrupted.
|
||||
* It should not be used for a corruption of volatile memory
|
||||
* (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
|
||||
* (use #PSA_ERROR_CORRUPTION_DETECTED), for a communication error
|
||||
* between the cryptoprocessor and its external storage (use
|
||||
* #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
|
||||
* in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
|
||||
@ -175,7 +174,7 @@
|
||||
* the global integrity of the keystore. Depending on the global
|
||||
* integrity guarantees offered by the implementation, access to other
|
||||
* data may or may not fail even if the data is still readable but
|
||||
* its integrity canont be guaranteed.
|
||||
* its integrity cannot be guaranteed.
|
||||
*
|
||||
* Implementations should only use this error code to report a
|
||||
* permanent storage corruption. However application writers should
|
||||
@ -218,7 +217,7 @@
|
||||
* This error indicates an attack against the application. Implementations
|
||||
* shall not return this error code as a consequence of the behavior of
|
||||
* the application itself. */
|
||||
#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)-151)
|
||||
#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
|
||||
|
||||
/** There is not enough entropy to generate random data needed
|
||||
* for the requested action.
|
||||
@ -269,7 +268,7 @@
|
||||
* to read from a resource. */
|
||||
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
|
||||
|
||||
/** The key handle is not valid.
|
||||
/** The key handle is not valid. See also :ref:\`key-handles\`.
|
||||
*/
|
||||
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
|
||||
|
||||
@ -324,7 +323,7 @@
|
||||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
|
||||
/** Whether a key type is a key pair containing a private part and a public
|
||||
* part. */
|
||||
#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_IS_KEY_PAIR(type) \
|
||||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
|
||||
/** The key pair type corresponding to a public key type.
|
||||
*
|
||||
@ -336,7 +335,7 @@
|
||||
* If \p type is not a public key or a key pair,
|
||||
* the return value is undefined.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
|
||||
#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \
|
||||
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||
/** The public key type corresponding to a key pair type.
|
||||
*
|
||||
@ -348,7 +347,7 @@
|
||||
* If \p type is not a public key or a key pair,
|
||||
* the return value is undefined.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) \
|
||||
((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||
|
||||
/** Raw data.
|
||||
@ -374,7 +373,7 @@
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000)
|
||||
|
||||
/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
|
||||
/** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher.
|
||||
*
|
||||
* The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
|
||||
* 32 bytes (AES-256).
|
||||
@ -392,7 +391,7 @@
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002)
|
||||
|
||||
/** Key for an cipher, AEAD or MAC algorithm based on the
|
||||
/** Key for a cipher, AEAD or MAC algorithm based on the
|
||||
* Camellia block cipher. */
|
||||
#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003)
|
||||
|
||||
@ -402,40 +401,41 @@
|
||||
* legacy protocols. */
|
||||
#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004)
|
||||
|
||||
/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm.
|
||||
*
|
||||
* ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539.
|
||||
*
|
||||
* Implementations must support 12-byte nonces, may support 8-byte nonces,
|
||||
* and should reject other sizes.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t)0x40000005)
|
||||
|
||||
/** RSA public key. */
|
||||
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000)
|
||||
/** RSA key pair (private and public key). */
|
||||
#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000)
|
||||
#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x70010000)
|
||||
/** Whether a key type is an RSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_RSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
/** DSA public key. */
|
||||
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
|
||||
/** DSA key pair (private and public key). */
|
||||
#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000)
|
||||
/** Whether a key type is an DSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
|
||||
#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000)
|
||||
#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x70030000)
|
||||
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
|
||||
/** Elliptic curve key pair. */
|
||||
#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
|
||||
(PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
|
||||
#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
|
||||
(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve))
|
||||
/** Elliptic curve public key. */
|
||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
|
||||
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
|
||||
|
||||
/** Whether a key type is an elliptic curve key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_ECC(type) \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
|
||||
~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
|
||||
/** Whether a key type is an elliptic curve key pair. */
|
||||
#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
|
||||
PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
|
||||
PSA_KEY_TYPE_ECC_KEY_PAIR_BASE)
|
||||
/** Whether a key type is an elliptic curve public key. */
|
||||
#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
|
||||
@ -480,9 +480,61 @@
|
||||
#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a)
|
||||
#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b)
|
||||
#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c)
|
||||
/** Curve25519.
|
||||
*
|
||||
* This is the curve defined in Bernstein et al.,
|
||||
* _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006.
|
||||
* The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve.
|
||||
*/
|
||||
#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
|
||||
/** Curve448
|
||||
*
|
||||
* This is the curve defined in Hamburg,
|
||||
* _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
|
||||
* The algorithm #PSA_ALG_ECDH performs X448 when used with this curve.
|
||||
*/
|
||||
#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
|
||||
|
||||
#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000)
|
||||
#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x70040000)
|
||||
#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff)
|
||||
/** Diffie-Hellman key pair. */
|
||||
#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \
|
||||
(PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group))
|
||||
/** Diffie-Hellman public key. */
|
||||
#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \
|
||||
(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group))
|
||||
|
||||
/** Whether a key type is a Diffie-Hellman key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DH(type) \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
|
||||
~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
|
||||
/** Whether a key type is a Diffie-Hellman key pair. */
|
||||
#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
|
||||
PSA_KEY_TYPE_DH_KEY_PAIR_BASE)
|
||||
/** Whether a key type is a Diffie-Hellman public key. */
|
||||
#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
|
||||
PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
|
||||
|
||||
/** Extract the group from a Diffie-Hellman key type. */
|
||||
#define PSA_KEY_TYPE_GET_GROUP(type) \
|
||||
((psa_dh_group_t) (PSA_KEY_TYPE_IS_DH(type) ? \
|
||||
((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \
|
||||
0))
|
||||
|
||||
/* The encoding of group identifiers is currently aligned with the
|
||||
* TLS Supported Groups Registry (formerly known as the
|
||||
* TLS EC Named Curve Registry)
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
|
||||
* The values are defined by RFC 7919. */
|
||||
#define PSA_DH_GROUP_FFDHE2048 ((psa_dh_group_t) 0x0100)
|
||||
#define PSA_DH_GROUP_FFDHE3072 ((psa_dh_group_t) 0x0101)
|
||||
#define PSA_DH_GROUP_FFDHE4096 ((psa_dh_group_t) 0x0102)
|
||||
#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103)
|
||||
#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104)
|
||||
|
||||
/** The block size of a block cipher.
|
||||
*
|
||||
* \param type A cipher key type (value of type #psa_key_type_t).
|
||||
@ -517,9 +569,8 @@
|
||||
#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000)
|
||||
#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000)
|
||||
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x30000000)
|
||||
|
||||
#define PSA_ALG_IS_VENDOR_DEFINED(alg) \
|
||||
(((alg) & PSA_ALG_VENDOR_FLAG) != 0)
|
||||
@ -591,7 +642,6 @@
|
||||
#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
|
||||
|
||||
#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000)
|
||||
/** Whether the specified algorithm is a key agreement algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
@ -601,8 +651,7 @@
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_KEY_AGREEMENT(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \
|
||||
PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
|
||||
/** Whether the specified algorithm is a key derivation algorithm.
|
||||
*
|
||||
@ -615,17 +664,6 @@
|
||||
#define PSA_ALG_IS_KEY_DERIVATION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
/** Whether the specified algorithm is a key selection algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is a key selection algorithm, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_KEY_SELECTION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION)
|
||||
|
||||
#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
|
||||
|
||||
#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
|
||||
@ -663,15 +701,12 @@
|
||||
*
|
||||
* That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros:
|
||||
* - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS,
|
||||
* - #PSA_ALG_DSA, #PSA_ALG_DETERMINISTIC_DSA,
|
||||
* - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA.
|
||||
* Then you may create and use a key as follows:
|
||||
* - Set the key usage field using #PSA_ALG_ANY_HASH, for example:
|
||||
* ```
|
||||
* psa_key_policy_set_usage(&policy,
|
||||
* PSA_KEY_USAGE_SIGN, //or PSA_KEY_USAGE_VERIFY
|
||||
* PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
|
||||
* psa_set_key_policy(handle, &policy);
|
||||
* psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN); // or VERIFY
|
||||
* psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
|
||||
* ```
|
||||
* - Import or generate key material.
|
||||
* - Call psa_asymmetric_sign() or psa_asymmetric_verify(), passing
|
||||
@ -685,7 +720,7 @@
|
||||
*
|
||||
* This value may not be used to build other algorithms that are
|
||||
* parametrized over a hash. For any valid use of this macro to build
|
||||
* an algorithm `\p alg`, #PSA_ALG_IS_HASH_AND_SIGN(\p alg) is true.
|
||||
* an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true.
|
||||
*
|
||||
* This value may not be used to build an algorithm specification to
|
||||
* perform an operation. It is only valid to build policies.
|
||||
@ -702,7 +737,7 @@
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding HMAC algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_HMAC(hash_alg) \
|
||||
@ -802,9 +837,14 @@
|
||||
(((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
|
||||
|
||||
#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000)
|
||||
/** The CBC-MAC construction over a block cipher
|
||||
*
|
||||
* \warning CBC-MAC is insecure in many cases.
|
||||
* A more secure mode, such as #PSA_ALG_CMAC, is recommended.
|
||||
*/
|
||||
#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001)
|
||||
/** The CMAC construction over a block cipher */
|
||||
#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002)
|
||||
#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003)
|
||||
|
||||
/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
|
||||
*
|
||||
@ -841,6 +881,18 @@
|
||||
*/
|
||||
#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001)
|
||||
|
||||
/** The ChaCha20 stream cipher.
|
||||
*
|
||||
* ChaCha20 is defined in RFC 7539.
|
||||
*
|
||||
* The nonce size for psa_cipher_set_iv() or psa_cipher_generate_iv()
|
||||
* must be 12.
|
||||
*
|
||||
* The initial block counter is always 0.
|
||||
*
|
||||
*/
|
||||
#define PSA_ALG_CHACHA20 ((psa_algorithm_t)0x04800005)
|
||||
|
||||
/** The CTR stream cipher mode.
|
||||
*
|
||||
* CTR is a stream cipher which is built from a block cipher.
|
||||
@ -850,8 +902,16 @@
|
||||
*/
|
||||
#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001)
|
||||
|
||||
/** The CFB stream cipher mode.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002)
|
||||
|
||||
/** The OFB stream cipher mode.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003)
|
||||
|
||||
/** The XTS cipher mode.
|
||||
@ -879,8 +939,43 @@
|
||||
*/
|
||||
#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101)
|
||||
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001)
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002)
|
||||
#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000)
|
||||
|
||||
/** Whether the specified algorithm is an AEAD mode on a block cipher.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is an AEAD algorithm which is an AEAD mode based on
|
||||
* a block cipher, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) \
|
||||
(((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \
|
||||
(PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG))
|
||||
|
||||
/** The CCM authenticated encryption algorithm.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06401001)
|
||||
|
||||
/** The GCM authenticated encryption algorithm.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06401002)
|
||||
|
||||
/** The Chacha20-Poly1305 AEAD algorithm.
|
||||
*
|
||||
* The ChaCha20_Poly1305 construction is defined in RFC 7539.
|
||||
*
|
||||
* Implementations must support 12-byte nonces, may support 8-byte nonces,
|
||||
* and should reject other sizes.
|
||||
*
|
||||
* Implementations must support 16-byte tags and should reject other sizes.
|
||||
*/
|
||||
#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x06001005)
|
||||
|
||||
/* In the encoding of a AEAD algorithm, the bits corresponding to
|
||||
* PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
|
||||
@ -920,14 +1015,15 @@
|
||||
* \return The corresponding AEAD algorithm with the default
|
||||
* tag length for that algorithm.
|
||||
*/
|
||||
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
|
||||
( \
|
||||
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_CCM) \
|
||||
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_GCM) \
|
||||
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
|
||||
( \
|
||||
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CCM) \
|
||||
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_GCM) \
|
||||
PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
|
||||
0)
|
||||
#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, ref) \
|
||||
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
|
||||
PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
|
||||
#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, ref) \
|
||||
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
|
||||
PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
|
||||
ref :
|
||||
|
||||
#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000)
|
||||
@ -943,7 +1039,7 @@
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding RSA PKCS#1 v1.5 signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \
|
||||
@ -974,7 +1070,7 @@
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding RSA PSS signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_PSS(hash_alg) \
|
||||
@ -982,37 +1078,6 @@
|
||||
#define PSA_ALG_IS_RSA_PSS(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
|
||||
|
||||
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
|
||||
/** DSA signature with hashing.
|
||||
*
|
||||
* This is the signature scheme defined by FIPS 186-4,
|
||||
* with a random per-message secret number (*k*).
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DSA(hash_alg) \
|
||||
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
|
||||
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
|
||||
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
|
||||
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_IS_DSA(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
|
||||
PSA_ALG_DSA_BASE)
|
||||
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
|
||||
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
|
||||
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
|
||||
#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
|
||||
/** ECDSA signature with hashing.
|
||||
*
|
||||
@ -1031,7 +1096,7 @@
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding ECDSA signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_ECDSA(hash_alg) \
|
||||
@ -1066,7 +1131,7 @@
|
||||
*
|
||||
* \return The corresponding deterministic ECDSA signature
|
||||
* algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \
|
||||
@ -1096,7 +1161,7 @@
|
||||
*/
|
||||
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
|
||||
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
|
||||
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
|
||||
PSA_ALG_IS_ECDSA(alg))
|
||||
|
||||
/** Get the hash used by a hash-and-sign signature algorithm.
|
||||
*
|
||||
@ -1138,7 +1203,7 @@
|
||||
* for MGF1.
|
||||
*
|
||||
* \return The corresponding RSA OAEP signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_OAEP(hash_alg) \
|
||||
@ -1150,16 +1215,25 @@
|
||||
((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
|
||||
0)
|
||||
|
||||
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100)
|
||||
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x20000100)
|
||||
/** Macro to build an HKDF algorithm.
|
||||
*
|
||||
* For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
|
||||
*
|
||||
* This key derivation algorithm uses the following inputs:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step.
|
||||
* It is optional; if omitted, the derivation uses an empty salt.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step.
|
||||
* You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET.
|
||||
* You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before
|
||||
* starting to generate output.
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding HKDF algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_HKDF(hash_alg) \
|
||||
@ -1180,18 +1254,22 @@
|
||||
#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200)
|
||||
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x20000200)
|
||||
/** Macro to build a TLS-1.2 PRF algorithm.
|
||||
*
|
||||
* TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
|
||||
* specified in Section 5 of RFC 5246. It is based on HMAC and can be
|
||||
* used with either SHA-256 or SHA-384.
|
||||
*
|
||||
* For the application to TLS-1.2, the salt and label arguments passed
|
||||
* to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246,
|
||||
* respectively. For example, for TLS key expansion, the salt is the
|
||||
* This key derivation algorithm uses the following inputs, which must be
|
||||
* passed in the order given here:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
|
||||
*
|
||||
* For the application to TLS-1.2 key expansion, the seed is the
|
||||
* concatenation of ServerHello.Random + ClientHello.Random,
|
||||
* while the label is "key expansion".
|
||||
* and the label is "key expansion".
|
||||
*
|
||||
* For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
|
||||
* TLS 1.2 PRF using HMAC-SHA-256.
|
||||
@ -1200,7 +1278,7 @@
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding TLS-1.2 PRF algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_TLS12_PRF(hash_alg) \
|
||||
@ -1219,7 +1297,7 @@
|
||||
#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300)
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x20000300)
|
||||
/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
|
||||
*
|
||||
* In a pure-PSK handshake in TLS 1.2, the master secret is derived
|
||||
@ -1228,10 +1306,16 @@
|
||||
* The latter is based on HMAC and can be used with either SHA-256
|
||||
* or SHA-384.
|
||||
*
|
||||
* For the application to TLS-1.2, the salt passed to psa_key_derivation()
|
||||
* (and forwarded to the TLS-1.2 PRF) is the concatenation of the
|
||||
* ClientHello.Random + ServerHello.Random, while the label is "master secret"
|
||||
* or "extended master secret".
|
||||
* This key derivation algorithm uses the following inputs, which must be
|
||||
* passed in the order given here:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
|
||||
*
|
||||
* For the application to TLS-1.2, the seed (which is
|
||||
* forwarded to the TLS-1.2 PRF) is the concatenation of the
|
||||
* ClientHello.Random + ServerHello.Random,
|
||||
* and the label is "master secret" or "extended master secret".
|
||||
*
|
||||
* For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
|
||||
* TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
|
||||
@ -1240,7 +1324,7 @@
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding TLS-1.2 PSK to MS algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \
|
||||
@ -1259,55 +1343,67 @@
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff)
|
||||
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x0803ffff)
|
||||
#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0x10fc0000)
|
||||
|
||||
/** Use a shared secret as is.
|
||||
/** Macro to build a combined algorithm that chains a key agreement with
|
||||
* a key derivation.
|
||||
*
|
||||
* Specify this algorithm as the selection component of a key agreement
|
||||
* to use the raw result of the key agreement as key material.
|
||||
* \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true).
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true).
|
||||
*
|
||||
* \warning The raw result of a key agreement algorithm such as finite-field
|
||||
* Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
|
||||
* not be used directly as key material. It can however be used as the secret
|
||||
* input in a key derivation algorithm.
|
||||
* \return The corresponding key agreement and derivation
|
||||
* algorithm.
|
||||
* \return Unspecified if \p ka_alg is not a supported
|
||||
* key agreement algorithm or \p kdf_alg is not a
|
||||
* supported key derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001)
|
||||
#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \
|
||||
((ka_alg) | (kdf_alg))
|
||||
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \
|
||||
(((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
|
||||
((alg) & ~PSA_ALG_KEY_DERIVATION_MASK)
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
|
||||
(((alg) & PSA_ALG_KEY_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
|
||||
#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000)
|
||||
/** The Diffie-Hellman key agreement algorithm.
|
||||
/** Whether the specified algorithm is a raw key agreement algorithm.
|
||||
*
|
||||
* This algorithm combines the finite-field Diffie-Hellman (DH) key
|
||||
* agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement,
|
||||
* to produce a shared secret from a private key and the peer's
|
||||
* public key, with a key selection or key derivation algorithm to produce
|
||||
* one or more shared keys and other shared cryptographic material.
|
||||
* A raw key agreement algorithm is one that does not specify
|
||||
* a key derivation function.
|
||||
* Usually, raw key agreement algorithms are constructed directly with
|
||||
* a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are
|
||||
* constructed with PSA_ALG_KEY_AGREEMENT().
|
||||
*
|
||||
* The shared secret produced by key agreement and passed as input to the
|
||||
* derivation or selection algorithm \p kdf_alg is the shared secret
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is a raw key agreement algorithm, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \
|
||||
(PSA_ALG_IS_KEY_AGREEMENT(alg) && \
|
||||
PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \
|
||||
((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg)))
|
||||
|
||||
/** The finite-field Diffie-Hellman (DH) key agreement algorithm.
|
||||
*
|
||||
* The shared secret produced by key agreement is
|
||||
* `g^{ab}` in big-endian format.
|
||||
* It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
|
||||
* in bits.
|
||||
*
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
|
||||
* or a key selection algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
|
||||
*
|
||||
* \return The Diffie-Hellman algorithm with the specified
|
||||
* selection or derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_FFDH(kdf_alg) \
|
||||
(PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
|
||||
#define PSA_ALG_FFDH ((psa_algorithm_t)0x30100000)
|
||||
|
||||
/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
|
||||
*
|
||||
* This includes every supported key selection or key agreement algorithm
|
||||
* for the output of the Diffie-Hellman calculation.
|
||||
* This includes the raw finite field Diffie-Hellman algorithm as well as
|
||||
* finite-field Diffie-Hellman followed by any supporter key derivation
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
@ -1316,18 +1412,11 @@
|
||||
* key agreement algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_FFDH(alg) \
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE)
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH)
|
||||
|
||||
#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000)
|
||||
/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
|
||||
*
|
||||
* This algorithm combines the elliptic curve Diffie-Hellman key
|
||||
* agreement to produce a shared secret from a private key and the peer's
|
||||
* public key, with a key selection or key derivation algorithm to produce
|
||||
* one or more shared keys and other shared cryptographic material.
|
||||
*
|
||||
* The shared secret produced by key agreement and passed as input to the
|
||||
* derivation or selection algorithm \p kdf_alg is the x-coordinate of
|
||||
* The shared secret produced by key agreement is the x-coordinate of
|
||||
* the shared secret point. It is always `ceiling(m / 8)` bytes long where
|
||||
* `m` is the bit size associated with the curve, i.e. the bit size of the
|
||||
* order of the curve's coordinate field. When `m` is not a multiple of 8,
|
||||
@ -1349,22 +1438,15 @@
|
||||
* the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
|
||||
* in big-endian byte order.
|
||||
* The bit size is `m` for the field `F_{2^m}`.
|
||||
*
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
|
||||
* or a selection algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
|
||||
*
|
||||
* \return The Diffie-Hellman algorithm with the specified
|
||||
* selection or derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_ECDH(kdf_alg) \
|
||||
(PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
|
||||
#define PSA_ALG_ECDH ((psa_algorithm_t)0x30200000)
|
||||
|
||||
/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
|
||||
* algorithm.
|
||||
*
|
||||
* This includes every supported key selection or key agreement algorithm
|
||||
* for the output of the Diffie-Hellman calculation.
|
||||
* This includes the raw elliptic curve Diffie-Hellman algorithm as well as
|
||||
* elliptic curve Diffie-Hellman followed by any supporter key derivation
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
@ -1374,7 +1456,7 @@
|
||||
* key agreement algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_ECDH(alg) \
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE)
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH)
|
||||
|
||||
/** Whether the specified algorithm encoding is a wildcard.
|
||||
*
|
||||
@ -1419,6 +1501,19 @@
|
||||
*/
|
||||
#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
|
||||
|
||||
/** The minimum value for a key identifier chosen by the application.
|
||||
*/
|
||||
#define PSA_KEY_ID_USER_MIN ((psa_app_key_id_t)0x00000001)
|
||||
/** The maximum value for a key identifier chosen by the application.
|
||||
*/
|
||||
#define PSA_KEY_ID_USER_MAX ((psa_app_key_id_t)0x3fffffff)
|
||||
/** The minimum value for a key identifier chosen by the implementation.
|
||||
*/
|
||||
#define PSA_KEY_ID_VENDOR_MIN ((psa_app_key_id_t)0x40000000)
|
||||
/** The maximum value for a key identifier chosen by the implementation.
|
||||
*/
|
||||
#define PSA_KEY_ID_VENDOR_MAX ((psa_app_key_id_t)0x7fffffff)
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup policy Key policies
|
||||
@ -1438,6 +1533,22 @@
|
||||
*/
|
||||
#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001)
|
||||
|
||||
/** Whether the key may be copied.
|
||||
*
|
||||
* This flag allows the use of psa_copy_key() to make a copy of the key
|
||||
* with the same policy or a more restrictive policy.
|
||||
*
|
||||
* For lifetimes for which the key is located in a secure element which
|
||||
* enforce the non-exportability of keys, copying a key outside the secure
|
||||
* element also requires the usage flag #PSA_KEY_USAGE_EXPORT.
|
||||
* Copying the key inside the secure element is permitted with just
|
||||
* #PSA_KEY_USAGE_COPY if the secure element supports it.
|
||||
* For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY
|
||||
* is sufficient to permit the copy.
|
||||
*/
|
||||
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002)
|
||||
|
||||
/** Whether the key may be used to encrypt a message.
|
||||
*
|
||||
* This flag allows the key to be used for a symmetric encryption operation,
|
||||
@ -1486,4 +1597,40 @@
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup derivation Key derivation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** A secret input for key derivation.
|
||||
*
|
||||
* This must be a key of type #PSA_KEY_TYPE_DERIVE.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101)
|
||||
|
||||
/** A label for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t)0x0201)
|
||||
|
||||
/** A salt for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202)
|
||||
|
||||
/** An information string for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t)0x0203)
|
||||
|
||||
/** A seed for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204)
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* PSA_CRYPTO_VALUES_H */
|
||||
|
@ -61,6 +61,7 @@ set(src_crypto
|
||||
platform_util.c
|
||||
poly1305.c
|
||||
psa_crypto.c
|
||||
psa_crypto_se.c
|
||||
psa_crypto_slot_management.c
|
||||
psa_crypto_storage.c
|
||||
psa_its_file.c
|
||||
@ -93,6 +94,8 @@ set(src_crypto
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND src_crypto ${thirdparty_src})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-declarations -Wmissing-prototypes")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Also see "include/mbedtls/config.h"
|
||||
|
||||
CFLAGS ?= -O2
|
||||
WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement
|
||||
WARNING_CFLAGS ?= -Wall -Wextra
|
||||
LDFLAGS ?=
|
||||
|
||||
CRYPTO_INCLUDES ?= -I../include
|
||||
@ -80,7 +80,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
|
||||
pk.o pk_wrap.o pkcs12.o \
|
||||
pkcs5.o pkparse.o pkwrite.o \
|
||||
platform.o platform_util.o poly1305.o \
|
||||
psa_crypto.o \
|
||||
psa_crypto.o psa_crypto_se.o \
|
||||
psa_crypto_slot_management.o \
|
||||
psa_crypto_storage.o \
|
||||
psa_its_file.o \
|
||||
@ -101,6 +101,10 @@ OBJS_CRYPTO += version.o
|
||||
OBJS_CRYPTO += version_features.o
|
||||
endif
|
||||
|
||||
include ../3rdparty/Makefile.inc
|
||||
LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES)
|
||||
OBJS_CRYPTO+=$(THIRDPARTY_CRYPTO_OBJECTS)
|
||||
|
||||
.SILENT:
|
||||
|
||||
.PHONY: all static shared clean
|
||||
@ -148,8 +152,9 @@ libmbedcrypto.dll: $(OBJS_CRYPTO)
|
||||
|
||||
clean:
|
||||
ifndef WINDOWS
|
||||
rm -f *.o libmbed*
|
||||
rm -f *.o libmbed* $(OBJS_CRYPTO)
|
||||
else
|
||||
if exist *.o del /Q /F *.o
|
||||
if exist libmbed* del /Q /F libmbed*
|
||||
if exist $(OBJS_CRYPTO) del /Q /F $(OBJS_CRYPTO)
|
||||
endif
|
||||
|
@ -2139,13 +2139,13 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
|
||||
{
|
||||
int ret;
|
||||
size_t lz, lzt;
|
||||
mbedtls_mpi TG, TA, TB;
|
||||
mbedtls_mpi TA, TB;
|
||||
|
||||
MPI_VALIDATE_RET( G != NULL );
|
||||
MPI_VALIDATE_RET( A != NULL );
|
||||
MPI_VALIDATE_RET( B != NULL );
|
||||
|
||||
mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
|
||||
mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
|
||||
@ -2183,7 +2183,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
|
||||
mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
@ -2410,8 +2410,6 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
|
||||
|
||||
i = mbedtls_mpi_bitlen( X );
|
||||
|
||||
for( i = 0; i < rounds; i++ )
|
||||
{
|
||||
/*
|
||||
@ -2428,7 +2426,8 @@ static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
|
||||
}
|
||||
|
||||
if (count++ > 30) {
|
||||
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
} while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
|
||||
|
@ -297,8 +297,7 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
||||
|
||||
psa_status_t status;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_usage_t key_usage;
|
||||
psa_key_policy_t key_policy;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
/* PSA Crypto API only accepts byte-aligned keys. */
|
||||
if( key_bitlen % 8 != 0 )
|
||||
@ -312,40 +311,33 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
||||
ctx->cipher_info->type );
|
||||
if( key_type == 0 )
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
|
||||
/* Allocate a key slot to use. */
|
||||
status = psa_allocate_key( &cipher_psa->slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
|
||||
/* Indicate that we own the key slot and need to
|
||||
* destroy it in mbedtls_cipher_free(). */
|
||||
cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
|
||||
|
||||
/* From that point on, the responsibility for destroying the
|
||||
* key slot is on mbedtls_cipher_free(). This includes the case
|
||||
* where the policy setup or key import below fail, as
|
||||
* mbedtls_cipher_free() needs to be called in any case. */
|
||||
|
||||
/* Setup policy for the new key slot. */
|
||||
key_policy = psa_key_policy_init();
|
||||
psa_set_key_type( &attributes, key_type );
|
||||
|
||||
/* Mbed TLS' cipher layer doesn't enforce the mode of operation
|
||||
* (encrypt vs. decrypt): it is possible to setup a key for encryption
|
||||
* and use it for AEAD decryption. Until tests relying on this
|
||||
* are changed, allow any usage in PSA. */
|
||||
/* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */
|
||||
key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg );
|
||||
status = psa_set_key_policy( cipher_psa->slot, &key_policy );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
/* mbedtls_psa_translate_cipher_operation( operation ); */
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||
psa_set_key_algorithm( &attributes, cipher_psa->alg );
|
||||
|
||||
/* Populate new key slot. */
|
||||
status = psa_import_key( cipher_psa->slot,
|
||||
key_type, key, key_bytelen );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
status = psa_import_key( &attributes, key, key_bytelen,
|
||||
&cipher_psa->slot );
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS:
|
||||
break;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
default:
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
}
|
||||
/* Indicate that we own the key slot and need to
|
||||
* destroy it in mbedtls_cipher_free(). */
|
||||
cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
|
||||
|
||||
ctx->key_bitlen = key_bitlen;
|
||||
ctx->operation = operation;
|
||||
|
@ -834,16 +834,16 @@ static const unsigned char des3_test_buf[8] =
|
||||
|
||||
static const unsigned char des3_test_ecb_dec[3][8] =
|
||||
{
|
||||
{ 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
|
||||
{ 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
|
||||
{ 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
|
||||
{ 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
|
||||
{ 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
|
||||
{ 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_ecb_enc[3][8] =
|
||||
{
|
||||
{ 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
|
||||
{ 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
|
||||
{ 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
|
||||
{ 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
|
||||
{ 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
|
||||
{ 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
|
||||
};
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
@ -854,16 +854,16 @@ static const unsigned char des3_test_iv[8] =
|
||||
|
||||
static const unsigned char des3_test_cbc_dec[3][8] =
|
||||
{
|
||||
{ 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
|
||||
{ 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
|
||||
{ 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
|
||||
{ 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
|
||||
{ 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
|
||||
{ 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
|
||||
};
|
||||
|
||||
static const unsigned char des3_test_cbc_enc[3][8] =
|
||||
{
|
||||
{ 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
|
||||
{ 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
|
||||
{ 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
|
||||
{ 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
|
||||
{ 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
|
||||
{ 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
|
||||
};
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
@ -928,7 +928,7 @@ int mbedtls_des_self_test( int verbose )
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
for( j = 0; j < 10000; j++ )
|
||||
for( j = 0; j < 100; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
mbedtls_des_crypt_ecb( &ctx, buf, buf );
|
||||
@ -1005,7 +1005,7 @@ int mbedtls_des_self_test( int verbose )
|
||||
|
||||
if( v == MBEDTLS_DES_DECRYPT )
|
||||
{
|
||||
for( j = 0; j < 10000; j++ )
|
||||
for( j = 0; j < 100; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
|
||||
@ -1015,7 +1015,7 @@ int mbedtls_des_self_test( int verbose )
|
||||
}
|
||||
else
|
||||
{
|
||||
for( j = 0; j < 10000; j++ )
|
||||
for( j = 0; j < 100; j++ )
|
||||
{
|
||||
unsigned char tmp[8];
|
||||
|
||||
|
@ -59,6 +59,13 @@ static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
|
||||
#endif
|
||||
}
|
||||
|
||||
int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
|
||||
{
|
||||
/* At this time, all groups support ECDH. */
|
||||
(void) gid;
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
|
||||
/*
|
||||
* Generate public key (restartable version)
|
||||
@ -215,6 +222,13 @@ int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
|
||||
#else
|
||||
switch( grp_id )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECP_DP_CURVE25519:
|
||||
ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
|
||||
ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
|
||||
ctx->grp_id = grp_id;
|
||||
return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
|
||||
#endif
|
||||
default:
|
||||
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
|
||||
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
|
||||
@ -266,6 +280,11 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
mbedtls_everest_free( &ctx->ctx.everest_ecdh );
|
||||
break;
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
ecdh_free_internal( &ctx->ctx.mbed_ecdh );
|
||||
break;
|
||||
@ -331,7 +350,7 @@ static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and write the ServerKeyExhange parameters (RFC 4492)
|
||||
* Setup and write the ServerKeyExchange parameters (RFC 4492)
|
||||
* struct {
|
||||
* ECParameters curve_params;
|
||||
* ECPoint public;
|
||||
@ -360,6 +379,11 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
|
||||
buf, blen, f_rng, p_rng ) );
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
|
||||
ctx->point_format, buf, blen,
|
||||
@ -409,6 +433,11 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
|
||||
buf, end) );
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
|
||||
buf, end ) );
|
||||
@ -473,6 +502,16 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
{
|
||||
mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
|
||||
MBEDTLS_EVEREST_ECDH_OURS :
|
||||
MBEDTLS_EVEREST_ECDH_THEIRS;
|
||||
return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
|
||||
key, s) );
|
||||
}
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
|
||||
key, side ) );
|
||||
@ -544,6 +583,11 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
|
||||
buf, blen, f_rng, p_rng ) );
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
|
||||
ctx->point_format, buf, blen,
|
||||
@ -585,6 +629,11 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
|
||||
buf, blen ) );
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
|
||||
buf, blen ) );
|
||||
@ -667,6 +716,11 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
#else
|
||||
switch( ctx->var )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
case MBEDTLS_ECDH_VARIANT_EVEREST:
|
||||
return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
|
||||
buf, blen, f_rng, p_rng ) );
|
||||
#endif
|
||||
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
|
||||
return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
|
||||
blen, f_rng, p_rng,
|
||||
|
@ -172,11 +172,11 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
|
||||
}
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
#define ECDSA_RS_ECP &rs_ctx->ecp
|
||||
#define ECDSA_RS_ECP ( rs_ctx == NULL ? NULL : &rs_ctx->ecp )
|
||||
|
||||
/* Utility macro for checking and updating ops budget */
|
||||
#define ECDSA_BUDGET( ops ) \
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, ECDSA_RS_ECP, ops ) );
|
||||
|
||||
/* Call this when entering a function that needs its own sub-context */
|
||||
#define ECDSA_RS_ENTER( SUB ) do { \
|
||||
@ -263,7 +263,7 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *pk = &k, *pr = r;
|
||||
|
||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||
if( grp->N.p == NULL )
|
||||
if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
/* Make sure d is in range 1..n-1 */
|
||||
@ -378,6 +378,20 @@ cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid )
|
||||
{
|
||||
switch( gid )
|
||||
{
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE25519: return 0;
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
case MBEDTLS_ECP_DP_CURVE448: return 0;
|
||||
#endif
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute ECDSA signature of a hashed message
|
||||
*/
|
||||
@ -502,7 +516,7 @@ static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
|
||||
|
||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||
if( grp->N.p == NULL )
|
||||
if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
ECDSA_RS_ENTER( ver );
|
||||
|
218
library/ecp.c
218
library/ecp.c
@ -366,7 +366,7 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
|
||||
/*
|
||||
* List of supported curves:
|
||||
* - internal ID
|
||||
* - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
|
||||
* - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7)
|
||||
* - size in bits
|
||||
* - readable name
|
||||
*
|
||||
@ -409,6 +409,9 @@ static const mbedtls_ecp_curve_info ecp_supported_curves[] =
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
{ MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
{ MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" },
|
||||
#endif
|
||||
{ MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
|
||||
};
|
||||
@ -1080,6 +1083,18 @@ cleanup:
|
||||
INC_MUL_COUNT \
|
||||
} while( 0 )
|
||||
|
||||
static inline int mbedtls_mpi_mul_mod( const mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *X,
|
||||
const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *B )
|
||||
{
|
||||
int ret;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( X, A, B ) );
|
||||
MOD_MUL( *X );
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
|
||||
* N->s < 0 is a very fast test, which fails only if N is 0
|
||||
@ -1088,6 +1103,18 @@ cleanup:
|
||||
while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) )
|
||||
|
||||
static inline int mbedtls_mpi_sub_mod( const mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *X,
|
||||
const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *B )
|
||||
{
|
||||
int ret;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( X, A, B ) );
|
||||
MOD_SUB( *X );
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
|
||||
* We known P, N and the result are positive, so sub_abs is correct, and
|
||||
@ -1097,6 +1124,29 @@ cleanup:
|
||||
while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) )
|
||||
|
||||
static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *X,
|
||||
const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *B )
|
||||
{
|
||||
int ret;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) );
|
||||
MOD_ADD( *X );
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static inline int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *X,
|
||||
size_t count )
|
||||
{
|
||||
int ret;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, count ) );
|
||||
MOD_ADD( *X );
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
/*
|
||||
* For curves in short Weierstrass form, we do all the internal operations in
|
||||
@ -1129,14 +1179,14 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p
|
||||
* X = X / Z^2 mod p
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ZZi ) );
|
||||
|
||||
/*
|
||||
* Y = Y / Z^3 mod p
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ZZi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &Zi ) );
|
||||
|
||||
/*
|
||||
* Z = 1
|
||||
@ -1190,8 +1240,7 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
|
||||
for( i = 1; i < T_size; i++ )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
|
||||
MOD_MUL( c[i] );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &c[i], &c[i-1], &T[i]->Z ) );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1210,17 +1259,17 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
|
||||
}
|
||||
else
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Zi, &u, &c[i-1] ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &u, &u, &T[i]->Z ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* proceed as in normalize()
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->X, &T[i]->X, &ZZi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &ZZi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &Zi ) );
|
||||
|
||||
/*
|
||||
* Post-precessing: reclaim some memory by shrinking coordinates
|
||||
@ -1306,52 +1355,52 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
if( grp->A.p == NULL )
|
||||
{
|
||||
/* M = 3(X + Z^2)(X - Z^2) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &T, &P->X, &S ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &U, &P->X, &S ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &U ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* M = 3.X^2 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &P->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
|
||||
|
||||
/* Optimize away for "koblitz" curves with A = 0 */
|
||||
if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
|
||||
{
|
||||
/* M += A.Z^4 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &S, &S ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &grp->A ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &M, &M, &S ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* S = 4.X.Y^2 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &P->Y, &P->Y ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &T ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &S, 1 ) );
|
||||
|
||||
/* U = 8.Y^4 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &T, &T ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
|
||||
|
||||
/* T = M^2 - 2.S */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &M, &M ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
|
||||
|
||||
/* S = M(S - T) - U */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &T ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &S, &M ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &U ) );
|
||||
|
||||
/* U = 2.Y.Z */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &P->Y, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
|
||||
@ -1414,12 +1463,12 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
|
||||
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &P->Z, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T1, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &T1, &Q->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T2, &Q->Y ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T1, &T1, &P->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T2, &T2, &P->Y ) );
|
||||
|
||||
/* Special cases (2) and (3) */
|
||||
if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
|
||||
@ -1436,18 +1485,19 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
}
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z, &P->Z, &T1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T1, &T1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T3, &T1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &P->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X, &T2, &T2 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T4 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3, &T3, &X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &T2 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T4, &P->Y ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y, &T3, &T4 ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
|
||||
@ -1498,15 +1548,15 @@ static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p
|
||||
while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
|
||||
|
||||
/* Z = l * Z */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z, &pt->Z, &l ) );
|
||||
|
||||
/* X = l^2 * X */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &l, &l ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ll ) );
|
||||
|
||||
/* Y = l^3 * Y */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &ll, &l ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ll ) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
|
||||
@ -2173,7 +2223,7 @@ static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P
|
||||
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
|
||||
|
||||
cleanup:
|
||||
@ -2217,8 +2267,8 @@ static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &l );
|
||||
@ -2258,24 +2308,24 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
|
||||
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &A, &P->X, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &AA, &A, &A ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &B, &P->X, &P->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &BB, &B, &B ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &E, &AA, &BB ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &C, &Q->X, &Q->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &D, &Q->X, &Q->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &DA, &D, &A ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &CB, &C, &B ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->X, &S->X, &S->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S->Z, &DA, &CB ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, &S->Z, &S->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, d, &S->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->X, &AA, &BB ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &grp->A, &E ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &R->Z, &BB, &R->Z ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &E, &R->Z ) );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
|
||||
@ -2450,8 +2500,8 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
|
||||
* YY = Y^2
|
||||
* RHS = X (X^2 + A) + B = X^3 + A X + B
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &YY, &pt->Y, &pt->Y ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &pt->X, &pt->X ) );
|
||||
|
||||
/* Special case for A = -3 */
|
||||
if( grp->A.p == NULL )
|
||||
@ -2460,11 +2510,11 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
|
||||
}
|
||||
else
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->A ) );
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &RHS, &pt->X ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->B ) );
|
||||
|
||||
if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
|
||||
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
|
@ -149,20 +149,32 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
|
||||
* Internal function used both for seeding and reseeding the DRBG.
|
||||
* Comments starting with arabic numbers refer to section 10.1.2.4
|
||||
* of SP800-90A, while roman numbers refer to section 9.2.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len )
|
||||
static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len,
|
||||
int use_nonce )
|
||||
{
|
||||
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen;
|
||||
size_t seedlen = 0;
|
||||
int ret;
|
||||
|
||||
/* III. Check input length */
|
||||
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||
ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
|
||||
{
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
|
||||
size_t total_entropy_len;
|
||||
|
||||
if( use_nonce == 0 )
|
||||
total_entropy_len = ctx->entropy_len;
|
||||
else
|
||||
total_entropy_len = ctx->entropy_len * 3 / 2;
|
||||
|
||||
/* III. Check input length */
|
||||
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||
total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
|
||||
{
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
|
||||
}
|
||||
}
|
||||
|
||||
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
|
||||
@ -170,9 +182,32 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
/* IV. Gather entropy_len bytes of entropy for the seed */
|
||||
if( ( ret = ctx->f_entropy( ctx->p_entropy,
|
||||
seed, ctx->entropy_len ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
}
|
||||
seedlen += ctx->entropy_len;
|
||||
|
||||
/* For initial seeding, allow adding of nonce generated
|
||||
* from the entropy source. See Sect 8.6.7 in SP800-90A. */
|
||||
if( use_nonce )
|
||||
{
|
||||
/* Note: We don't merge the two calls to f_entropy() in order
|
||||
* to avoid requesting too much entropy from f_entropy()
|
||||
* at once. Specifically, if the underlying digest is not
|
||||
* SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
|
||||
* is larger than the maximum of 32 Bytes that our own
|
||||
* entropy source implementation can emit in a single
|
||||
* call in configurations disabling SHA-512. */
|
||||
if( ( ret = ctx->f_entropy( ctx->p_entropy,
|
||||
seed + seedlen,
|
||||
ctx->entropy_len / 2 ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
}
|
||||
|
||||
seedlen += ctx->entropy_len / 2;
|
||||
}
|
||||
|
||||
seedlen = ctx->entropy_len;
|
||||
|
||||
/* 1. Concatenate entropy and additional data if any */
|
||||
if( additional != NULL && len != 0 )
|
||||
@ -194,8 +229,20 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG reseeding: 10.1.2.4 + 9.2
|
||||
*/
|
||||
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len )
|
||||
{
|
||||
return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* HMAC_DRBG initialisation (10.1.2.3 + 9.1)
|
||||
*
|
||||
* The nonce is not passed as a separate parameter but extracted
|
||||
* from the entropy source as suggested in 8.6.7.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
const mbedtls_md_info_t * md_info,
|
||||
@ -205,7 +252,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
size_t len )
|
||||
{
|
||||
int ret;
|
||||
size_t entropy_len, md_size;
|
||||
size_t md_size;
|
||||
|
||||
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
|
||||
return( ret );
|
||||
@ -233,20 +280,15 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
*
|
||||
* (This also matches the sizes used in the NIST test vectors.)
|
||||
*/
|
||||
entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
|
||||
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
|
||||
32; /* better (256+) -> 256 bits */
|
||||
ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
|
||||
md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
|
||||
32; /* better (256+) -> 256 bits */
|
||||
|
||||
/*
|
||||
* For initialisation, use more entropy to emulate a nonce
|
||||
* (Again, matches test vectors.)
|
||||
*/
|
||||
ctx->entropy_len = entropy_len * 3 / 2;
|
||||
|
||||
if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
|
||||
if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
|
||||
1 /* add nonce */ ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
|
||||
ctx->entropy_len = entropy_len;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
37
library/pk.c
37
library/pk.c
@ -158,17 +158,20 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
|
||||
int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key )
|
||||
{
|
||||
const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t *pk_ctx;
|
||||
psa_key_type_t type;
|
||||
|
||||
if( ctx == NULL || ctx->pk_info != NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
if( PSA_SUCCESS != psa_get_key_information( key, &type, NULL ) )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
type = psa_get_key_type( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
/* Current implementation of can_do() relies on this. */
|
||||
if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
|
||||
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
|
||||
|
||||
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
|
||||
@ -589,19 +592,18 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
|
||||
* Currently only works for EC private keys.
|
||||
*/
|
||||
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||
psa_key_handle_t *slot,
|
||||
psa_key_handle_t *handle,
|
||||
psa_algorithm_t hash_alg )
|
||||
{
|
||||
#if !defined(MBEDTLS_ECP_C)
|
||||
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||
#else
|
||||
psa_key_handle_t key;
|
||||
const mbedtls_ecp_keypair *ec;
|
||||
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t d_len;
|
||||
psa_ecc_curve_t curve_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_policy_t policy;
|
||||
int ret;
|
||||
|
||||
/* export the private key material in the format PSA wants */
|
||||
@ -614,32 +616,23 @@ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||
return( ret );
|
||||
|
||||
curve_id = mbedtls_ecp_curve_info_from_grp_id( ec->grp.id )->tls_id;
|
||||
key_type = PSA_KEY_TYPE_ECC_KEYPAIR(
|
||||
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
mbedtls_psa_parse_tls_ecc_group ( curve_id ) );
|
||||
|
||||
/* allocate a key slot */
|
||||
if( PSA_SUCCESS != psa_allocate_key( &key ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
/* prepare the key attributes */
|
||||
psa_set_key_type( &attributes, key_type );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
|
||||
psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
|
||||
|
||||
/* set policy */
|
||||
policy = psa_key_policy_init();
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN,
|
||||
PSA_ALG_ECDSA(hash_alg) );
|
||||
if( PSA_SUCCESS != psa_set_key_policy( key, &policy ) )
|
||||
/* import private key into PSA */
|
||||
if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, handle ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
|
||||
/* import private key in slot */
|
||||
if( PSA_SUCCESS != psa_import_key( key, key_type, d, d_len ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
|
||||
/* remember slot number to be destroyed later by caller */
|
||||
*slot = key;
|
||||
|
||||
/* make PK context wrap the key slot */
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
|
||||
return( mbedtls_pk_setup_opaque( pk, key ) );
|
||||
return( mbedtls_pk_setup_opaque( pk, *handle ) );
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -546,9 +546,9 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
const unsigned char *sig, size_t sig_len )
|
||||
{
|
||||
int ret;
|
||||
psa_key_handle_t key_slot;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_type_t psa_type;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t key_handle = 0;
|
||||
psa_status_t status;
|
||||
mbedtls_pk_context key;
|
||||
int key_len;
|
||||
/* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
|
||||
@ -576,23 +576,17 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
if( psa_md == 0 )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
psa_sig_md = PSA_ALG_ECDSA( psa_md );
|
||||
psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
|
||||
|
||||
if( ( ret = psa_allocate_key( &key_slot ) ) != PSA_SUCCESS )
|
||||
return( mbedtls_psa_err_translate_pk( ret ) );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
|
||||
psa_set_key_algorithm( &attributes, psa_sig_md );
|
||||
|
||||
policy = psa_key_policy_init();
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md );
|
||||
if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS )
|
||||
status = psa_import_key( &attributes,
|
||||
buf + sizeof( buf ) - key_len, key_len,
|
||||
&key_handle );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = mbedtls_psa_err_translate_pk( ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len )
|
||||
!= PSA_SUCCESS )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
ret = mbedtls_psa_err_translate_pk( status );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -611,7 +605,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( psa_asymmetric_verify( key_slot, psa_sig_md,
|
||||
if( psa_asymmetric_verify( key_handle, psa_sig_md,
|
||||
hash, hash_len,
|
||||
buf, 2 * signature_part_size )
|
||||
!= PSA_SUCCESS )
|
||||
@ -628,7 +622,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
psa_destroy_key( key_slot );
|
||||
psa_destroy_key( key_handle );
|
||||
return( ret );
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
@ -898,10 +892,13 @@ static size_t pk_opaque_get_bitlen( const void *ctx )
|
||||
{
|
||||
const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
|
||||
size_t bits;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) )
|
||||
return( 0 );
|
||||
|
||||
bits = psa_get_key_bits( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
return( bits );
|
||||
}
|
||||
|
||||
@ -1002,8 +999,9 @@ static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
|
||||
size_t bits, buf_len;
|
||||
size_t buf_len;
|
||||
psa_status_t status;
|
||||
|
||||
/* PSA has its own RNG */
|
||||
@ -1014,11 +1012,11 @@ static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
||||
* that information. Assume that the buffer is large enough for a
|
||||
* maximal-length signature with that key (otherwise the application is
|
||||
* buggy anyway). */
|
||||
status = psa_get_key_information( *key, NULL, &bits );
|
||||
status = psa_get_key_attributes( *key, &attributes );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( mbedtls_psa_err_translate_pk( status ) );
|
||||
|
||||
buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( bits );
|
||||
buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
/* make the signature */
|
||||
status = psa_asymmetric_sign( *key, alg, hash, hash_len,
|
||||
|
@ -246,17 +246,16 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( pk_type == MBEDTLS_PK_OPAQUE )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_handle_t handle;
|
||||
psa_ecc_curve_t curve;
|
||||
|
||||
handle = *((psa_key_handle_t*) key->pk_ctx );
|
||||
|
||||
status = psa_get_key_information( handle, &key_type,
|
||||
NULL /* bitsize not needed */ );
|
||||
if( status != PSA_SUCCESS )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( handle, &attributes ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
key_type = psa_get_key_type( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
curve = PSA_KEY_TYPE_GET_CURVE( key_type );
|
||||
if( curve == 0 )
|
||||
|
2651
library/psa_crypto.c
2651
library/psa_crypto.c
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
@ -38,27 +39,102 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
psa_key_type_t type;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_file_id_t persistent_storage_id;
|
||||
unsigned allocated : 1;
|
||||
psa_core_key_attributes_t attr;
|
||||
union
|
||||
{
|
||||
/* Raw-data key (key_type_is_raw_bytes() in psa_crypto.c) */
|
||||
struct raw_data
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t bytes;
|
||||
} raw;
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/* RSA public key or key pair */
|
||||
mbedtls_rsa_context *rsa;
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* EC public key or key pair */
|
||||
mbedtls_ecp_keypair *ecp;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* Any key type in a secure element */
|
||||
struct se
|
||||
{
|
||||
psa_key_slot_number_t slot_number;
|
||||
} se;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
} data;
|
||||
} psa_key_slot_t;
|
||||
|
||||
/* A mask of key attribute flags used only internally.
|
||||
* Currently there aren't any. */
|
||||
#define PSA_KA_MASK_INTERNAL_ONLY ( \
|
||||
0 )
|
||||
|
||||
/** Test whether a key slot is occupied.
|
||||
*
|
||||
* A key slot is occupied iff the key type is nonzero. This works because
|
||||
* no valid key can have 0 as its key type.
|
||||
*
|
||||
* \param[in] slot The key slot to test.
|
||||
*
|
||||
* \return 1 if the slot is occupied, 0 otherwise.
|
||||
*/
|
||||
static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot )
|
||||
{
|
||||
return( slot->attr.type != 0 );
|
||||
}
|
||||
|
||||
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in] slot The key slot to query.
|
||||
* \param mask The mask of bits to extract.
|
||||
*
|
||||
* \return The key attribute flags in the given slot,
|
||||
* bitwise-anded with \p mask.
|
||||
*/
|
||||
static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
return( slot->attr.flags & mask );
|
||||
}
|
||||
|
||||
/** Set flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to modify.
|
||||
* \param value The new value of the selected bits.
|
||||
*/
|
||||
static inline void psa_key_slot_set_flags( psa_key_slot_t *slot,
|
||||
uint16_t mask,
|
||||
uint16_t value )
|
||||
{
|
||||
slot->attr.flags = ( ( ~mask & slot->attr.flags ) |
|
||||
( mask & value ) );
|
||||
}
|
||||
|
||||
/** Turn on flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to set.
|
||||
*/
|
||||
static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
slot->attr.flags |= mask;
|
||||
}
|
||||
|
||||
/** Turn off flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to clear.
|
||||
*/
|
||||
static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
slot->attr.flags &= ~mask;
|
||||
}
|
||||
|
||||
/** Completely wipe a slot in memory, including its policy.
|
||||
*
|
||||
* Persistent storage is not affected.
|
||||
@ -68,7 +144,7 @@ typedef struct
|
||||
* \retval PSA_SUCCESS
|
||||
* Success. This includes the case of a key slot that was
|
||||
* already fully wiped.
|
||||
* \retval PSA_ERROR_TAMPERING_DETECTED
|
||||
* \retval PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );
|
||||
|
||||
|
356
library/psa_crypto_se.c
Normal file
356
library/psa_crypto_se.c
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/* 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)
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver lookup */
|
||||
/****************************************************************/
|
||||
|
||||
/* This structure is identical to psa_drv_se_context_t declared in
|
||||
* `crypto_se_driver.h`, except that some parts are writable here
|
||||
* (non-const, or pointer to non-const). */
|
||||
typedef struct
|
||||
{
|
||||
void *persistent_data;
|
||||
size_t persistent_data_size;
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_internal_context_t;
|
||||
|
||||
typedef struct psa_se_drv_table_entry_s
|
||||
{
|
||||
psa_key_lifetime_t lifetime;
|
||||
const psa_drv_se_t *methods;
|
||||
union
|
||||
{
|
||||
psa_drv_se_internal_context_t internal;
|
||||
psa_drv_se_context_t context;
|
||||
};
|
||||
} psa_se_drv_table_entry_t;
|
||||
|
||||
static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
|
||||
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime )
|
||||
{
|
||||
size_t i;
|
||||
/* In the driver table, lifetime=0 means an entry that isn't used.
|
||||
* No driver has a lifetime of 0 because it's a reserved value
|
||||
* (which designates volatile keys). Make sure we never return
|
||||
* a driver entry for lifetime 0. */
|
||||
if( lifetime == 0 )
|
||||
return( NULL );
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].lifetime == lifetime )
|
||||
return( &driver_table[i] );
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
return( driver->methods );
|
||||
}
|
||||
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
return( &driver->context );
|
||||
}
|
||||
|
||||
int psa_get_se_driver( psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context)
|
||||
{
|
||||
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
|
||||
if( p_methods != NULL )
|
||||
*p_methods = ( driver ? driver->methods : NULL );
|
||||
if( p_drv_context != NULL )
|
||||
*p_drv_context = ( driver ? &driver->context : NULL );
|
||||
return( driver != NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Persistent data management */
|
||||
/****************************************************************/
|
||||
|
||||
static psa_status_t psa_get_se_driver_its_file_uid(
|
||||
const psa_se_drv_table_entry_t *driver,
|
||||
psa_storage_uid_t *uid )
|
||||
{
|
||||
if( driver->lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
/* ITS file sizes are limited to 32 bits. */
|
||||
if( driver->internal.persistent_data_size > UINT32_MAX )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif
|
||||
|
||||
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
|
||||
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
size_t length;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid( driver, &uid );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* Read the amount of persistent data that the driver requests.
|
||||
* If the data in storage is larger, it is truncated. If the data
|
||||
* in storage is smaller, silently keep what is already at the end
|
||||
* of the output buffer. */
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return( psa_its_get( uid, 0,
|
||||
(uint32_t) driver->internal.persistent_data_size,
|
||||
driver->internal.persistent_data,
|
||||
&length ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid( driver, &uid );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return( psa_its_set( uid,
|
||||
(uint32_t) driver->internal.persistent_data_size,
|
||||
driver->internal.persistent_data,
|
||||
0 ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
|
||||
{
|
||||
psa_storage_uid_t uid;
|
||||
if( lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime;
|
||||
return( psa_its_remove( uid ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* If the lifetime is wrong, it's a bug in the library. */
|
||||
if( driver->lifetime != psa_get_key_lifetime( attributes ) )
|
||||
return( PSA_ERROR_CORRUPTION_DETECTED );
|
||||
|
||||
/* If the driver doesn't support key creation in any way, give up now. */
|
||||
if( driver->methods->key_management == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
|
||||
{
|
||||
/* The application wants to use a specific slot. Allow it if
|
||||
* the driver supports it. On a system with isolation,
|
||||
* the crypto service must check that the application is
|
||||
* permitted to request this slot. */
|
||||
psa_drv_se_validate_slot_number_t p_validate_slot_number =
|
||||
driver->methods->key_management->p_validate_slot_number;
|
||||
if( p_validate_slot_number == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
status = p_validate_slot_number( &driver->context,
|
||||
attributes, method,
|
||||
*slot_number );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The application didn't tell us which slot to use. Let the driver
|
||||
* choose. This is the normal case. */
|
||||
psa_drv_se_allocate_key_t p_allocate =
|
||||
driver->methods->key_management->p_allocate;
|
||||
if( p_allocate == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
status = p_allocate( &driver->context,
|
||||
driver->internal.persistent_data,
|
||||
attributes, method,
|
||||
slot_number );
|
||||
}
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t storage_status;
|
||||
/* Normally a missing method would mean that the action is not
|
||||
* supported. But psa_destroy_key() is not supposed to return
|
||||
* PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
|
||||
* be able to destroy it. The only use case for a driver that
|
||||
* does not have a way to destroy keys at all is if the keys are
|
||||
* locked in a read-only state: we can use the keys but not
|
||||
* destroy them. Hence, if the driver doesn't support destroying
|
||||
* keys, it's really a lack of permission. */
|
||||
if( driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_destroy == NULL )
|
||||
return( PSA_ERROR_NOT_PERMITTED );
|
||||
status = driver->methods->key_management->p_destroy(
|
||||
&driver->context,
|
||||
driver->internal.persistent_data,
|
||||
slot_number );
|
||||
storage_status = psa_save_se_persistent_data( driver );
|
||||
return( status == PSA_SUCCESS ? storage_status : status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver registration */
|
||||
/****************************************************************/
|
||||
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t *methods)
|
||||
{
|
||||
size_t i;
|
||||
psa_status_t status;
|
||||
|
||||
if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
/* Driver table entries are 0-initialized. 0 is not a valid driver
|
||||
* lifetime because it means a volatile key. */
|
||||
#if defined(static_assert)
|
||||
static_assert( PSA_KEY_LIFETIME_VOLATILE == 0,
|
||||
"Secure element support requires 0 to mean a volatile key" );
|
||||
#endif
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE ||
|
||||
lifetime == PSA_KEY_LIFETIME_PERSISTENT )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
if( lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].lifetime == 0 )
|
||||
break;
|
||||
/* Check that lifetime isn't already in use up to the first free
|
||||
* entry. Since entries are created in order and never deleted,
|
||||
* there can't be a used entry after the first free entry. */
|
||||
if( driver_table[i].lifetime == lifetime )
|
||||
return( PSA_ERROR_ALREADY_EXISTS );
|
||||
}
|
||||
if( i == PSA_MAX_SE_DRIVERS )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
driver_table[i].lifetime = lifetime;
|
||||
driver_table[i].methods = methods;
|
||||
|
||||
if( methods->persistent_data_size != 0 )
|
||||
{
|
||||
driver_table[i].internal.persistent_data =
|
||||
mbedtls_calloc( 1, methods->persistent_data_size );
|
||||
if( driver_table[i].internal.persistent_data == NULL )
|
||||
{
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* Load the driver's persistent data. On first use, the persistent
|
||||
* data does not exist in storage, and is initialized to
|
||||
* all-bits-zero by the calloc call just above. */
|
||||
status = psa_load_se_persistent_data( &driver_table[i] );
|
||||
if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
|
||||
goto error;
|
||||
}
|
||||
driver_table[i].internal.persistent_data_size =
|
||||
methods->persistent_data_size;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
error:
|
||||
memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
|
||||
return( status );
|
||||
}
|
||||
|
||||
void psa_unregister_all_se_drivers( void )
|
||||
{
|
||||
size_t i;
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].internal.persistent_data != NULL )
|
||||
mbedtls_free( driver_table[i].internal.persistent_data );
|
||||
}
|
||||
memset( driver_table, 0, sizeof( driver_table ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
184
library/psa_crypto_se.h
Normal file
184
library/psa_crypto_se.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/* 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 PSA_CRYPTO_SE_H
|
||||
#define PSA_CRYPTO_SE_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/** The maximum lifetime value that this implementation supports
|
||||
* for a secure element.
|
||||
*
|
||||
* This is not a characteristic that each PSA implementation has, but a
|
||||
* limitation of the current implementation due to the constraints imposed
|
||||
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
|
||||
*
|
||||
* The minimum lifetime value for a secure element is 2, like on any
|
||||
* PSA implementation (0=volatile and 1=internal-storage are taken).
|
||||
*/
|
||||
#define PSA_MAX_SE_LIFETIME 255
|
||||
|
||||
/** The base of the range of ITS file identifiers for secure element
|
||||
* driver persistent data.
|
||||
*
|
||||
* We use a slice of the implemenation reserved range 0xffff0000..0xffffffff,
|
||||
* specifically the range 0xfffffe00..0xfffffeff. The length of this range
|
||||
* drives the value of #PSA_MAX_SE_LIFETIME.
|
||||
* The identifiers 0xfffffe00 and 0xfffffe01 are actually not used since
|
||||
* they correspond to #PSA_KEY_LIFETIME_VOLATILE and
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT which don't have a driver.
|
||||
*/
|
||||
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ( (psa_key_id_t) 0xfffffe00 )
|
||||
|
||||
/** The maximum number of registered secure element driver lifetimes. */
|
||||
#define PSA_MAX_SE_DRIVERS 4
|
||||
|
||||
/** Unregister all secure element drivers.
|
||||
*
|
||||
* \warning Do not call this function while the library is in the initialized
|
||||
* state. This function is only intended to be called at the end
|
||||
* of mbedtls_psa_crypto_free().
|
||||
*/
|
||||
void psa_unregister_all_se_drivers( void );
|
||||
|
||||
/** A structure that describes a registered secure element driver.
|
||||
*
|
||||
* A secure element driver table entry contains a pointer to the
|
||||
* driver's method table as well as the driver context structure.
|
||||
*/
|
||||
typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
|
||||
|
||||
/** Return the secure element driver information for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
* \param[out] p_methods On output, if there is a driver,
|
||||
* \c *methods points to its method table.
|
||||
* Otherwise \c *methods is \c NULL.
|
||||
* \param[out] p_drv_context On output, if there is a driver,
|
||||
* \c *drv_context points to its context
|
||||
* structure.
|
||||
* Otherwise \c *drv_context is \c NULL.
|
||||
*
|
||||
* \retval 1
|
||||
* \p lifetime corresponds to a registered driver.
|
||||
* \retval 0
|
||||
* \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
int psa_get_se_driver( psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context);
|
||||
|
||||
/** Return the secure element driver table entry for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
*
|
||||
* \return The driver table entry for \p lifetime, or
|
||||
* \p NULL if \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime );
|
||||
|
||||
/** Return the method table for a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return The driver's method table.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Return the context of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return A pointer to the driver context.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Find a free slot for a key that is to be created.
|
||||
*
|
||||
* This function calls the relevant method in the driver to find a suitable
|
||||
* slot for a key with the given attributes.
|
||||
*
|
||||
* \param[in] attributes Metadata about the key that is about to be created.
|
||||
* \param[in] driver The driver table entry to query.
|
||||
* \param[out] slot_number On success, a slot number that is free in this
|
||||
* secure element.
|
||||
*/
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number );
|
||||
|
||||
/** Destoy a key in a secure element.
|
||||
*
|
||||
* This function calls the relevant driver method to destroy a key
|
||||
* and updates the driver's persistent data.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number );
|
||||
|
||||
/** Load the persistent data of a secure element driver.
|
||||
*
|
||||
* \param driver The driver table entry containing the persistent
|
||||
* data to load from storage.
|
||||
*/
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Save the persistent data of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry containing the persistent
|
||||
* data to save to storage.
|
||||
*/
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Destroy the persistent data of a secure element driver.
|
||||
*
|
||||
* This is currently only used for testing.
|
||||
*
|
||||
* \param[in] lifetime The driver lifetime whose persistent data should
|
||||
* be erased.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime );
|
||||
|
||||
|
||||
/** The storage representation of a key whose data is in a secure element.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot_number[sizeof( psa_key_slot_number_t )];
|
||||
uint8_t bits[sizeof( psa_key_bits_t )];
|
||||
} psa_se_key_data_storage_t;
|
||||
|
||||
#endif /* PSA_CRYPTO_SE_H */
|
@ -33,6 +33,9 @@
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
#include "psa_crypto_se.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -71,8 +74,8 @@ psa_status_t psa_get_key_slot( psa_key_handle_t handle,
|
||||
return( PSA_ERROR_INVALID_HANDLE );
|
||||
slot = &global_data.key_slots[handle - 1];
|
||||
|
||||
/* If the slot hasn't been allocated, the handle is invalid. */
|
||||
if( ! slot->allocated )
|
||||
/* If the slot isn't occupied, the handle is invalid. */
|
||||
if( ! psa_is_key_slot_occupied( slot ) )
|
||||
return( PSA_ERROR_INVALID_HANDLE );
|
||||
|
||||
*p_slot = slot;
|
||||
@ -99,71 +102,55 @@ void psa_wipe_all_key_slots( void )
|
||||
global_data.key_slots_initialized = 0;
|
||||
}
|
||||
|
||||
/** Find a free key slot and mark it as in use.
|
||||
*
|
||||
* \param[out] handle On success, a slot number that is not in use. This
|
||||
* value can be used as a handle to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
*/
|
||||
static psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle )
|
||||
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
|
||||
psa_key_slot_t **p_slot )
|
||||
{
|
||||
if( ! global_data.key_slots_initialized )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
|
||||
{
|
||||
psa_key_slot_t *slot = &global_data.key_slots[*handle - 1];
|
||||
if( ! slot->allocated )
|
||||
{
|
||||
slot->allocated = 1;
|
||||
*p_slot = &global_data.key_slots[*handle - 1];
|
||||
if( ! psa_is_key_slot_occupied( *p_slot ) )
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
}
|
||||
*p_slot = NULL;
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
}
|
||||
|
||||
/** Wipe a key slot and mark it as available.
|
||||
*
|
||||
* This does not affect persistent storage.
|
||||
*
|
||||
* \param handle The handle to the key slot to release.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||
*/
|
||||
static psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle )
|
||||
{
|
||||
psa_key_slot_t *slot;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_get_key_slot( handle, &slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
return( psa_wipe_key_slot( slot ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_allocate_key( psa_key_handle_t *handle )
|
||||
{
|
||||
*handle = 0;
|
||||
return( psa_internal_allocate_key_slot( handle ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
|
||||
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
uint8_t *key_data = NULL;
|
||||
size_t key_data_length = 0;
|
||||
|
||||
status = psa_load_persistent_key( p_slot->persistent_storage_id,
|
||||
&( p_slot )->type,
|
||||
&( p_slot )->policy, &key_data,
|
||||
&key_data_length );
|
||||
status = psa_load_persistent_key( &slot->attr,
|
||||
&key_data, &key_data_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
status = psa_import_key_into_slot( p_slot,
|
||||
key_data, key_data_length );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
|
||||
{
|
||||
psa_se_key_data_storage_t *data;
|
||||
if( key_data_length != sizeof( *data ) )
|
||||
{
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
data = (psa_se_key_data_storage_t *) key_data;
|
||||
memcpy( &slot->data.se.slot_number, &data->slot_number,
|
||||
sizeof( slot->data.se.slot_number ) );
|
||||
memcpy( &slot->attr.bits, &data->bits,
|
||||
sizeof( slot->attr.bits ) );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
{
|
||||
status = psa_import_key_into_slot( slot, key_data, key_data_length );
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_free_persistent_key_data( key_data, key_data_length );
|
||||
return( status );
|
||||
@ -176,120 +163,134 @@ exit:
|
||||
* is provided.
|
||||
*
|
||||
* \param file_id The key identifier to check.
|
||||
* \param vendor_ok Nonzero to allow key ids in the vendor range.
|
||||
* 0 to allow only key ids in the application range.
|
||||
*
|
||||
* \return 1 if \p file_id is acceptable, otherwise 0.
|
||||
*/
|
||||
static int psa_is_key_id_valid( psa_key_file_id_t file_id )
|
||||
static int psa_is_key_id_valid( psa_key_file_id_t file_id,
|
||||
int vendor_ok )
|
||||
{
|
||||
psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id );
|
||||
/* Reject id=0 because by general library conventions, 0 is an invalid
|
||||
* value wherever possible. */
|
||||
if( key_id == 0 )
|
||||
if( PSA_KEY_ID_USER_MIN <= key_id && key_id <= PSA_KEY_ID_USER_MAX )
|
||||
return( 1 );
|
||||
else if( vendor_ok &&
|
||||
PSA_KEY_ID_VENDOR_MIN <= key_id &&
|
||||
key_id <= PSA_KEY_ID_VENDOR_MAX )
|
||||
return( 1 );
|
||||
else
|
||||
return( 0 );
|
||||
/* Reject high values because the file names are reserved for the
|
||||
* library's internal use. */
|
||||
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
|
||||
return( 0 );
|
||||
return( 1 );
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
|
||||
/** Declare a slot as persistent and load it from storage.
|
||||
*
|
||||
* This function may only be called immediately after a successful call
|
||||
* to psa_internal_allocate_key_slot().
|
||||
*
|
||||
* \param handle A handle to a key slot freshly allocated with
|
||||
* psa_internal_allocate_key_slot().
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The slot content was loaded successfully.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no content for this slot in persistent storage.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p id is not acceptable.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
*/
|
||||
static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
|
||||
psa_key_file_id_t id )
|
||||
psa_status_t psa_validate_persistent_key_parameters(
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_se_drv_table_entry_t **p_drv,
|
||||
int creating )
|
||||
{
|
||||
if( p_drv != NULL )
|
||||
*p_drv = NULL;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( psa_key_lifetime_is_external( lifetime ) )
|
||||
{
|
||||
*p_drv = psa_get_se_driver_entry( lifetime );
|
||||
if( *p_drv == NULL )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
if( ! psa_is_key_id_valid( id, ! creating ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
(void) id;
|
||||
(void) creating;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
}
|
||||
|
||||
psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle )
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_key_slot_t *slot;
|
||||
psa_status_t status;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
if( ! psa_is_key_id_valid( id ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
*handle = 0;
|
||||
|
||||
status = psa_validate_persistent_key_parameters(
|
||||
PSA_KEY_LIFETIME_PERSISTENT, id, NULL, 0 );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
status = psa_get_empty_key_slot( handle, &slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
|
||||
slot->attr.id = id;
|
||||
|
||||
status = psa_load_persistent_key_into_slot( slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_wipe_key_slot( slot );
|
||||
*handle = 0;
|
||||
}
|
||||
return( status );
|
||||
|
||||
#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
(void) id;
|
||||
*handle = 0;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
}
|
||||
|
||||
psa_status_t psa_close_key( psa_key_handle_t handle )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
status = psa_get_key_slot( handle, &slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
|
||||
slot->persistent_storage_id = id;
|
||||
status = psa_load_persistent_key_into_slot( slot );
|
||||
|
||||
return( status );
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
(void) handle;
|
||||
(void) id;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
return( psa_wipe_key_slot( slot ) );
|
||||
}
|
||||
|
||||
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_key_handle_t *handle,
|
||||
psa_status_t wanted_load_status )
|
||||
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
*handle = 0;
|
||||
|
||||
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
status = psa_internal_allocate_key_slot( handle );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
status = psa_internal_make_key_persistent( *handle, id );
|
||||
if( status != wanted_load_status )
|
||||
psa_key_handle_t key;
|
||||
memset( stats, 0, sizeof( *stats ) );
|
||||
for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
|
||||
{
|
||||
psa_internal_release_key_slot( *handle );
|
||||
*handle = 0;
|
||||
const psa_key_slot_t *slot = &global_data.key_slots[key - 1];
|
||||
if( ! psa_is_key_slot_occupied( slot ) )
|
||||
{
|
||||
++stats->empty_slots;
|
||||
continue;
|
||||
}
|
||||
if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
++stats->volatile_slots;
|
||||
else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
|
||||
{
|
||||
psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id);
|
||||
++stats->persistent_slots;
|
||||
if( id > stats->max_open_internal_key_id )
|
||||
stats->max_open_internal_key_id = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id);
|
||||
++stats->external_slots;
|
||||
if( id > stats->max_open_external_key_id )
|
||||
stats->max_open_external_key_id = id;
|
||||
}
|
||||
}
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_key_handle_t *handle )
|
||||
{
|
||||
return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_create_key( psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_key_handle_t *handle )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
status = persistent_key_setup( lifetime, id, handle,
|
||||
PSA_ERROR_DOES_NOT_EXIST );
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS: return( PSA_ERROR_ALREADY_EXISTS );
|
||||
case PSA_ERROR_DOES_NOT_EXIST: return( PSA_SUCCESS );
|
||||
default: return( status );
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_close_key( psa_key_handle_t handle )
|
||||
{
|
||||
return( psa_internal_release_key_slot( handle ) );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
@ -22,6 +22,9 @@
|
||||
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
/* Number of key slots (plus one because 0 is not used).
|
||||
* The value is a compile-time constant for now, for simplicity. */
|
||||
#define PSA_KEY_SLOT_COUNT 32
|
||||
@ -55,4 +58,72 @@ psa_status_t psa_initialize_key_slots( void );
|
||||
* This does not affect persistent storage. */
|
||||
void psa_wipe_all_key_slots( void );
|
||||
|
||||
/** Find a free key slot.
|
||||
*
|
||||
* This function returns a key slot that is available for use and is in its
|
||||
* ground state (all-bits-zero).
|
||||
*
|
||||
* \param[out] handle On success, a slot number that can be used as a
|
||||
* handle to the slot.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
*/
|
||||
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
|
||||
psa_key_slot_t **p_slot );
|
||||
|
||||
/** Test whether a lifetime designates a key in an external cryptoprocessor.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The lifetime designates an external key. There should be a
|
||||
* registered driver for this lifetime, otherwise the key cannot
|
||||
* be created or manipulated.
|
||||
* \retval 0
|
||||
* The lifetime designates a key that is volatile or in internal
|
||||
* storage.
|
||||
*/
|
||||
static inline int psa_key_lifetime_is_external( psa_key_lifetime_t lifetime )
|
||||
{
|
||||
return( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
|
||||
lifetime != PSA_KEY_LIFETIME_PERSISTENT );
|
||||
}
|
||||
|
||||
/** Test whether the given parameters are acceptable for a persistent key.
|
||||
*
|
||||
* This function does not access the storage in any way. It only tests
|
||||
* whether the parameters are meaningful and permitted by general policy.
|
||||
* It does not test whether the a file by the given id exists or could be
|
||||
* created.
|
||||
*
|
||||
* If the key is in external storage, this function returns the corresponding
|
||||
* driver.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
* \param id The key id to test.
|
||||
* \param[out] p_drv On output, if \p lifetime designates a key
|
||||
* in an external processor, \c *p_drv is a pointer
|
||||
* to the driver table entry fot this lifetime.
|
||||
* If \p lifetime designates a transparent key,
|
||||
* \c *p_drv is \c NULL.
|
||||
* \param creating 0 if attempting to open an existing key.
|
||||
* Nonzero if attempting to create a key.
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* The given parameters are valid.
|
||||
* \retval PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p lifetime is volatile or is invalid.
|
||||
* \retval PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p id is invalid.
|
||||
*/
|
||||
psa_status_t psa_validate_persistent_key_parameters(
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_se_drv_table_entry_t **p_drv,
|
||||
int creating );
|
||||
|
||||
|
||||
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|
||||
|
@ -50,6 +50,12 @@
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key storage */
|
||||
/****************************************************************/
|
||||
|
||||
/* Determine a file name (ITS file identifier) for the given key file
|
||||
* identifier. The file name must be distinct from any file that is used
|
||||
* for a purpose other than storing a key. Currently, the only such file
|
||||
@ -224,7 +230,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_LE
|
||||
#define GET_UINT32_LE(n,b,i) \
|
||||
#define GET_UINT32_LE( n, b, i ) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||
@ -234,7 +240,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_LE
|
||||
#define PUT_UINT32_LE(n,b,i) \
|
||||
#define PUT_UINT32_LE( n, b, i ) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
|
||||
@ -252,6 +258,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
||||
typedef struct {
|
||||
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
||||
uint8_t version[4];
|
||||
uint8_t lifetime[sizeof( psa_key_lifetime_t )];
|
||||
uint8_t type[sizeof( psa_key_type_t )];
|
||||
uint8_t policy[sizeof( psa_key_policy_t )];
|
||||
uint8_t data_len[4];
|
||||
@ -260,20 +267,20 @@ typedef struct {
|
||||
|
||||
void psa_format_key_data_for_storage( const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
uint8_t *storage_data )
|
||||
{
|
||||
psa_persistent_key_storage_format *storage_format =
|
||||
(psa_persistent_key_storage_format *) storage_data;
|
||||
|
||||
memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
|
||||
PUT_UINT32_LE(0, storage_format->version, 0);
|
||||
PUT_UINT32_LE(type, storage_format->type, 0);
|
||||
PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
|
||||
PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
|
||||
PUT_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE(data_length, storage_format->data_len, 0);
|
||||
PUT_UINT32_LE( 0, storage_format->version, 0 );
|
||||
PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
|
||||
PUT_UINT32_LE( attr->type, storage_format->type, 0 );
|
||||
PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
|
||||
PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
|
||||
memcpy( storage_format->key_data, data, data_length );
|
||||
}
|
||||
|
||||
@ -289,8 +296,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy )
|
||||
psa_core_key_attributes_t *attr )
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
@ -304,32 +310,37 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
GET_UINT32_LE(version, storage_format->version, 0);
|
||||
GET_UINT32_LE( version, storage_format->version, 0 );
|
||||
if( version != 0 )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
|
||||
GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
|
||||
GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 );
|
||||
if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
|
||||
*key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
|
||||
*key_data = mbedtls_calloc( 1, *key_data_length );
|
||||
if( *key_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
if( *key_data_length == 0 )
|
||||
{
|
||||
*key_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*key_data = mbedtls_calloc( 1, *key_data_length );
|
||||
if( *key_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
memcpy( *key_data, storage_format->key_data, *key_data_length );
|
||||
}
|
||||
|
||||
GET_UINT32_LE(*type, storage_format->type, 0);
|
||||
GET_UINT32_LE(policy->usage, storage_format->policy, 0);
|
||||
GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
|
||||
GET_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ));
|
||||
|
||||
memcpy( *key_data, storage_format->key_data, *key_data_length );
|
||||
GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
|
||||
GET_UINT32_LE( attr->type, storage_format->type, 0 );
|
||||
GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
|
||||
GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
|
||||
GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length )
|
||||
{
|
||||
@ -345,10 +356,9 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
if( storage_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
psa_format_key_data_for_storage( data, data_length, type, policy,
|
||||
storage_data );
|
||||
psa_format_key_data_for_storage( data, data_length, attr, storage_data );
|
||||
|
||||
status = psa_crypto_storage_store( key,
|
||||
status = psa_crypto_storage_store( attr->id,
|
||||
storage_data, storage_data_length );
|
||||
|
||||
mbedtls_free( storage_data );
|
||||
@ -365,15 +375,14 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
|
||||
mbedtls_free( key_data );
|
||||
}
|
||||
|
||||
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy,
|
||||
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
uint8_t *loaded_data;
|
||||
size_t storage_data_length = 0;
|
||||
psa_key_id_t key = attr->id;
|
||||
|
||||
status = psa_crypto_storage_get_data_length( key, &storage_data_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
@ -389,13 +398,74 @@ psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
|
||||
goto exit;
|
||||
|
||||
status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
|
||||
data, data_length, type, policy );
|
||||
data, data_length, attr );
|
||||
|
||||
exit:
|
||||
mbedtls_free( loaded_data );
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Transactions */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
psa_status_t psa_crypto_save_transaction( void )
|
||||
{
|
||||
struct psa_storage_info_t p_info;
|
||||
psa_status_t status;
|
||||
status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
|
||||
if( status == PSA_SUCCESS )
|
||||
{
|
||||
/* This shouldn't happen: we're trying to start a transaction while
|
||||
* there is still a transaction that hasn't been replayed. */
|
||||
return( PSA_ERROR_CORRUPTION_DETECTED );
|
||||
}
|
||||
else if( status != PSA_ERROR_DOES_NOT_EXIST )
|
||||
return( status );
|
||||
return( psa_its_set( PSA_CRYPTO_ITS_TRANSACTION_UID,
|
||||
sizeof( psa_crypto_transaction ),
|
||||
&psa_crypto_transaction,
|
||||
0 ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_load_transaction( void )
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t length;
|
||||
status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
|
||||
sizeof( psa_crypto_transaction ),
|
||||
&psa_crypto_transaction, &length );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
if( length != sizeof( psa_crypto_transaction ) )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_stop_transaction( void )
|
||||
{
|
||||
psa_status_t status = psa_its_remove( PSA_CRYPTO_ITS_TRANSACTION_UID );
|
||||
/* Whether or not updating the storage succeeded, the transaction is
|
||||
* finished now. It's too late to go back, so zero out the in-memory
|
||||
* data. */
|
||||
memset( &psa_crypto_transaction, 0, sizeof( psa_crypto_transaction ) );
|
||||
return( status );
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Random generator state */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
|
||||
size_t seed_size )
|
||||
@ -418,4 +488,10 @@ psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
|
@ -29,20 +29,20 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
|
||||
* in each of its header files. */
|
||||
#if defined(MBEDTLS_CONFIG_FILE)
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#else
|
||||
#include "mbedtls/config.h"
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <stdint.h>
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/* Limit the maximum key size to 30kB (just in case someone tries to
|
||||
* inadvertently store an obscene amount of data) */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Limit the maximum key size in storage. This should have no effect
|
||||
* since the key size is limited in memory. */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( PSA_BITS_TO_BYTES( PSA_MAX_KEY_BITS ) )
|
||||
/* Sanity check: a file size must fit in 32 bits. Allow a generous
|
||||
* 64kB of metadata. */
|
||||
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#error PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#endif
|
||||
|
||||
/** The maximum permitted persistent slot number.
|
||||
*
|
||||
@ -59,7 +59,7 @@ extern "C" {
|
||||
* This limitation will probably become moot when we implement client
|
||||
* separation for key storage.
|
||||
*/
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
|
||||
|
||||
/**
|
||||
* \brief Checks if persistent data is stored for the given key slot number
|
||||
@ -88,12 +88,11 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
|
||||
* already occupied non-persistent key, as well as validating the key data.
|
||||
*
|
||||
*
|
||||
* \param key Persistent identifier of the key to be stored. This
|
||||
* should be an unoccupied storage location.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[in] policy The key policy to save.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length The number of bytes that make up the key data.
|
||||
* \param[in] attr The attributes of the key to save.
|
||||
* The key identifier field in the attributes
|
||||
* determines the key's location.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length The number of bytes that make up the key data.
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
@ -101,9 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
|
||||
* \retval PSA_ERROR_STORAGE_FAILURE
|
||||
* \retval PSA_ERROR_ALREADY_EXISTS
|
||||
*/
|
||||
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length );
|
||||
|
||||
@ -119,11 +116,10 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
* this function to zeroize and free this buffer, regardless of whether this
|
||||
* function succeeds or fails.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be loaded. This
|
||||
* should be an occupied storage location.
|
||||
* \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX
|
||||
* value).
|
||||
* \param[out] policy On success, the key's policy.
|
||||
* \param[in,out] attr On input, the key identifier field identifies
|
||||
* the key to load. Other fields are ignored.
|
||||
* On success, the attribute structure contains
|
||||
* the key metadata that was loaded from storage.
|
||||
* \param[out] data Pointer to an allocated key data buffer on return.
|
||||
* \param[out] data_length The number of bytes that make up the key data.
|
||||
*
|
||||
@ -132,9 +128,7 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
* \retval PSA_ERROR_STORAGE_FAILURE
|
||||
* \retval PSA_ERROR_DOES_NOT_EXIST
|
||||
*/
|
||||
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy,
|
||||
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length );
|
||||
|
||||
@ -166,17 +160,15 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length );
|
||||
/**
|
||||
* \brief Formats key data and metadata for persistent storage
|
||||
*
|
||||
* \param[in] data Buffer for the key data.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length Length of the key data buffer.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param policy The key policy.
|
||||
* \param[in] attr The core attributes of the key.
|
||||
* \param[out] storage_data Output buffer for the formatted data.
|
||||
*
|
||||
*/
|
||||
void psa_format_key_data_for_storage( const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
uint8_t *storage_data );
|
||||
|
||||
/**
|
||||
@ -188,8 +180,8 @@ void psa_format_key_data_for_storage( const uint8_t *data,
|
||||
* containing the key data. This must be freed
|
||||
* using psa_free_persistent_key_data()
|
||||
* \param[out] key_data_length Length of the key data buffer
|
||||
* \param[out] type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[out] policy The key policy.
|
||||
* \param[out] attr On success, the attribute structure is filled
|
||||
* with the loaded key metadata.
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
@ -200,8 +192,180 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy );
|
||||
psa_core_key_attributes_t *attr );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** This symbol is defined if transaction support is required. */
|
||||
#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS
|
||||
#endif
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
/** The type of transaction that is in progress.
|
||||
*/
|
||||
/* This is an integer type rather than an enum for two reasons: to support
|
||||
* unknown values when loading a transaction file, and to ensure that the
|
||||
* type has a known size.
|
||||
*/
|
||||
typedef uint16_t psa_crypto_transaction_type_t;
|
||||
|
||||
/** No transaction is in progress.
|
||||
*
|
||||
* This has the value 0, so zero-initialization sets a transaction's type to
|
||||
* this value.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
|
||||
|
||||
/** A key creation transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are created atomically in storage
|
||||
* (simple file creation), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ( (psa_crypto_transaction_type_t) 0x0001 )
|
||||
|
||||
/** A key destruction transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are destroyed atomically in storage
|
||||
* (simple file deletion), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ( (psa_crypto_transaction_type_t) 0x0002 )
|
||||
|
||||
/** Transaction data.
|
||||
*
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
* and reading it back on the same device.
|
||||
*
|
||||
* \note The transaction mechanism is designed for a single active transaction
|
||||
* at a time. The transaction object is #psa_crypto_transaction.
|
||||
*
|
||||
* \note If an API call starts a transaction, it must complete this transaction
|
||||
* before returning to the application.
|
||||
*
|
||||
* The lifetime of a transaction is the following (note that only one
|
||||
* transaction may be active at a time):
|
||||
*
|
||||
* -# Call psa_crypto_prepare_transaction() to initialize the transaction
|
||||
* object in memory and declare the type of transaction that is starting.
|
||||
* -# Fill in the type-specific fields of #psa_crypto_transaction.
|
||||
* -# Call psa_crypto_save_transaction() to start the transaction. This
|
||||
* saves the transaction data to internal storage.
|
||||
* -# Perform the work of the transaction by modifying files, contacting
|
||||
* external entities, or whatever needs doing. Note that the transaction
|
||||
* may be interrupted by a power failure, so you need to have a way
|
||||
* recover from interruptions either by undoing what has been done
|
||||
* so far or by resuming where you left off.
|
||||
* -# If there are intermediate stages in the transaction, update
|
||||
* the fields of #psa_crypto_transaction and call
|
||||
* psa_crypto_save_transaction() again when each stage is reached.
|
||||
* -# When the transaction is over, call psa_crypto_stop_transaction() to
|
||||
* remove the transaction data in storage and in memory.
|
||||
*
|
||||
* If the system crashes while a transaction is in progress, psa_crypto_init()
|
||||
* calls psa_crypto_load_transaction() and takes care of completing or
|
||||
* rewinding the transaction. This is done in psa_crypto_recover_transaction()
|
||||
* in psa_crypto.c. If you add a new type of transaction, be
|
||||
* sure to add code for it in psa_crypto_recover_transaction().
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/* Each element of this union must have the following properties
|
||||
* to facilitate serialization and deserialization:
|
||||
*
|
||||
* - The element is a struct.
|
||||
* - The first field of the struct is `psa_crypto_transaction_type_t type`.
|
||||
* - Elements of the struct are arranged such a way that there is
|
||||
* no padding.
|
||||
*/
|
||||
struct psa_crypto_transaction_unknown_s
|
||||
{
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
uint32_t unused2;
|
||||
uint64_t unused3;
|
||||
uint64_t unused4;
|
||||
} unknown;
|
||||
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
|
||||
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
|
||||
struct psa_crypto_transaction_key_s
|
||||
{
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_slot_number_t slot;
|
||||
psa_key_id_t id;
|
||||
} key;
|
||||
} psa_crypto_transaction_t;
|
||||
|
||||
/** The single active transaction.
|
||||
*/
|
||||
extern psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
/** Prepare for a transaction.
|
||||
*
|
||||
* There must not be an ongoing transaction.
|
||||
*
|
||||
* \param type The type of transaction to start.
|
||||
*/
|
||||
static inline void psa_crypto_prepare_transaction(
|
||||
psa_crypto_transaction_type_t type )
|
||||
{
|
||||
psa_crypto_transaction.unknown.type = type;
|
||||
}
|
||||
|
||||
/** Save the transaction data to storage.
|
||||
*
|
||||
* You may call this function multiple times during a transaction to
|
||||
* atomically update the transaction state.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
*/
|
||||
psa_status_t psa_crypto_save_transaction( void );
|
||||
|
||||
/** Load the transaction data from storage, if any.
|
||||
*
|
||||
* This function is meant to be called from psa_crypto_init() to recover
|
||||
* in case a transaction was interrupted by a system crash.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The data about the ongoing transaction has been loaded to
|
||||
* #psa_crypto_transaction.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no ongoing transaction.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
*/
|
||||
psa_status_t psa_crypto_load_transaction( void );
|
||||
|
||||
/** Indicate that the current transaction is finished.
|
||||
*
|
||||
* Call this function at the very end of transaction processing.
|
||||
* This function does not "commit" or "abort" the transaction: the storage
|
||||
* subsystem has no concept of "commit" and "abort", just saving and
|
||||
* removing the transaction information in storage.
|
||||
*
|
||||
* This function erases the transaction data in storage (if any) and
|
||||
* resets the transaction data in memory.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* There was transaction data in storage.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There was no transaction data in storage.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
* It was impossible to determine whether there was transaction data
|
||||
* in storage, or the transaction data could not be erased.
|
||||
*/
|
||||
psa_status_t psa_crypto_stop_transaction( void );
|
||||
|
||||
/** The ITS file identifier for the transaction data.
|
||||
*
|
||||
* 0xffffffNN = special file; 0x74 = 't' for transaction.
|
||||
*/
|
||||
#define PSA_CRYPTO_ITS_TRANSACTION_UID ( (psa_key_id_t) 0xffffff74 )
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
/** Backend side of mbedtls_psa_inject_entropy().
|
||||
|
@ -92,6 +92,15 @@
|
||||
}
|
||||
#endif /* PUT_UINT64_BE */
|
||||
|
||||
#if defined(MBEDTLS_SHA512_SMALLER)
|
||||
static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
|
||||
{
|
||||
PUT_UINT64_BE(n, b, i);
|
||||
}
|
||||
#else
|
||||
#define sha512_put_uint64_be PUT_UINT64_BE
|
||||
#endif /* MBEDTLS_SHA512_SMALLER */
|
||||
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
SHA512_VALIDATE( ctx != NULL );
|
||||
@ -219,7 +228,7 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
uint64_t A[8];
|
||||
|
||||
SHA512_VALIDATE_RET( ctx != NULL );
|
||||
SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
|
||||
@ -244,6 +253,28 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
|
||||
(d) += temp1; (h) = temp1 + temp2; \
|
||||
} while( 0 )
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
A[i] = ctx->state[i];
|
||||
|
||||
#if defined(MBEDTLS_SHA512_SMALLER)
|
||||
for( i = 0; i < 80; i++ )
|
||||
{
|
||||
if( i < 16 )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
|
||||
|
||||
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
|
||||
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
|
||||
}
|
||||
#else /* MBEDTLS_SHA512_SMALLER */
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
@ -255,37 +286,23 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
#endif /* MBEDTLS_SHA512_SMALLER */
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
for( i = 0; i < 8; i++ )
|
||||
ctx->state[i] += A[i];
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -403,8 +420,8 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, ctx->buffer, 112 );
|
||||
PUT_UINT64_BE( low, ctx->buffer, 120 );
|
||||
sha512_put_uint64_be( high, ctx->buffer, 112 );
|
||||
sha512_put_uint64_be( low, ctx->buffer, 120 );
|
||||
|
||||
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
|
||||
return( ret );
|
||||
@ -412,17 +429,17 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
|
||||
/*
|
||||
* Output final state
|
||||
*/
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
sha512_put_uint64_be( ctx->state[0], output, 0 );
|
||||
sha512_put_uint64_be( ctx->state[1], output, 8 );
|
||||
sha512_put_uint64_be( ctx->state[2], output, 16 );
|
||||
sha512_put_uint64_be( ctx->state[3], output, 24 );
|
||||
sha512_put_uint64_be( ctx->state[4], output, 32 );
|
||||
sha512_put_uint64_be( ctx->state[5], output, 40 );
|
||||
|
||||
if( ctx->is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
sha512_put_uint64_be( ctx->state[6], output, 48 );
|
||||
sha512_put_uint64_be( ctx->state[7], output, 56 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
|
@ -51,7 +51,6 @@
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#include <process.h>
|
||||
|
||||
struct _hr_time
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static const char *features[] = {
|
||||
static const char * const features[] = {
|
||||
#if defined(MBEDTLS_VERSION_FEATURES)
|
||||
#if defined(MBEDTLS_HAVE_ASM)
|
||||
"MBEDTLS_HAVE_ASM",
|
||||
@ -90,6 +90,9 @@ static const char *features[] = {
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
"MBEDTLS_CHECK_PARAMS",
|
||||
#endif /* MBEDTLS_CHECK_PARAMS */
|
||||
#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
|
||||
"MBEDTLS_CHECK_PARAMS_ASSERT",
|
||||
#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
|
||||
#if defined(MBEDTLS_TIMING_ALT)
|
||||
"MBEDTLS_TIMING_ALT",
|
||||
#endif /* MBEDTLS_TIMING_ALT */
|
||||
@ -405,6 +408,9 @@ static const char *features[] = {
|
||||
#if defined(MBEDTLS_SHA256_SMALLER)
|
||||
"MBEDTLS_SHA256_SMALLER",
|
||||
#endif /* MBEDTLS_SHA256_SMALLER */
|
||||
#if defined(MBEDTLS_SHA512_SMALLER)
|
||||
"MBEDTLS_SHA512_SMALLER",
|
||||
#endif /* MBEDTLS_SHA512_SMALLER */
|
||||
#if defined(MBEDTLS_THREADING_ALT)
|
||||
"MBEDTLS_THREADING_ALT",
|
||||
#endif /* MBEDTLS_THREADING_ALT */
|
||||
@ -555,6 +561,9 @@ static const char *features[] = {
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
"MBEDTLS_PSA_CRYPTO_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
"MBEDTLS_PSA_CRYPTO_SE_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
"MBEDTLS_PSA_CRYPTO_STORAGE_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
@ -594,7 +603,7 @@ static const char *features[] = {
|
||||
|
||||
int mbedtls_version_check_feature( const char *feature )
|
||||
{
|
||||
const char **idx = features;
|
||||
const char * const *idx = features;
|
||||
|
||||
if( *idx == NULL )
|
||||
return( -2 );
|
||||
|
@ -2,8 +2,8 @@
|
||||
# To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
|
||||
|
||||
CFLAGS ?= -O2
|
||||
WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement
|
||||
WARNING_CXXFLAGS ?= -Wall -W
|
||||
WARNING_CFLAGS ?= -Wall -Wextra
|
||||
WARNING_CXXFLAGS ?= -Wall -Wextra
|
||||
LDFLAGS ?=
|
||||
|
||||
LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../include -D_FILE_OFFSET_BITS=64
|
||||
@ -11,6 +11,9 @@ LOCAL_CXXFLAGS = $(WARNING_CXXFLAGS) -I../include -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_LDFLAGS = -L../library \
|
||||
-lmbedcrypto$(SHARED_SUFFIX)
|
||||
|
||||
include ../3rdparty/Makefile.inc
|
||||
LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES)
|
||||
|
||||
ifndef SHARED
|
||||
DEP=../library/libmbedcrypto.a
|
||||
else
|
||||
@ -244,6 +247,7 @@ psa/crypto_examples$(EXEXT): psa/crypto_examples.c $(DEP)
|
||||
clean:
|
||||
ifndef WINDOWS
|
||||
rm -f $(APPS) $(EXTRA_GENERATED)
|
||||
-rm -f test/cpp_dummy_build$(EXEXT)
|
||||
else
|
||||
if exist *.o del /S /Q /F *.o
|
||||
if exist *.exe del /S /Q /F *.exe
|
||||
|
@ -80,17 +80,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -82,17 +82,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -52,17 +52,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
static int generic_wrapper( const mbedtls_md_info_t *md_info, char *filename, unsigned char *sum )
|
||||
{
|
||||
|
@ -48,17 +48,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( void )
|
||||
{
|
||||
|
@ -69,17 +69,6 @@ int main( void )
|
||||
*/
|
||||
#define GENERATOR "4"
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
@ -53,17 +53,6 @@ int main( void )
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -100,17 +100,6 @@ static void dump_pubkey( const char *title, mbedtls_ecdsa_context *key )
|
||||
#define dump_pubkey( a, b )
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -137,17 +137,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global options
|
||||
|
@ -64,7 +64,6 @@
|
||||
" password_file=%%s default: \"\"\n" \
|
||||
"\n"
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_BIGNUM_C) || \
|
||||
!defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO)
|
||||
int main( void )
|
||||
@ -75,17 +74,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global options
|
||||
|
@ -98,17 +98,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global options
|
||||
|
@ -50,17 +50,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( void )
|
||||
{
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_PK_PARSE_C) || \
|
||||
!defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \
|
||||
!defined(MBEDTLS_CTR_DRBG_C)
|
||||
@ -61,17 +60,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -61,17 +61,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -60,17 +60,6 @@ int main( void )
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
@ -56,17 +56,6 @@ int main( void )
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
@ -112,7 +101,6 @@ int main( int argc, char *argv[] )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
i = fread( buf, 1, sizeof(buf), f );
|
||||
|
||||
fclose( f );
|
||||
|
@ -59,17 +59,6 @@ int main( void )
|
||||
}
|
||||
#else
|
||||
|
||||
#if defined(MBEDTLS_CHECK_PARAMS)
|
||||
#include "mbedtls/platform_util.h"
|
||||
void mbedtls_param_failed( const char *failure_condition,
|
||||
const char *file,
|
||||
int line )
|
||||
{
|
||||
mbedtls_printf( "%s:%i: Input param failed - %s\n",
|
||||
file, line, failure_condition );
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user