feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -59,18 +59,6 @@
|
|||
// Disable deprecated
|
||||
#define MBEDTLS_DEPRECATED_REMOVED
|
||||
|
||||
// mbedTLS 3.6 finally enabled TLSv1.3 by default, but it requires some mobule
|
||||
// changes, and to enable PSA crypto (new "standard" API specification).
|
||||
// Disable it for now.
|
||||
#undef MBEDTLS_SSL_PROTO_TLS1_3
|
||||
|
||||
// Disable PSA Crypto.
|
||||
#undef MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
#undef MBEDTLS_PSA_CRYPTO_C
|
||||
#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
#undef MBEDTLS_PSA_ITS_FILE_C
|
||||
#undef MBEDTLS_LMS_C
|
||||
|
||||
#endif // GODOT_MBEDTLS_INCLUDE_H
|
||||
|
||||
#endif // GODOT_MODULE_MBEDTLS_CONFIG_H
|
||||
|
|
|
|||
|
|
@ -880,7 +880,7 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A,
|
|||
mbedtls_mpi_sint b);
|
||||
|
||||
/**
|
||||
* \brief Perform a sliding-window exponentiation: X = A^E mod N
|
||||
* \brief Perform a modular exponentiation: X = A^E mod N
|
||||
*
|
||||
* \param X The destination MPI. This must point to an initialized MPI.
|
||||
* This must not alias E or N.
|
||||
|
|
|
|||
|
|
@ -26,16 +26,16 @@
|
|||
*/
|
||||
#define MBEDTLS_VERSION_MAJOR 3
|
||||
#define MBEDTLS_VERSION_MINOR 6
|
||||
#define MBEDTLS_VERSION_PATCH 0
|
||||
#define MBEDTLS_VERSION_PATCH 2
|
||||
|
||||
/**
|
||||
* The single version number has the following structure:
|
||||
* MMNNPP00
|
||||
* Major version | Minor version | Patch version
|
||||
*/
|
||||
#define MBEDTLS_VERSION_NUMBER 0x03060000
|
||||
#define MBEDTLS_VERSION_STRING "3.6.0"
|
||||
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.0"
|
||||
#define MBEDTLS_VERSION_NUMBER 0x03060200
|
||||
#define MBEDTLS_VERSION_STRING "3.6.2"
|
||||
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.2"
|
||||
|
||||
/* Macros for build-time platform detection */
|
||||
|
||||
|
|
@ -101,6 +101,13 @@
|
|||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Something went wrong: MBEDTLS_CONFIG_FILES_READ defined before reading the config files!"
|
||||
#endif
|
||||
#if defined(MBEDTLS_CONFIG_IS_FINALIZED)
|
||||
#error "Something went wrong: MBEDTLS_CONFIG_IS_FINALIZED defined before reading the config files!"
|
||||
#endif
|
||||
|
||||
/* X.509, TLS and non-PSA crypto configuration */
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/mbedtls_config.h"
|
||||
|
|
@ -135,6 +142,12 @@
|
|||
#endif
|
||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
|
||||
|
||||
/* Indicate that all configuration files have been read.
|
||||
* It is now time to adjust the configuration (follow through on dependencies,
|
||||
* make PSA and legacy crypto consistent, etc.).
|
||||
*/
|
||||
#define MBEDTLS_CONFIG_FILES_READ
|
||||
|
||||
/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if
|
||||
* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined
|
||||
* to ensure a 128-bit key size in CTR_DRBG.
|
||||
|
|
@ -169,8 +182,13 @@
|
|||
|
||||
#include "mbedtls/config_adjust_ssl.h"
|
||||
|
||||
/* Make sure all configuration symbols are set before including check_config.h,
|
||||
* even the ones that are calculated programmatically. */
|
||||
/* Indicate that all configuration symbols are set,
|
||||
* even the ones that are calculated programmatically.
|
||||
* It is now safe to query the configuration (to check it, to size buffers,
|
||||
* etc.).
|
||||
*/
|
||||
#define MBEDTLS_CONFIG_IS_FINALIZED
|
||||
|
||||
#include "mbedtls/check_config.h"
|
||||
|
||||
#endif /* MBEDTLS_BUILD_INFO_H */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
* \file check_config.h
|
||||
*
|
||||
* \brief Consistency checks for configuration options
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* This header is included automatically by all public Mbed TLS headers
|
||||
* (via mbedtls/build_info.h). Do not include it directly in a configuration
|
||||
* file such as mbedtls/mbedtls_config.h or #MBEDTLS_USER_CONFIG_FILE!
|
||||
* It would run at the wrong time due to missing derived symbols.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
|
|
@ -12,6 +19,13 @@
|
|||
#define MBEDTLS_CHECK_CONFIG_H
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_IS_FINALIZED)
|
||||
#warning "Do not include mbedtls/check_config.h manually! " \
|
||||
"This may cause spurious errors. " \
|
||||
"It is included automatically at the right point since Mbed TLS 3.0."
|
||||
#endif /* !MBEDTLS_CONFIG_IS_FINALIZED */
|
||||
|
||||
/*
|
||||
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
|
||||
* target platforms, so not an issue, but let's just be extra sure.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
* \file mbedtls/config_adjust_legacy_crypto.h
|
||||
* \brief Adjust legacy configuration configuration
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDTLS_xxx
|
||||
* configurations need to be explicitly enabled by the user: enabling
|
||||
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
|
||||
* compilation error. However, we do automatically enable certain options
|
||||
|
|
@ -22,6 +24,14 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/* Ideally, we'd set those as defaults in mbedtls_config.h, but
|
||||
* putting an #ifdef _WIN32 in mbedtls_config.h would confuse config.py.
|
||||
*
|
||||
|
|
@ -48,7 +58,8 @@
|
|||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG))
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC))
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#endif
|
||||
|
||||
|
|
@ -293,6 +304,14 @@
|
|||
#define MBEDTLS_ECP_LIGHT
|
||||
#endif
|
||||
|
||||
/* Backward compatibility: after #8740 the RSA module offers functions to parse
|
||||
* and write RSA private/public keys without relying on the PK one. Of course
|
||||
* this needs ASN1 support to do so, so we enable it here. */
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in Mbed TLS version 3.5, while
|
||||
* in previous version compressed points were automatically supported as long
|
||||
* as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward
|
||||
|
|
@ -409,12 +428,12 @@
|
|||
|
||||
/* psa_util file features some ECDSA conversion functions, to convert between
|
||||
* legacy's ASN.1 DER format and PSA's raw one. */
|
||||
#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||
#if (defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
|
||||
(defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)))
|
||||
#define MBEDTLS_PSA_UTIL_HAVE_ECDSA
|
||||
#endif
|
||||
|
||||
/* Some internal helpers to determine which keys are availble. */
|
||||
/* Some internal helpers to determine which keys are available. */
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
|
||||
#define MBEDTLS_SSL_HAVE_AES
|
||||
|
|
@ -428,7 +447,7 @@
|
|||
#define MBEDTLS_SSL_HAVE_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* Some internal helpers to determine which operation modes are availble. */
|
||||
/* Some internal helpers to determine which operation modes are available. */
|
||||
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING))
|
||||
#define MBEDTLS_SSL_HAVE_CBC
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file mbedtls/config_adjust_legacy_from_psa.h
|
||||
* \brief Adjust PSA configuration: activate legacy implementations
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* When MBEDTLS_PSA_CRYPTO_CONFIG is enabled, activate legacy implementations
|
||||
* of cryptographic mechanisms as needed to fulfill the needs of the PSA
|
||||
* configuration. Generally speaking, we activate a legacy mechanism if
|
||||
|
|
@ -16,6 +18,14 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/* Define appropriate ACCEL macros for the p256-m driver.
|
||||
* In the future, those should be generated from the drivers JSON description.
|
||||
*/
|
||||
|
|
@ -498,7 +508,6 @@
|
|||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */
|
||||
#endif /* PSA_WANT_ALG_HKDF */
|
||||
|
|
@ -509,7 +518,6 @@
|
|||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */
|
||||
#endif /* PSA_WANT_ALG_HKDF_EXTRACT */
|
||||
|
|
@ -520,7 +528,6 @@
|
|||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */
|
||||
#endif /* PSA_WANT_ALG_HKDF_EXPAND */
|
||||
|
|
@ -630,9 +637,6 @@
|
|||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1
|
||||
#define PSA_HAVE_SOFT_PBKDF2_HMAC 1
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
|
||||
#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file mbedtls/config_adjust_psa_from_legacy.h
|
||||
* \brief Adjust PSA configuration: construct PSA configuration from legacy
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* When MBEDTLS_PSA_CRYPTO_CONFIG is disabled, we automatically enable
|
||||
* cryptographic mechanisms through the PSA interface when the corresponding
|
||||
* legacy mechanism is enabled. In many cases, this just enables the PSA
|
||||
|
|
@ -18,6 +20,14 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/*
|
||||
* Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
* is not defined
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file mbedtls/config_adjust_psa_superset_legacy.h
|
||||
* \brief Adjust PSA configuration: automatic enablement from legacy
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* To simplify some edge cases, we automatically enable certain cryptographic
|
||||
* mechanisms in the PSA API if they are enabled in the legacy API. The general
|
||||
* idea is that if legacy module M uses mechanism A internally, and A has
|
||||
|
|
@ -17,6 +19,14 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/****************************************************************/
|
||||
/* Hashes that are built in are also enabled in PSA.
|
||||
* This simplifies dependency declarations especially
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
* \file mbedtls/config_adjust_ssl.h
|
||||
* \brief Adjust TLS configuration
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDTLS_xxx
|
||||
* configurations need to be explicitly enabled by the user: enabling
|
||||
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
|
||||
* compilation error. However, we do automatically enable certain options
|
||||
|
|
@ -22,6 +24,14 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_SSL_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_SSL_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/* The following blocks make it easier to disable all of TLS,
|
||||
* or of TLS 1.2 or 1.3 or DTLS, without having to manually disable all
|
||||
* key exchanges, options and extensions related to them. */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
* \file mbedtls/config_adjust_x509.h
|
||||
* \brief Adjust X.509 configuration
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDLTS_xxx
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDTLS_xxx
|
||||
* configurations need to be explicitly enabled by the user: enabling
|
||||
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
|
||||
* compilation error. However, we do automatically enable certain options
|
||||
|
|
@ -22,4 +24,12 @@
|
|||
#ifndef MBEDTLS_CONFIG_ADJUST_X509_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_X509_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_X509_H */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "psa/crypto_adjust_config_synonyms.h"
|
||||
|
||||
#include "psa/crypto_adjust_config_dependencies.h"
|
||||
|
||||
#include "mbedtls/config_adjust_psa_superset_legacy.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
|
||||
|
|
@ -32,7 +34,11 @@
|
|||
* before we deduce what built-ins are required. */
|
||||
#include "psa/crypto_adjust_config_key_pair_types.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
/* If we are implementing PSA crypto ourselves, then we want to enable the
|
||||
* required built-ins. Otherwise, PSA features will be provided by the server. */
|
||||
#include "mbedtls/config_adjust_legacy_from_psa.h"
|
||||
#endif
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_CONFIG */
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,27 @@
|
|||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
/* In case AES_C is defined then it is the primary option for backward
|
||||
* compatibility purposes. If that's not available, PSA is used instead */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#include "mbedtls/aes.h"
|
||||
#else
|
||||
/* The CTR_DRBG implementation can either directly call the low-level AES
|
||||
* module (gated by MBEDTLS_AES_C) or call the PSA API to perform AES
|
||||
* operations. Calling the AES module directly is the default, both for
|
||||
* maximum backward compatibility and because it's a bit more efficient
|
||||
* (less glue code).
|
||||
*
|
||||
* When MBEDTLS_AES_C is disabled, the CTR_DRBG module calls PSA crypto and
|
||||
* thus benefits from the PSA AES accelerator driver.
|
||||
* It is technically possible to enable MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO
|
||||
* to use PSA even when MBEDTLS_AES_C is enabled, but there is very little
|
||||
* reason to do so other than testing purposes and this is not officially
|
||||
* supported.
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#define MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#else
|
||||
#include "mbedtls/aes.h"
|
||||
#endif
|
||||
|
||||
#include "entropy.h"
|
||||
|
|
@ -157,7 +172,7 @@ extern "C" {
|
|||
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
typedef struct mbedtls_ctr_drbg_psa_context {
|
||||
mbedtls_svc_key_id_t key_id;
|
||||
psa_cipher_operation_t operation;
|
||||
|
|
@ -189,10 +204,10 @@ typedef struct mbedtls_ctr_drbg_context {
|
|||
* This is the maximum number of requests
|
||||
* that can be made between reseedings. */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */
|
||||
#else
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx,
|
|||
* \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
|
||||
* ServerKeyExchange for static ECDH, and imports ECDH
|
||||
* parameters from the EC key information of a certificate.
|
||||
*
|
||||
* \see ecp.h
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ mbedtls_ecp_point;
|
|||
* range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
|
||||
* which is congruent mod \p P to the given MPI, and is close enough to \p pbits
|
||||
* in size, so that it may be efficiently brought in the 0..P-1 range by a few
|
||||
* additions or subtractions. Therefore, it is only an approximative modular
|
||||
* additions or subtractions. Therefore, it is only an approximate modular
|
||||
* reduction. It must return 0 on success and non-zero on failure.
|
||||
*
|
||||
* \note Alternative implementations of the ECP module must obey the
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@
|
|||
* MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
*
|
||||
* \warning If SHA-256 is provided only by a PSA driver, you must call
|
||||
* psa_crypto_init() before the first hanshake (even if
|
||||
* psa_crypto_init() before the first handshake (even if
|
||||
* MBEDTLS_USE_PSA_CRYPTO is disabled).
|
||||
*
|
||||
* This enables the following ciphersuites (if other requisites are
|
||||
|
|
@ -1414,6 +1414,23 @@
|
|||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_SPM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_KEY_STORE_DYNAMIC
|
||||
*
|
||||
* Dynamically resize the PSA key store to accommodate any number of
|
||||
* volatile keys (until the heap memory is exhausted).
|
||||
*
|
||||
* If this option is disabled, the key store has a fixed size
|
||||
* #MBEDTLS_PSA_KEY_SLOT_COUNT for volatile keys and loaded persistent keys
|
||||
* together.
|
||||
*
|
||||
* This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled.
|
||||
*
|
||||
* Module: library/psa_crypto.c
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C
|
||||
*/
|
||||
#define MBEDTLS_PSA_KEY_STORE_DYNAMIC
|
||||
|
||||
/**
|
||||
* Uncomment to enable p256-m. This is an alternative implementation of
|
||||
* key generation, ECDH and (randomized) ECDSA on the curve SECP256R1.
|
||||
|
|
@ -1781,8 +1798,9 @@
|
|||
* Requires: MBEDTLS_PSA_CRYPTO_C
|
||||
*
|
||||
* \note TLS 1.3 uses PSA crypto for cryptographic operations that are
|
||||
* directly performed by TLS 1.3 code. As a consequence, you must
|
||||
* call psa_crypto_init() before the first TLS 1.3 handshake.
|
||||
* directly performed by TLS 1.3 code. As a consequence, when TLS 1.3
|
||||
* is enabled, a TLS handshake may call psa_crypto_init(), even
|
||||
* if it ends up negotiating a different TLS version.
|
||||
*
|
||||
* \note Cryptographic operations performed indirectly via another module
|
||||
* (X.509, PK) or by code shared with TLS 1.2 (record protection,
|
||||
|
|
@ -2625,7 +2643,7 @@
|
|||
* The CTR_DRBG generator uses AES-256 by default.
|
||||
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
|
||||
*
|
||||
* AES support can either be achived through builtin (MBEDTLS_AES_C) or PSA.
|
||||
* AES support can either be achieved through builtin (MBEDTLS_AES_C) or PSA.
|
||||
* Builtin is the default option when MBEDTLS_AES_C is defined otherwise PSA
|
||||
* is used.
|
||||
*
|
||||
|
|
@ -4016,22 +4034,38 @@
|
|||
* Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
|
||||
* PSA crypto subsystem.
|
||||
*
|
||||
* If this option is unset:
|
||||
* - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG.
|
||||
* - Otherwise, the PSA subsystem uses HMAC_DRBG with either
|
||||
* #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and
|
||||
* on unspecified heuristics.
|
||||
* If this option is unset, the library chooses a hash (currently between
|
||||
* #MBEDTLS_MD_SHA512 and #MBEDTLS_MD_SHA256) based on availability and
|
||||
* unspecified heuristics.
|
||||
*
|
||||
* \note The PSA crypto subsystem uses the first available mechanism amongst
|
||||
* the following:
|
||||
* - #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG if enabled;
|
||||
* - Entropy from #MBEDTLS_ENTROPY_C plus CTR_DRBG with AES
|
||||
* if #MBEDTLS_CTR_DRBG_C is enabled;
|
||||
* - Entropy from #MBEDTLS_ENTROPY_C plus HMAC_DRBG.
|
||||
*
|
||||
* A future version may reevaluate the prioritization of DRBG mechanisms.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
|
||||
|
||||
/** \def MBEDTLS_PSA_KEY_SLOT_COUNT
|
||||
* Restrict the PSA library to supporting a maximum amount of simultaneously
|
||||
* loaded keys. A loaded key is a key stored by the PSA Crypto core as a
|
||||
* volatile key, or a persistent key which is loaded temporarily by the
|
||||
* library as part of a crypto operation in flight.
|
||||
*
|
||||
* If this option is unset, the library will fall back to a default value of
|
||||
* 32 keys.
|
||||
* When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled,
|
||||
* the maximum amount of PSA keys simultaneously in memory. This counts all
|
||||
* volatile keys, plus loaded persistent keys.
|
||||
*
|
||||
* When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled,
|
||||
* the maximum number of loaded persistent keys.
|
||||
*
|
||||
* Currently, persistent keys do not need to be loaded all the time while
|
||||
* a multipart operation is in progress, only while the operation is being
|
||||
* set up. This may change in future versions of the library.
|
||||
*
|
||||
* Currently, the library traverses of the whole table on each access to a
|
||||
* persistent key. Therefore large values may cause poor performance.
|
||||
*
|
||||
* This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled.
|
||||
*/
|
||||
//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
|
||||
|
||||
|
|
|
|||
50
engine/thirdparty/mbedtls/include/mbedtls/pk.h
vendored
50
engine/thirdparty/mbedtls/include/mbedtls/pk.h
vendored
|
|
@ -359,32 +359,40 @@ 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.
|
||||
* \brief Initialize a PK context to wrap a PSA key.
|
||||
*
|
||||
* \note This function replaces mbedtls_pk_setup() for contexts
|
||||
* that wrap a (possibly opaque) PSA key instead of
|
||||
* storing and manipulating the key material directly.
|
||||
* This function creates a PK context which wraps a PSA key. The PSA wrapped
|
||||
* key must be an EC or RSA key pair (DH is not suported in the PK module).
|
||||
*
|
||||
* \param ctx The context to initialize. It must be empty (type NONE).
|
||||
* \param key The PSA key to wrap, which must hold an ECC or RSA key
|
||||
* pair (see notes below).
|
||||
* Under the hood PSA functions will be used to perform the required
|
||||
* operations and, based on the key type, used algorithms will be:
|
||||
* * EC:
|
||||
* * verify, verify_ext, sign, sign_ext: ECDSA.
|
||||
* * RSA:
|
||||
* * sign, decrypt: use the primary algorithm in the wrapped PSA key;
|
||||
* * sign_ext: RSA PSS if the pk_type is #MBEDTLS_PK_RSASSA_PSS, otherwise
|
||||
* it falls back to the sign() case;
|
||||
* * verify, verify_ext, encrypt: not supported.
|
||||
*
|
||||
* \note The wrapped key must remain valid as long as the
|
||||
* wrapping PK context is in use, that is at least between
|
||||
* the point this function is called and the point
|
||||
* mbedtls_pk_free() is called on this context. The wrapped
|
||||
* key might then be independently used or destroyed.
|
||||
* In order for the above operations to succeed, the policy of the wrapped PSA
|
||||
* key must allow the specified algorithm.
|
||||
*
|
||||
* \note This function is currently only available for ECC or RSA
|
||||
* key pairs (that is, keys containing private key material).
|
||||
* Support for other key types may be added later.
|
||||
* Opaque PK contexts wrapping an EC keys also support \c mbedtls_pk_check_pair(),
|
||||
* whereas RSA ones do not.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
|
||||
* (context already used, invalid key identifier).
|
||||
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
|
||||
* ECC key pair.
|
||||
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
|
||||
* \warning The PSA 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.
|
||||
*
|
||||
* \param ctx The context to initialize. It must be empty (type NONE).
|
||||
* \param key The PSA key to wrap, which must hold an ECC or RSA key pair.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input (context already
|
||||
* used, invalid key identifier).
|
||||
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an ECC or
|
||||
* RSA key pair.
|
||||
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
|
||||
*/
|
||||
int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx,
|
||||
const mbedtls_svc_key_id_t key);
|
||||
|
|
|
|||
145
engine/thirdparty/mbedtls/include/mbedtls/ssl.h
vendored
145
engine/thirdparty/mbedtls/include/mbedtls/ssl.h
vendored
|
|
@ -83,10 +83,7 @@
|
|||
/** Processing of the Certificate handshake message failed. */
|
||||
#define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00
|
||||
/* Error space gap */
|
||||
/**
|
||||
* Received NewSessionTicket Post Handshake Message.
|
||||
* This error code is experimental and may be changed or removed without notice.
|
||||
*/
|
||||
/** A TLS 1.3 NewSessionTicket message has been received. */
|
||||
#define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00
|
||||
/** Not possible to read early data */
|
||||
#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80
|
||||
|
|
@ -324,6 +321,9 @@
|
|||
#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0
|
||||
#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED 0
|
||||
#define MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED 1
|
||||
|
||||
#define MBEDTLS_SSL_PRESET_DEFAULT 0
|
||||
#define MBEDTLS_SSL_PRESET_SUITEB 2
|
||||
|
||||
|
|
@ -1446,6 +1446,12 @@ struct mbedtls_ssl_config {
|
|||
#endif
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_SSL_CLI_C)
|
||||
/** Encodes two booleans, one stating whether TLS 1.2 session tickets are
|
||||
* enabled or not, the other one whether the handling of TLS 1.3
|
||||
* NewSessionTicket messages is enabled or not. They are respectively set
|
||||
* by mbedtls_ssl_conf_session_tickets() and
|
||||
* mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets().
|
||||
*/
|
||||
uint8_t MBEDTLS_PRIVATE(session_tickets); /*!< use session tickets? */
|
||||
#endif
|
||||
|
||||
|
|
@ -2364,7 +2370,7 @@ int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl,
|
|||
*/
|
||||
int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl,
|
||||
int *enabled,
|
||||
unsigned char own_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
|
||||
unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX],
|
||||
size_t *own_cid_len);
|
||||
|
||||
/**
|
||||
|
|
@ -3216,16 +3222,16 @@ void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
|
|||
* a full handshake.
|
||||
*
|
||||
* \note This function can handle a variety of mechanisms for session
|
||||
* resumption: For TLS 1.2, both session ID-based resumption and
|
||||
* ticket-based resumption will be considered. For TLS 1.3,
|
||||
* once implemented, sessions equate to tickets, and loading
|
||||
* one or more sessions via this call will lead to their
|
||||
* corresponding tickets being advertised as resumption PSKs
|
||||
* by the client.
|
||||
*
|
||||
* \note Calling this function multiple times will only be useful
|
||||
* once TLS 1.3 is supported. For TLS 1.2 connections, this
|
||||
* function should be called at most once.
|
||||
* resumption: For TLS 1.2, both session ID-based resumption
|
||||
* and ticket-based resumption will be considered. For TLS 1.3,
|
||||
* sessions equate to tickets, and loading one session by
|
||||
* calling this function will lead to its corresponding ticket
|
||||
* being advertised as resumption PSK by the client. This
|
||||
* depends on session tickets being enabled (see
|
||||
* #MBEDTLS_SSL_SESSION_TICKETS configuration option) though.
|
||||
* If session tickets are disabled, a call to this function
|
||||
* with a TLS 1.3 session, will not have any effect on the next
|
||||
* handshake for the SSL context \p ssl.
|
||||
*
|
||||
* \param ssl The SSL context representing the connection which should
|
||||
* be attempted to be setup using session resumption. This
|
||||
|
|
@ -3240,9 +3246,10 @@ void mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
|
|||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return \c MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if the session
|
||||
* could not be loaded because of an implementation limitation.
|
||||
* This error is non-fatal, and has no observable effect on
|
||||
* the SSL context or the session that was attempted to be loaded.
|
||||
* could not be loaded because one session has already been
|
||||
* loaded. This error is non-fatal, and has no observable
|
||||
* effect on the SSL context or the session that was attempted
|
||||
* to be loaded.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*
|
||||
* \sa mbedtls_ssl_get_session()
|
||||
|
|
@ -3309,8 +3316,16 @@ int mbedtls_ssl_session_load(mbedtls_ssl_session *session,
|
|||
* to determine the necessary size by calling this function
|
||||
* with \p buf set to \c NULL and \p buf_len to \c 0.
|
||||
*
|
||||
* \note For TLS 1.3 sessions, this feature is supported only if the
|
||||
* MBEDTLS_SSL_SESSION_TICKETS configuration option is enabled,
|
||||
* as in TLS 1.3 session resumption is possible only with
|
||||
* tickets.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
|
||||
* \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if the
|
||||
* MBEDTLS_SSL_SESSION_TICKETS configuration option is disabled
|
||||
* and the session is a TLS 1.3 session.
|
||||
*/
|
||||
int mbedtls_ssl_session_save(const mbedtls_ssl_session *session,
|
||||
unsigned char *buf,
|
||||
|
|
@ -4456,21 +4471,50 @@ int mbedtls_ssl_conf_max_frag_len(mbedtls_ssl_config *conf, unsigned char mfl_co
|
|||
void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order);
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
/**
|
||||
* \brief Enable / Disable session tickets (client only).
|
||||
* (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.)
|
||||
* \brief Enable / Disable TLS 1.2 session tickets (client only,
|
||||
* TLS 1.2 only). Enabled by default.
|
||||
*
|
||||
* \note On server, use \c mbedtls_ssl_conf_session_tickets_cb().
|
||||
*
|
||||
* \param conf SSL configuration
|
||||
* \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
|
||||
* MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
|
||||
* \param use_tickets Enable or disable (#MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
|
||||
* #MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
|
||||
*/
|
||||
void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets);
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS &&
|
||||
MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/**
|
||||
* \brief Enable / Disable handling of TLS 1.3 NewSessionTicket messages
|
||||
* (client only, TLS 1.3 only).
|
||||
*
|
||||
* The handling of TLS 1.3 NewSessionTicket messages is disabled by
|
||||
* default.
|
||||
*
|
||||
* In TLS 1.3, servers may send a NewSessionTicket message at any time,
|
||||
* and may send multiple NewSessionTicket messages. By default, TLS 1.3
|
||||
* clients ignore NewSessionTicket messages.
|
||||
*
|
||||
* To support session tickets in TLS 1.3 clients, call this function
|
||||
* with #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED. When
|
||||
* this is enabled, when a client receives a NewSessionTicket message,
|
||||
* the next call to a message processing functions (notably
|
||||
* mbedtls_ssl_handshake() and mbedtls_ssl_read()) will return
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET. The client should then
|
||||
* call mbedtls_ssl_get_session() to retrieve the session ticket before
|
||||
* calling the same message processing function again.
|
||||
*
|
||||
* \param conf SSL configuration
|
||||
* \param signal_new_session_tickets Enable or disable
|
||||
* (#MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED or
|
||||
* #MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED)
|
||||
*/
|
||||
void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
|
||||
mbedtls_ssl_config *conf, int signal_new_session_tickets);
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_SSL_SRV_C) && \
|
||||
|
|
@ -4837,23 +4881,16 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert(const mbedtls_ssl_context *ssl
|
|||
* \note This function can handle a variety of mechanisms for session
|
||||
* resumption: For TLS 1.2, both session ID-based resumption and
|
||||
* ticket-based resumption will be considered. For TLS 1.3,
|
||||
* once implemented, sessions equate to tickets, and calling
|
||||
* this function multiple times will export the available
|
||||
* tickets one a time until no further tickets are available,
|
||||
* in which case MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE will
|
||||
* be returned.
|
||||
*
|
||||
* \note Calling this function multiple times will only be useful
|
||||
* once TLS 1.3 is supported. For TLS 1.2 connections, this
|
||||
* function should be called at most once.
|
||||
* sessions equate to tickets, and if session tickets are
|
||||
* enabled (see #MBEDTLS_SSL_SESSION_TICKETS configuration
|
||||
* option), this function exports the last received ticket and
|
||||
* the exported session may be used to resume the TLS 1.3
|
||||
* session. If session tickets are disabled, exported sessions
|
||||
* cannot be used to resume a TLS 1.3 session.
|
||||
*
|
||||
* \return \c 0 if successful. In this case, \p session can be used for
|
||||
* session resumption by passing it to mbedtls_ssl_set_session(),
|
||||
* and serialized for storage via mbedtls_ssl_session_save().
|
||||
* \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if no further session
|
||||
* is available for export.
|
||||
* This error is a non-fatal, and has no observable effect on
|
||||
* the SSL context or the destination session.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*
|
||||
* \sa mbedtls_ssl_set_session()
|
||||
|
|
@ -4885,6 +4922,10 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
|
|||
* \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
|
||||
* and the client did not demonstrate reachability yet - in
|
||||
* this case you must stop using the context (see below).
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
|
||||
* NewSessionTicket message has been received. See the
|
||||
* documentation of mbedtls_ssl_read() for more information
|
||||
* about this error code.
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
|
||||
* defined in RFC 8446 (TLS 1.3 specification), has been
|
||||
* received as part of the handshake. This is server specific
|
||||
|
|
@ -4901,6 +4942,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
|
|||
* #MBEDTLS_ERR_SSL_WANT_WRITE,
|
||||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
|
||||
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
|
||||
* you must stop using the SSL context for reading or writing,
|
||||
* and either free it or call \c mbedtls_ssl_session_reset()
|
||||
|
|
@ -4921,10 +4963,13 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
|
|||
* currently being processed might or might not contain further
|
||||
* DTLS records.
|
||||
*
|
||||
* \note If the context is configured to allow TLS 1.3, or if
|
||||
* #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
|
||||
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
|
||||
* subsystem must have been initialized by calling
|
||||
* psa_crypto_init() before calling this function.
|
||||
* Otherwise, the handshake may call psa_crypto_init()
|
||||
* if a negotiation involving TLS 1.3 takes place (this may
|
||||
* be the case even if TLS 1.3 is offered but eventually
|
||||
* not selected).
|
||||
*/
|
||||
int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl);
|
||||
|
||||
|
|
@ -4972,6 +5017,7 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl)
|
|||
* #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
|
||||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
|
||||
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using
|
||||
* the SSL context for reading or writing, and either free it
|
||||
* or call \c mbedtls_ssl_session_reset() on it before
|
||||
|
|
@ -5040,6 +5086,17 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
|
|||
* \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
|
||||
* side of a DTLS connection and the client is initiating a
|
||||
* new connection using the same source port. See below.
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
|
||||
* NewSessionTicket message has been received.
|
||||
* This error code is only returned on the client side. It is
|
||||
* only returned if handling of TLS 1.3 NewSessionTicket
|
||||
* messages has been enabled through
|
||||
* mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets().
|
||||
* This error code indicates that a TLS 1.3 NewSessionTicket
|
||||
* message has been received and parsed successfully by the
|
||||
* client. The ticket data can be retrieved from the SSL
|
||||
* context by calling mbedtls_ssl_get_session(). It remains
|
||||
* available until the next call to mbedtls_ssl_read().
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
|
||||
* defined in RFC 8446 (TLS 1.3 specification), has been
|
||||
* received as part of the handshake. This is server specific
|
||||
|
|
@ -5057,6 +5114,7 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl);
|
|||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
|
||||
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
|
||||
* #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
|
||||
* you must stop using the SSL context for reading or writing,
|
||||
* and either free it or call \c mbedtls_ssl_session_reset()
|
||||
|
|
@ -5122,6 +5180,10 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
|
|||
* operation is in progress (see mbedtls_ecp_set_max_ops()) -
|
||||
* in this case you must call this function again to complete
|
||||
* the handshake when you're done attending other tasks.
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET if a TLS 1.3
|
||||
* NewSessionTicket message has been received. See the
|
||||
* documentation of mbedtls_ssl_read() for more information
|
||||
* about this error code.
|
||||
* \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as
|
||||
* defined in RFC 8446 (TLS 1.3 specification), has been
|
||||
* received as part of the handshake. This is server specific
|
||||
|
|
@ -5138,6 +5200,7 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
|
|||
* #MBEDTLS_ERR_SSL_WANT_WRITE,
|
||||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
|
||||
* #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET or
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA,
|
||||
* you must stop using the SSL context for reading or writing,
|
||||
* and either free it or call \c mbedtls_ssl_session_reset()
|
||||
|
|
|
|||
188
engine/thirdparty/mbedtls/include/psa/crypto.h
vendored
188
engine/thirdparty/mbedtls/include/psa/crypto.h
vendored
|
|
@ -121,8 +121,8 @@ static psa_key_attributes_t psa_key_attributes_init(void);
|
|||
* value in the structure.
|
||||
* The persistent key will be written to storage when the attribute
|
||||
* structure is passed to a key creation function such as
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_custom(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_custom()
|
||||
* or psa_copy_key().
|
||||
*
|
||||
* This function may be declared as `static` (i.e. without external
|
||||
|
|
@ -131,6 +131,9 @@ static psa_key_attributes_t psa_key_attributes_init(void);
|
|||
*
|
||||
* \param[out] attributes The attribute structure to write to.
|
||||
* \param key The persistent identifier for the key.
|
||||
* This can be any value in the range from
|
||||
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX
|
||||
* inclusive.
|
||||
*/
|
||||
static void psa_set_key_id(psa_key_attributes_t *attributes,
|
||||
mbedtls_svc_key_id_t key);
|
||||
|
|
@ -166,8 +169,8 @@ static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
|
|||
* value in the structure.
|
||||
* The persistent key will be written to storage when the attribute
|
||||
* structure is passed to a key creation function such as
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_ext(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_ext()
|
||||
* psa_import_key(), psa_generate_key(), psa_generate_key_custom(),
|
||||
* psa_key_derivation_output_key(), psa_key_derivation_output_key_custom()
|
||||
* or psa_copy_key().
|
||||
*
|
||||
* This function may be declared as `static` (i.e. without external
|
||||
|
|
@ -875,7 +878,7 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg,
|
|||
* such that #PSA_ALG_IS_HASH(\p alg) is true).
|
||||
* \param[in] input Buffer containing the message to hash.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] hash Buffer containing the expected hash value.
|
||||
* \param[in] hash Buffer containing the expected hash value.
|
||||
* \param hash_length Size of the \p hash buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
|
|
@ -1230,7 +1233,7 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
|
|||
* such that #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
* \param[in] input Buffer containing the input message.
|
||||
* \param input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] mac Buffer containing the expected MAC value.
|
||||
* \param[in] mac Buffer containing the expected MAC value.
|
||||
* \param mac_length Size of the \p mac buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
|
|
@ -2922,7 +2925,7 @@ psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
|
|||
* \p key.
|
||||
* \param[in] input The message whose signature is to be verified.
|
||||
* \param[in] input_length Size of the \p input buffer in bytes.
|
||||
* \param[out] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature Buffer containing the signature to verify.
|
||||
* \param[in] signature_length Size of the \p signature buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
|
|
@ -3248,7 +3251,7 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
|
|||
* of or after providing inputs. For some algorithms, this step is mandatory
|
||||
* because the output depends on the maximum capacity.
|
||||
* -# To derive a key, call psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
* psa_key_derivation_output_key_custom().
|
||||
* To derive a byte string for a different purpose, call
|
||||
* psa_key_derivation_output_bytes().
|
||||
* Successive calls to these functions use successive output bytes
|
||||
|
|
@ -3471,7 +3474,7 @@ psa_status_t psa_key_derivation_input_integer(
|
|||
* \note Once all inputs steps are completed, the operations will allow:
|
||||
* - psa_key_derivation_output_bytes() if each input was either a direct input
|
||||
* or a key with #PSA_KEY_USAGE_DERIVE set;
|
||||
* - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext()
|
||||
* - psa_key_derivation_output_key() or psa_key_derivation_output_key_custom()
|
||||
* if the input for step
|
||||
* #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
|
||||
* was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
|
||||
|
|
@ -3721,9 +3724,9 @@ psa_status_t psa_key_derivation_output_bytes(
|
|||
* on the derived key based on the attributes and strength of the secret key.
|
||||
*
|
||||
* \note This function is equivalent to calling
|
||||
* psa_key_derivation_output_key_ext()
|
||||
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* and `params_data_length == 0` (i.e. `params->data` is empty).
|
||||
* psa_key_derivation_output_key_custom()
|
||||
* with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT
|
||||
* and `custom_data_length == 0` (i.e. `custom_data` is empty).
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* If the key type to be created is
|
||||
|
|
@ -3795,6 +3798,85 @@ psa_status_t psa_key_derivation_output_key(
|
|||
* the policy must be the same as in the current
|
||||
* operation.
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] custom Customization parameters for the key generation.
|
||||
* When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT
|
||||
* with \p custom_data_length = 0,
|
||||
* this function is equivalent to
|
||||
* psa_key_derivation_output_key().
|
||||
* \param[in] custom_data Variable-length data associated with \c custom.
|
||||
* \param custom_data_length
|
||||
* Length of `custom_data` in bytes.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
* key. For persistent keys, this is the key
|
||||
* identifier defined in \p attributes.
|
||||
* \c 0 on failure.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* If the key is persistent, the key material and the key's metadata
|
||||
* have been saved to persistent storage.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* This is an attempt to create a persistent key, and there is
|
||||
* already a persistent key with the given identifier.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_DATA
|
||||
* There was not enough data to create the desired key.
|
||||
* Note that in this case, no output is written to the output buffer.
|
||||
* The operation's capacity is set to 0, thus subsequent calls to
|
||||
* this function will not succeed, even with a smaller output buffer.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The key type or key size is not supported, either by the
|
||||
* implementation in general or in this particular location.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The provided key attributes are not valid for the operation.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The #PSA_KEY_DERIVATION_INPUT_SECRET or
|
||||
* #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
|
||||
* key; or one of the inputs was a key whose policy didn't allow
|
||||
* #PSA_KEY_USAGE_DERIVE.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The operation state is not valid (it must be active and completed
|
||||
* all required input steps), or 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 psa_key_derivation_output_key_custom(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const psa_custom_key_parameters_t *custom,
|
||||
const uint8_t *custom_data,
|
||||
size_t custom_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* Omitted when compiling in C++, because one of the parameters is a
|
||||
* pointer to a struct with a flexible array member, and that is not
|
||||
* standard C++.
|
||||
* https://github.com/Mbed-TLS/mbedtls/issues/9020
|
||||
*/
|
||||
/** Derive a key from an ongoing key derivation operation with custom
|
||||
* production parameters.
|
||||
*
|
||||
* \note
|
||||
* This is a deprecated variant of psa_key_derivation_output_key_custom().
|
||||
* It is equivalent except that the associated variable-length data
|
||||
* is passed in `params->data` instead of a separate parameter.
|
||||
* This function will be removed in a future version of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* If the key type to be created is
|
||||
* #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
|
||||
* the policy must be the same as in the current
|
||||
* operation.
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] params Customization parameters for the key derivation.
|
||||
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* with \p params_data_length = 0,
|
||||
|
|
@ -3848,14 +3930,13 @@ psa_status_t psa_key_derivation_output_key(
|
|||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
psa_status_t psa_key_derivation_output_key_ext(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
#endif
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value.
|
||||
*
|
||||
|
|
@ -3881,8 +3962,8 @@ psa_status_t psa_key_derivation_output_key_ext(
|
|||
* psa_key_derivation_abort().
|
||||
*
|
||||
* \param[in,out] operation The key derivation operation object to read from.
|
||||
* \param[in] expected_output Buffer containing the expected derivation output.
|
||||
* \param output_length Length of the expected output; this is also the
|
||||
* \param[in] expected Buffer containing the expected derivation output.
|
||||
* \param expected_length Length of the expected output; this is also the
|
||||
* number of bytes that will be read.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
|
|
@ -3912,8 +3993,8 @@ psa_status_t psa_key_derivation_output_key_ext(
|
|||
*/
|
||||
psa_status_t psa_key_derivation_verify_bytes(
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const uint8_t *expected_output,
|
||||
size_t output_length);
|
||||
const uint8_t *expected,
|
||||
size_t expected_length);
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value
|
||||
* stored in a key object.
|
||||
|
|
@ -3943,7 +4024,7 @@ psa_status_t psa_key_derivation_verify_bytes(
|
|||
* operation. The value of this key was likely
|
||||
* computed by a previous call to
|
||||
* psa_key_derivation_output_key() or
|
||||
* psa_key_derivation_output_key_ext().
|
||||
* psa_key_derivation_output_key_custom().
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_SIGNATURE
|
||||
|
|
@ -4111,9 +4192,9 @@ psa_status_t psa_generate_random(uint8_t *output,
|
|||
* between 2^{n-1} and 2^n where n is the bit size specified in the
|
||||
* attributes.
|
||||
*
|
||||
* \note This function is equivalent to calling psa_generate_key_ext()
|
||||
* with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* and `params_data_length == 0` (i.e. `params->data` is empty).
|
||||
* \note This function is equivalent to calling psa_generate_key_custom()
|
||||
* with the custom production parameters #PSA_CUSTOM_KEY_PARAMETERS_INIT
|
||||
* and `custom_data_length == 0` (i.e. `custom_data` is empty).
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
|
|
@ -4153,7 +4234,7 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
|||
* See the description of psa_generate_key() for the operation of this
|
||||
* function with the default production parameters. In addition, this function
|
||||
* supports the following production customizations, described in more detail
|
||||
* in the documentation of ::psa_key_production_parameters_t:
|
||||
* in the documentation of ::psa_custom_key_parameters_t:
|
||||
*
|
||||
* - RSA keys: generation with a custom public exponent.
|
||||
*
|
||||
|
|
@ -4161,6 +4242,64 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
|||
* versions of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* \param[in] custom Customization parameters for the key generation.
|
||||
* When this is #PSA_CUSTOM_KEY_PARAMETERS_INIT
|
||||
* with \p custom_data_length = 0,
|
||||
* this function is equivalent to
|
||||
* psa_generate_key().
|
||||
* \param[in] custom_data Variable-length data associated with \c custom.
|
||||
* \param custom_data_length
|
||||
* Length of `custom_data` in bytes.
|
||||
* \param[out] key On success, an identifier for the newly created
|
||||
* key. For persistent keys, this is the key
|
||||
* identifier defined in \p attributes.
|
||||
* \c 0 on failure.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* If the key is persistent, the key material and the key's metadata
|
||||
* have been saved to persistent storage.
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS
|
||||
* This is an attempt to create a persistent key, and there is
|
||||
* already a persistent key with the given identifier.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \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 psa_generate_key_custom(const psa_key_attributes_t *attributes,
|
||||
const psa_custom_key_parameters_t *custom,
|
||||
const uint8_t *custom_data,
|
||||
size_t custom_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* Omitted when compiling in C++, because one of the parameters is a
|
||||
* pointer to a struct with a flexible array member, and that is not
|
||||
* standard C++.
|
||||
* https://github.com/Mbed-TLS/mbedtls/issues/9020
|
||||
*/
|
||||
/**
|
||||
* \brief Generate a key or key pair using custom production parameters.
|
||||
*
|
||||
* \note
|
||||
* This is a deprecated variant of psa_key_derivation_output_key_custom().
|
||||
* It is equivalent except that the associated variable-length data
|
||||
* is passed in `params->data` instead of a separate parameter.
|
||||
* This function will be removed in a future version of Mbed TLS.
|
||||
*
|
||||
* \param[in] attributes The attributes for the new key.
|
||||
* \param[in] params Customization parameters for the key generation.
|
||||
* When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT
|
||||
* with \p params_data_length = 0,
|
||||
|
|
@ -4196,12 +4335,11 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
|||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
#endif
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file psa/crypto_adjust_auto_enabled.h
|
||||
* \brief Adjust PSA configuration: enable always-on features
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Always enable certain features which require a negligible amount of code
|
||||
* to implement, to avoid some edge cases in the configuration combinatorics.
|
||||
*/
|
||||
|
|
@ -13,6 +15,14 @@
|
|||
#ifndef PSA_CRYPTO_ADJUST_AUTO_ENABLED_H
|
||||
#define PSA_CRYPTO_ADJUST_AUTO_ENABLED_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_PASSWORD 1
|
||||
#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
|
||||
|
|
|
|||
51
engine/thirdparty/mbedtls/include/psa/crypto_adjust_config_dependencies.h
vendored
Normal file
51
engine/thirdparty/mbedtls/include/psa/crypto_adjust_config_dependencies.h
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* \file psa/crypto_adjust_config_dependencies.h
|
||||
* \brief Adjust PSA configuration by resolving some dependencies.
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* See docs/proposed/psa-conditional-inclusion-c.md.
|
||||
* If the Mbed TLS implementation of a cryptographic mechanism A depends on a
|
||||
* cryptographic mechanism B then if the cryptographic mechanism A is enabled
|
||||
* and not accelerated enable B. Note that if A is enabled and accelerated, it
|
||||
* is not necessary to enable B for A support.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H
|
||||
#define PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
#if (defined(PSA_WANT_ALG_TLS12_PRF) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)) || \
|
||||
(defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)) || \
|
||||
(defined(PSA_WANT_ALG_HKDF) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)) || \
|
||||
(defined(PSA_WANT_ALG_HKDF_EXTRACT) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT)) || \
|
||||
(defined(PSA_WANT_ALG_HKDF_EXPAND) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND)) || \
|
||||
(defined(PSA_WANT_ALG_PBKDF2_HMAC) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC))
|
||||
#define PSA_WANT_ALG_HMAC 1
|
||||
#define PSA_WANT_KEY_TYPE_HMAC 1
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128))
|
||||
#define PSA_WANT_KEY_TYPE_AES 1
|
||||
#define PSA_WANT_ALG_CMAC 1
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_ADJUST_CONFIG_DEPENDENCIES_H */
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
* \file psa/crypto_adjust_config_key_pair_types.h
|
||||
* \brief Adjust PSA configuration for key pair types.
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* See docs/proposed/psa-conditional-inclusion-c.md.
|
||||
* - Support non-basic operations in a keypair type implicitly enables basic
|
||||
* support for that keypair type.
|
||||
|
|
@ -19,6 +21,14 @@
|
|||
#ifndef PSA_CRYPTO_ADJUST_KEYPAIR_TYPES_H
|
||||
#define PSA_CRYPTO_ADJUST_KEYPAIR_TYPES_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/*****************************************************************
|
||||
* ANYTHING -> BASIC
|
||||
****************************************************************/
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file psa/crypto_adjust_config_synonyms.h
|
||||
* \brief Adjust PSA configuration: enable quasi-synonyms
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* When two features require almost the same code, we automatically enable
|
||||
* both when either one is requested, to reduce the combinatorics of
|
||||
* possible configurations.
|
||||
|
|
@ -14,6 +16,14 @@
|
|||
#ifndef PSA_CRYPTO_ADJUST_CONFIG_SYNONYMS_H
|
||||
#define PSA_CRYPTO_ADJUST_CONFIG_SYNONYMS_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILES_READ)
|
||||
#error "Do not include psa/crypto_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/****************************************************************/
|
||||
/* De facto synonyms */
|
||||
/****************************************************************/
|
||||
|
|
|
|||
|
|
@ -154,6 +154,14 @@ static inline void psa_clear_key_slot_number(
|
|||
* specified in \p attributes.
|
||||
*
|
||||
* \param[in] attributes The attributes of the existing key.
|
||||
* - The lifetime must be a persistent lifetime
|
||||
* in a secure element. Volatile lifetimes are
|
||||
* not currently supported.
|
||||
* - The key identifier must be in the valid
|
||||
* range for persistent keys.
|
||||
* - The key type and size must be specified and
|
||||
* must be consistent with the key material
|
||||
* in the secure element.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully registered.
|
||||
|
|
@ -479,7 +487,7 @@ psa_status_t mbedtls_psa_external_get_random(
|
|||
* #PSA_KEY_ID_VENDOR_MIN and #PSA_KEY_ID_VENDOR_MAX and must not intersect
|
||||
* with any other set of implementation-chosen key identifiers.
|
||||
*
|
||||
* This value is part of the library's ABI since changing it would invalidate
|
||||
* This value is part of the library's API since changing it would invalidate
|
||||
* the values of built-in key identifiers in applications.
|
||||
*/
|
||||
#define MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ((psa_key_id_t) 0x7fff0000)
|
||||
|
|
|
|||
|
|
@ -223,13 +223,36 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
|
|||
return v;
|
||||
}
|
||||
|
||||
#ifndef __cplusplus
|
||||
struct psa_key_production_parameters_s {
|
||||
struct psa_custom_key_parameters_s {
|
||||
/* Future versions may add other fields in this structure. */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/** The default production parameters for key generation or key derivation.
|
||||
*
|
||||
* Calling psa_generate_key_custom() or psa_key_derivation_output_key_custom()
|
||||
* with `custom=PSA_CUSTOM_KEY_PARAMETERS_INIT` and `custom_data_length=0` is
|
||||
* equivalent to calling psa_generate_key() or psa_key_derivation_output_key()
|
||||
* respectively.
|
||||
*/
|
||||
#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 }
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* Omitted when compiling in C++, because one of the parameters is a
|
||||
* pointer to a struct with a flexible array member, and that is not
|
||||
* standard C++.
|
||||
* https://github.com/Mbed-TLS/mbedtls/issues/9020
|
||||
*/
|
||||
/* This is a deprecated variant of `struct psa_custom_key_parameters_s`.
|
||||
* It has exactly the same layout, plus an extra field which is a flexible
|
||||
* array member. Thus a `const struct psa_key_production_parameters_s *`
|
||||
* can be passed to any function that reads a
|
||||
* `const struct psa_custom_key_parameters_s *`.
|
||||
*/
|
||||
struct psa_key_production_parameters_s {
|
||||
uint32_t flags;
|
||||
uint8_t data[];
|
||||
};
|
||||
#endif
|
||||
|
||||
/** The default production parameters for key generation or key derivation.
|
||||
*
|
||||
|
|
@ -240,6 +263,7 @@ struct psa_key_production_parameters_s {
|
|||
* respectively.
|
||||
*/
|
||||
#define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 }
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
struct psa_key_policy_s {
|
||||
psa_key_usage_t MBEDTLS_PRIVATE(usage);
|
||||
|
|
|
|||
|
|
@ -455,6 +455,30 @@ typedef uint64_t psa_key_slot_number_t;
|
|||
*/
|
||||
typedef uint16_t psa_key_derivation_step_t;
|
||||
|
||||
/** \brief Custom parameters for key generation or key derivation.
|
||||
*
|
||||
* This is a structure type with at least the following field:
|
||||
*
|
||||
* - \c flags: an unsigned integer type. 0 for the default production parameters.
|
||||
*
|
||||
* Functions that take such a structure as input also take an associated
|
||||
* input buffer \c custom_data of length \c custom_data_length.
|
||||
*
|
||||
* The interpretation of this structure and the associated \c custom_data
|
||||
* parameter depend on the type of the created key.
|
||||
*
|
||||
* - #PSA_KEY_TYPE_RSA_KEY_PAIR:
|
||||
* - \c flags: must be 0.
|
||||
* - \c custom_data: the public exponent, in little-endian order.
|
||||
* This must be an odd integer and must not be 1.
|
||||
* Implementations must support 65537, should support 3 and may
|
||||
* support other values.
|
||||
* When not using a driver, Mbed TLS supports values up to \c INT_MAX.
|
||||
* If this is empty, the default value 65537 is used.
|
||||
* - Other key types: reserved for future use. \c flags must be 0.
|
||||
*/
|
||||
typedef struct psa_custom_key_parameters_s psa_custom_key_parameters_t;
|
||||
|
||||
/** \brief Custom parameters for key generation or key derivation.
|
||||
*
|
||||
* This is a structure type with at least the following fields:
|
||||
|
|
@ -477,9 +501,7 @@ typedef uint16_t psa_key_derivation_step_t;
|
|||
* - Other key types: reserved for future use. \c flags must be 0.
|
||||
*
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
typedef struct psa_key_production_parameters_s psa_key_production_parameters_t;
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
|
|
|||
31
engine/thirdparty/mbedtls/library/bignum.c
vendored
31
engine/thirdparty/mbedtls/library/bignum.c
vendored
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_internal.h"
|
||||
#include "bn_mul.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
|
@ -1610,9 +1611,13 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR)
|
||||
/*
|
||||
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
|
||||
* this function is not constant time with respect to the exponent (parameter E).
|
||||
*/
|
||||
static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, int E_public,
|
||||
const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
|
|
@ -1695,7 +1700,11 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
|
|||
{
|
||||
mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
|
||||
mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
|
||||
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
|
||||
if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
|
||||
mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
|
||||
} else {
|
||||
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
|
||||
}
|
||||
mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
|
||||
}
|
||||
|
||||
|
|
@ -1720,6 +1729,20 @@ cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR)
|
||||
{
|
||||
return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
|
||||
}
|
||||
|
||||
int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR)
|
||||
{
|
||||
return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
|
||||
*/
|
||||
|
|
|
|||
163
engine/thirdparty/mbedtls/library/bignum_core.c
vendored
163
engine/thirdparty/mbedtls/library/bignum_core.c
vendored
|
|
@ -746,7 +746,93 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
|
||||
int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function calculates the indices of the exponent where the exponentiation algorithm should
|
||||
* start processing.
|
||||
*
|
||||
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
|
||||
* this function is not constant time with respect to the exponent (parameter E).
|
||||
*/
|
||||
static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
|
||||
size_t E_limbs,
|
||||
int E_public,
|
||||
size_t *E_limb_index,
|
||||
size_t *E_bit_index)
|
||||
{
|
||||
if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
|
||||
/*
|
||||
* Skip leading zero bits.
|
||||
*/
|
||||
size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
|
||||
if (E_bits == 0) {
|
||||
/*
|
||||
* If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want
|
||||
* to represent it as a single 0 bit and as such the bitlength will be 1.
|
||||
*/
|
||||
E_bits = 1;
|
||||
}
|
||||
|
||||
*E_limb_index = E_bits / biL;
|
||||
*E_bit_index = E_bits % biL;
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* Here we need to be constant time with respect to E and can't do anything better than
|
||||
* start at the first allocated bit.
|
||||
*/
|
||||
*E_limb_index = E_limbs;
|
||||
*E_bit_index = 0;
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
// Only mark the codepath safe if there wasn't an unsafe codepath before
|
||||
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
|
||||
* not constant time with respect to the window parameter and consequently the exponent of the
|
||||
* exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
|
||||
*/
|
||||
static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
|
||||
mbedtls_mpi_uint *Wtable,
|
||||
size_t AN_limbs, size_t welem,
|
||||
mbedtls_mpi_uint window,
|
||||
int window_public)
|
||||
{
|
||||
if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
|
||||
memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
|
||||
#endif
|
||||
} else {
|
||||
/* Select Wtable[window] without leaking window through
|
||||
* memory access patterns. */
|
||||
mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
|
||||
AN_limbs, welem, window);
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
// Only mark the codepath safe if there wasn't an unsafe codepath before
|
||||
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Exponentiation: X := A^E mod N.
|
||||
*
|
||||
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
|
||||
* this function is not constant time with respect to the exponent (parameter E).
|
||||
*
|
||||
* A must already be in Montgomery form.
|
||||
*
|
||||
|
|
@ -758,16 +844,25 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
|
|||
* (The difference is that the body in our loop processes a single bit instead
|
||||
* of a full window.)
|
||||
*/
|
||||
void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E,
|
||||
size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T)
|
||||
static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N,
|
||||
size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E,
|
||||
size_t E_limbs,
|
||||
int E_public,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T)
|
||||
{
|
||||
const size_t wsize = exp_mod_get_window_size(E_limbs * biL);
|
||||
/* We'll process the bits of E from most significant
|
||||
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
|
||||
* (limb_index=0, E_bit_index=0). */
|
||||
size_t E_limb_index;
|
||||
size_t E_bit_index;
|
||||
exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
|
||||
&E_limb_index, &E_bit_index);
|
||||
|
||||
const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);
|
||||
const size_t welem = ((size_t) 1) << wsize;
|
||||
|
||||
/* This is how we will use the temporary storage T, which must have space
|
||||
|
|
@ -786,7 +881,7 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
|||
|
||||
const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);
|
||||
|
||||
/* Set Wtable[i] = A^(2^i) (in Montgomery representation) */
|
||||
/* Set Wtable[i] = A^i (in Montgomery representation) */
|
||||
exp_mod_precompute_window(A, N, AN_limbs,
|
||||
mm, RR,
|
||||
welem, Wtable, temp);
|
||||
|
|
@ -798,11 +893,6 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
|||
/* X = 1 (in Montgomery presentation) initially */
|
||||
memcpy(X, Wtable, AN_limbs * ciL);
|
||||
|
||||
/* We'll process the bits of E from most significant
|
||||
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
|
||||
* (limb_index=0, E_bit_index=0). */
|
||||
size_t E_limb_index = E_limbs;
|
||||
size_t E_bit_index = 0;
|
||||
/* At any given time, window contains window_bits bits from E.
|
||||
* window_bits can go up to wsize. */
|
||||
size_t window_bits = 0;
|
||||
|
|
@ -828,10 +918,9 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
|||
* when we've finished processing the exponent. */
|
||||
if (window_bits == wsize ||
|
||||
(E_bit_index == 0 && E_limb_index == 0)) {
|
||||
/* Select Wtable[window] without leaking window through
|
||||
* memory access patterns. */
|
||||
mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
|
||||
AN_limbs, welem, window);
|
||||
|
||||
exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
|
||||
window, E_public);
|
||||
/* Multiply X by the selected element. */
|
||||
mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
|
||||
temp);
|
||||
|
|
@ -841,6 +930,42 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
|||
} while (!(E_bit_index == 0 && E_limb_index == 0));
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E, size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T)
|
||||
{
|
||||
mbedtls_mpi_core_exp_mod_optionally_safe(X,
|
||||
A,
|
||||
N,
|
||||
AN_limbs,
|
||||
E,
|
||||
E_limbs,
|
||||
MBEDTLS_MPI_IS_SECRET,
|
||||
RR,
|
||||
T);
|
||||
}
|
||||
|
||||
void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E, size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T)
|
||||
{
|
||||
mbedtls_mpi_core_exp_mod_optionally_safe(X,
|
||||
A,
|
||||
N,
|
||||
AN_limbs,
|
||||
E,
|
||||
E_limbs,
|
||||
MBEDTLS_MPI_IS_PUBLIC,
|
||||
RR,
|
||||
T);
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
mbedtls_mpi_uint c, /* doubles as carry */
|
||||
|
|
|
|||
70
engine/thirdparty/mbedtls/library/bignum_core.h
vendored
70
engine/thirdparty/mbedtls/library/bignum_core.h
vendored
|
|
@ -90,6 +90,27 @@
|
|||
#define GET_BYTE(X, i) \
|
||||
(((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)
|
||||
|
||||
/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by
|
||||
* this constant, the function must be constant time with respect to the parameter.
|
||||
*
|
||||
* This is only needed for functions with the _optionally_safe postfix. All other functions have
|
||||
* fixed behavior that can't be changed at runtime and are constant time with respect to their
|
||||
* parameters as prescribed by their documentation or by conventions in their module's documentation.
|
||||
*
|
||||
* Parameters should be named X_public where X is the name of the
|
||||
* corresponding input parameter.
|
||||
*
|
||||
* Implementation should always check using
|
||||
* if (X_public == MBEDTLS_MPI_IS_PUBLIC) {
|
||||
* // unsafe path
|
||||
* } else {
|
||||
* // safe path
|
||||
* }
|
||||
* not the other way round, in order to prevent misuse. (This is, if a value
|
||||
* other than the two below is passed, default to the safe path.) */
|
||||
#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a
|
||||
#define MBEDTLS_MPI_IS_SECRET 0
|
||||
|
||||
/** Count leading zero bits in a given integer.
|
||||
*
|
||||
* \warning The result is undefined if \p a == 0
|
||||
|
|
@ -604,6 +625,42 @@ int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
|
|||
*/
|
||||
size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs);
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation with public or secret exponent:
|
||||
* X = A^E mod N, where \p A is already in Montgomery form.
|
||||
*
|
||||
* \warning This function is not constant time with respect to \p E (the exponent).
|
||||
*
|
||||
* \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
|
||||
* \p AN_limbs.
|
||||
*
|
||||
* \param[out] X The destination MPI, as a little endian array of length
|
||||
* \p AN_limbs.
|
||||
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
|
||||
* Must be in Montgomery form.
|
||||
* \param[in] N The modulus, as a little endian array of length \p AN_limbs.
|
||||
* \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
|
||||
* \param[in] E The exponent, as a little endian array of length \p E_limbs.
|
||||
* \param E_limbs The number of limbs in \p E.
|
||||
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
|
||||
* endian array of length \p AN_limbs.
|
||||
* \param[in,out] T Temporary storage of at least the number of limbs returned
|
||||
* by `mbedtls_mpi_core_exp_mod_working_limbs()`.
|
||||
* Its initial content is unused and its final content is
|
||||
* indeterminate.
|
||||
* It must not alias or otherwise overlap any of the other
|
||||
* parameters.
|
||||
* It is up to the caller to zeroize \p T when it is no
|
||||
* longer needed, and before freeing it if it was dynamically
|
||||
* allocated.
|
||||
*/
|
||||
void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
const mbedtls_mpi_uint *N, size_t AN_limbs,
|
||||
const mbedtls_mpi_uint *E, size_t E_limbs,
|
||||
const mbedtls_mpi_uint *RR,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation with secret exponent:
|
||||
* X = A^E mod N, where \p A is already in Montgomery form.
|
||||
|
|
@ -760,4 +817,17 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
|
|||
mbedtls_mpi_uint mm,
|
||||
mbedtls_mpi_uint *T);
|
||||
|
||||
/*
|
||||
* Can't define thread local variables with our abstraction layer: do nothing if threading is on.
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
|
||||
extern int mbedtls_mpi_optionally_safe_codepath;
|
||||
|
||||
static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
|
||||
{
|
||||
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
|
||||
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_CORE_H */
|
||||
|
|
|
|||
50
engine/thirdparty/mbedtls/library/bignum_internal.h
vendored
Normal file
50
engine/thirdparty/mbedtls/library/bignum_internal.h
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* \file bignum_internal.h
|
||||
*
|
||||
* \brief Internal-only bignum public-key cryptosystem API.
|
||||
*
|
||||
* This file declares bignum-related functions that are to be used
|
||||
* only from within the Mbed TLS library itself.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BIGNUM_INTERNAL_H
|
||||
#define MBEDTLS_BIGNUM_INTERNAL_H
|
||||
|
||||
/**
|
||||
* \brief Perform a modular exponentiation: X = A^E mod N
|
||||
*
|
||||
* \warning This function is not constant time with respect to \p E (the exponent).
|
||||
*
|
||||
* \param X The destination MPI. This must point to an initialized MPI.
|
||||
* This must not alias E or N.
|
||||
* \param A The base of the exponentiation.
|
||||
* This must point to an initialized MPI.
|
||||
* \param E The exponent MPI. This must point to an initialized MPI.
|
||||
* \param N The base for the modular reduction. This must point to an
|
||||
* initialized MPI.
|
||||
* \param prec_RR A helper MPI depending solely on \p N which can be used to
|
||||
* speed-up multiple modular exponentiations for the same value
|
||||
* of \p N. This may be \c NULL. If it is not \c NULL, it must
|
||||
* point to an initialized MPI. If it hasn't been used after
|
||||
* the call to mbedtls_mpi_init(), this function will compute
|
||||
* the helper value and store it in \p prec_RR for reuse on
|
||||
* subsequent calls to this function. Otherwise, the function
|
||||
* will assume that \p prec_RR holds the helper value set by a
|
||||
* previous call to mbedtls_mpi_exp_mod(), and reuse it.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
|
||||
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
|
||||
* even, or if \c E is negative.
|
||||
* \return Another negative error code on different kinds of failures.
|
||||
*
|
||||
*/
|
||||
int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
const mbedtls_mpi *E, const mbedtls_mpi *N,
|
||||
mbedtls_mpi *prec_RR);
|
||||
|
||||
#endif /* bignum_internal.h */
|
||||
394
engine/thirdparty/mbedtls/library/bignum_mod.c
vendored
394
engine/thirdparty/mbedtls/library/bignum_mod.c
vendored
|
|
@ -1,394 +0,0 @@
|
|||
/**
|
||||
* Modular bignum functions
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_mod.h"
|
||||
#include "bignum_mod_raw.h"
|
||||
#include "constant_time_internal.h"
|
||||
|
||||
int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *p,
|
||||
size_t p_limbs)
|
||||
{
|
||||
if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
r->limbs = N->limbs;
|
||||
r->p = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r)
|
||||
{
|
||||
if (r == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
r->limbs = 0;
|
||||
r->p = NULL;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
N->p = NULL;
|
||||
N->limbs = 0;
|
||||
N->bits = 0;
|
||||
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
||||
}
|
||||
|
||||
void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
if (N->rep.mont.rr != NULL) {
|
||||
mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr,
|
||||
N->limbs * sizeof(mbedtls_mpi_uint));
|
||||
N->rep.mont.rr = NULL;
|
||||
}
|
||||
N->rep.mont.mm = 0;
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
N->rep.ored.modp = NULL;
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_INVALID:
|
||||
break;
|
||||
}
|
||||
|
||||
N->p = NULL;
|
||||
N->limbs = 0;
|
||||
N->bits = 0;
|
||||
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
||||
}
|
||||
|
||||
static int set_mont_const_square(const mbedtls_mpi_uint **X,
|
||||
const mbedtls_mpi_uint *A,
|
||||
size_t limbs)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi N;
|
||||
mbedtls_mpi RR;
|
||||
*X = NULL;
|
||||
|
||||
mbedtls_mpi_init(&N);
|
||||
mbedtls_mpi_init(&RR);
|
||||
|
||||
if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mbedtls_mpi_grow(&N, limbs)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs);
|
||||
|
||||
ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
|
||||
|
||||
if (ret == 0) {
|
||||
*X = RR.p;
|
||||
RR.p = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&N);
|
||||
mbedtls_mpi_free(&RR);
|
||||
ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void standard_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
mbedtls_mpi_mod_rep_selector int_rep)
|
||||
{
|
||||
N->p = p;
|
||||
N->limbs = p_limbs;
|
||||
N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
|
||||
N->int_rep = int_rep;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs)
|
||||
{
|
||||
int ret = 0;
|
||||
standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY);
|
||||
N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
|
||||
ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
|
||||
|
||||
if (ret != 0) {
|
||||
mbedtls_mpi_mod_modulus_free(N);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
||||
const mbedtls_mpi_uint *p,
|
||||
size_t p_limbs,
|
||||
mbedtls_mpi_modp_fn modp)
|
||||
{
|
||||
standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_OPT_RED);
|
||||
N->rep.ored.modp = modp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (N->limbs == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL);
|
||||
if (T == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T);
|
||||
|
||||
mbedtls_free(T);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *working_memory)
|
||||
{
|
||||
/* Input already in Montgomery form, so there's little to do */
|
||||
mbedtls_mpi_mod_raw_inv_prime(X->p, A->p,
|
||||
N->p, N->limbs,
|
||||
N->rep.mont.rr,
|
||||
working_memory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
mbedtls_mpi_uint *working_memory)
|
||||
{
|
||||
/* Need to convert input into Montgomery form */
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_mpi_mod_modulus Nmont;
|
||||
mbedtls_mpi_mod_modulus_init(&Nmont);
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs));
|
||||
|
||||
/* We'll use X->p to hold the Montgomery form of the input A->p */
|
||||
mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.mm, Nmont.rep.mont.rr,
|
||||
working_memory);
|
||||
|
||||
mbedtls_mpi_mod_raw_inv_prime(X->p, X->p,
|
||||
Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.rr,
|
||||
working_memory);
|
||||
|
||||
/* And convert back from Montgomery form */
|
||||
|
||||
mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs,
|
||||
Nmont.rep.mont.mm, working_memory);
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_mod_modulus_free(&Nmont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
/* Zero has the same value regardless of Montgomery form or not */
|
||||
if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
size_t working_limbs =
|
||||
mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs);
|
||||
|
||||
mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs,
|
||||
sizeof(mbedtls_mpi_uint));
|
||||
if (working_memory == NULL) {
|
||||
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
switch (N->int_rep) {
|
||||
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
||||
ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory);
|
||||
break;
|
||||
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
||||
ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory);
|
||||
break;
|
||||
default:
|
||||
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
mbedtls_zeroize_and_free(working_memory,
|
||||
working_limbs * sizeof(mbedtls_mpi_uint));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,
|
||||
const mbedtls_mpi_mod_residue *A,
|
||||
const mbedtls_mpi_mod_residue *B,
|
||||
const mbedtls_mpi_mod_modulus *N)
|
||||
{
|
||||
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,
|
||||
mbedtls_mpi_uint min,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng)
|
||||
{
|
||||
if (X->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng);
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
const unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
|
||||
/* Do our best to check if r and m have been set up */
|
||||
if (r->limbs == 0 || N->limbs == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (r->limbs != N->limbs) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r->limbs = N->limbs;
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
|
||||
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
|
||||
const mbedtls_mpi_mod_modulus *N,
|
||||
unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_mpi_mod_ext_rep ext_rep)
|
||||
{
|
||||
/* Do our best to check if r and m have been set up */
|
||||
if (r->limbs == 0 || N->limbs == 0) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
if (r->limbs != N->limbs) {
|
||||
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_uint *working_memory = r->p;
|
||||
size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs;
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
|
||||
|
||||
working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint));
|
||||
|
||||
if (working_memory == NULL) {
|
||||
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(working_memory, r->p, working_memory_len);
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep);
|
||||
|
||||
cleanup:
|
||||
|
||||
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
|
||||
working_memory != NULL) {
|
||||
|
||||
mbedtls_zeroize_and_free(working_memory, working_memory_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
|
||||
203
engine/thirdparty/mbedtls/library/block_cipher.c
vendored
203
engine/thirdparty/mbedtls/library/block_cipher.c
vendored
|
|
@ -1,203 +0,0 @@
|
|||
/**
|
||||
* \file block_cipher.c
|
||||
*
|
||||
* \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
|
||||
* for use by the GCM and CCM modules.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
|
||||
#include "block_cipher_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)
|
||||
{
|
||||
switch (cipher_id) {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return PSA_KEY_TYPE_AES;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return PSA_KEY_TYPE_ARIA;
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return PSA_KEY_TYPE_CAMELLIA;
|
||||
#endif
|
||||
default:
|
||||
return PSA_KEY_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static int mbedtls_cipher_error_from_psa(psa_status_t status)
|
||||
{
|
||||
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors,
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_destroy_key(ctx->psa_key_id);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_free(&ctx->ctx.aes);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_free(&ctx->ctx.aria);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_free(&ctx->ctx.camellia);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
|
||||
mbedtls_cipher_id_t cipher_id)
|
||||
{
|
||||
ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA :
|
||||
(cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA :
|
||||
MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id);
|
||||
if (psa_key_type != PSA_KEY_TYPE_NONE &&
|
||||
psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) {
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA;
|
||||
return 0;
|
||||
}
|
||||
ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY;
|
||||
#endif
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
mbedtls_aes_init(&ctx->ctx.aes);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
mbedtls_aria_init(&ctx->ctx.aria);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
mbedtls_camellia_init(&ctx->ctx.camellia);
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
|
||||
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned key_bitlen)
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id));
|
||||
psa_set_key_bits(&key_attr, key_bitlen);
|
||||
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
|
||||
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
|
||||
|
||||
status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16])
|
||||
{
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
|
||||
psa_status_t status;
|
||||
size_t olen;
|
||||
|
||||
status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
input, 16, output, 16, &olen);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return mbedtls_cipher_error_from_psa(status);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
|
||||
|
||||
switch (ctx->id) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_AES:
|
||||
return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
|
||||
return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
|
||||
return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia,
|
||||
MBEDTLS_CAMELLIA_ENCRYPT,
|
||||
input, output);
|
||||
#endif
|
||||
default:
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_C */
|
||||
3
engine/thirdparty/mbedtls/library/cipher.c
vendored
3
engine/thirdparty/mbedtls/library/cipher.c
vendored
|
|
@ -849,6 +849,9 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
|
|||
}
|
||||
|
||||
padding_len = input[input_len - 1];
|
||||
if (padding_len == 0 || padding_len > input_len) {
|
||||
return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
|
||||
}
|
||||
*data_len = input_len - padding_len;
|
||||
|
||||
mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
|
||||
|
|
|
|||
16
engine/thirdparty/mbedtls/library/common.h
vendored
16
engine/thirdparty/mbedtls/library/common.h
vendored
|
|
@ -352,17 +352,19 @@ static inline void mbedtls_xor_no_simd(unsigned char *r,
|
|||
#endif
|
||||
|
||||
/* Always provide a static assert macro, so it can be used unconditionally.
|
||||
* It will expand to nothing on some systems.
|
||||
* Can be used outside functions (but don't add a trailing ';' in that case:
|
||||
* the semicolon is included here to avoid triggering -Wextra-semi when
|
||||
* MBEDTLS_STATIC_ASSERT() expands to nothing).
|
||||
* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
|
||||
* It does nothing on systems where we don't know how to define a static assert.
|
||||
*/
|
||||
/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
|
||||
* defines static_assert even with -std=c99, but then complains about it.
|
||||
*/
|
||||
#if defined(static_assert) && !defined(__FreeBSD__)
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg);
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
|
||||
#else
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg)
|
||||
/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
|
||||
* outside a function. We choose a struct declaration, which can be repeated
|
||||
* any number of times and does not need a matching definition. */
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) \
|
||||
struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
|
||||
#endif
|
||||
|
||||
#if defined(__has_builtin)
|
||||
|
|
|
|||
128
engine/thirdparty/mbedtls/library/ctr_drbg.c
vendored
128
engine/thirdparty/mbedtls/library/ctr_drbg.c
vendored
|
|
@ -26,13 +26,13 @@
|
|||
#endif
|
||||
|
||||
/* Using error translation functions from PSA to MbedTLS */
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
#include "psa_util_internal.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
|
||||
unsigned char *key, size_t key_len)
|
||||
{
|
||||
|
|
@ -73,11 +73,11 @@ static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx)
|
|||
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_init(&ctx->aes_ctx);
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
ctx->psa_ctx.operation = psa_cipher_operation_init();
|
||||
#else
|
||||
mbedtls_aes_init(&ctx->aes_ctx);
|
||||
#endif
|
||||
/* Indicate that the entropy nonce length is not set explicitly.
|
||||
* See mbedtls_ctr_drbg_set_nonce_len(). */
|
||||
|
|
@ -102,10 +102,10 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
|
|||
mbedtls_mutex_free(&ctx->mutex);
|
||||
}
|
||||
#endif
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_free(&ctx->aes_ctx);
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
|
||||
#else
|
||||
mbedtls_aes_free(&ctx->aes_ctx);
|
||||
#endif
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
|
|
@ -168,15 +168,15 @@ static int block_cipher_df(unsigned char *output,
|
|||
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
|
||||
unsigned char *p, *iv;
|
||||
int ret = 0;
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context aes_ctx;
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
mbedtls_ctr_drbg_psa_context psa_ctx;
|
||||
|
||||
psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
psa_ctx.operation = psa_cipher_operation_init();
|
||||
#else
|
||||
mbedtls_aes_context aes_ctx;
|
||||
#endif
|
||||
|
||||
int i, j;
|
||||
|
|
@ -209,19 +209,19 @@ static int block_cipher_df(unsigned char *output,
|
|||
key[i] = i;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -238,18 +238,18 @@ static int block_cipher_df(unsigned char *output,
|
|||
use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
|
||||
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
chain, chain)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
|
||||
chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
chain, chain)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -264,12 +264,7 @@ static int block_cipher_df(unsigned char *output,
|
|||
/*
|
||||
* Do final encryption with reduced data
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
ctr_drbg_destroy_psa_contex(&psa_ctx);
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
|
|
@ -277,32 +272,37 @@ static int block_cipher_df(unsigned char *output,
|
|||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
|
||||
p = output;
|
||||
|
||||
for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
iv, iv)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
|
||||
iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
iv, iv)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
exit:
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_free(&aes_ctx);
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
ctr_drbg_destroy_psa_contex(&psa_ctx);
|
||||
#else
|
||||
mbedtls_aes_free(&aes_ctx);
|
||||
#endif
|
||||
/*
|
||||
* tidy up the stack
|
||||
|
|
@ -336,7 +336,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
|||
unsigned char *p = tmp;
|
||||
int j;
|
||||
int ret = 0;
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
#endif
|
||||
|
|
@ -352,18 +352,18 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
|||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, p)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
|
||||
p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, p)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
|
|
@ -374,12 +374,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
|||
/*
|
||||
* Update key and counter
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
|
|
@ -387,6 +382,11 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
|
|||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
|
||||
MBEDTLS_CTR_DRBG_BLOCKSIZE);
|
||||
|
|
@ -564,12 +564,7 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
|
|||
good_nonce_len(ctx->entropy_len));
|
||||
|
||||
/* Initialize with an empty key. */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
psa_status_t status;
|
||||
|
||||
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
|
||||
|
|
@ -577,6 +572,11 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
|
|||
ret = psa_generic_status_to_mbedtls(status);
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
|
||||
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do the initial seeding. */
|
||||
|
|
@ -655,12 +655,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
|
|||
/*
|
||||
* Crypt counter block
|
||||
*/
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, locals.tmp)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
psa_status_t status;
|
||||
size_t tmp_len;
|
||||
|
||||
|
|
@ -670,6 +665,11 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
|
|||
ret = psa_generic_status_to_mbedtls(status);
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
|
||||
ctx->counter, locals.tmp)) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
|
||||
|
|
|
|||
6036
engine/thirdparty/mbedtls/library/ecp_curves_new.c
vendored
6036
engine/thirdparty/mbedtls/library/ecp_curves_new.c
vendored
File diff suppressed because it is too large
Load diff
4
engine/thirdparty/mbedtls/library/entropy.c
vendored
4
engine/thirdparty/mbedtls/library/entropy.c
vendored
|
|
@ -61,6 +61,10 @@ void mbedtls_entropy_init(mbedtls_entropy_context *ctx)
|
|||
|
||||
void mbedtls_entropy_free(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the context was already free, don't call free() again.
|
||||
* This is important for mutexes which don't allow double-free. */
|
||||
if (ctx->accumulator_started == -1) {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#if defined(__linux__) || defined(__midipix__) && !defined(_GNU_SOURCE)
|
||||
#if defined(__linux__) || defined(__midipix__)
|
||||
/* Ensure that syscall() is available even when compiling with -std=c99 */
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
|
|
|||
2
engine/thirdparty/mbedtls/library/error.c
vendored
2
engine/thirdparty/mbedtls/library/error.c
vendored
|
|
@ -418,7 +418,7 @@ const char *mbedtls_high_level_strerr(int error_code)
|
|||
case -(MBEDTLS_ERR_SSL_BAD_CERTIFICATE):
|
||||
return( "SSL - Processing of the Certificate handshake message failed" );
|
||||
case -(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET):
|
||||
return( "SSL - * Received NewSessionTicket Post Handshake Message. This error code is experimental and may be changed or removed without notice" );
|
||||
return( "SSL - A TLS 1.3 NewSessionTicket message has been received" );
|
||||
case -(MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA):
|
||||
return( "SSL - Not possible to read early data" );
|
||||
case -(MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA):
|
||||
|
|
|
|||
778
engine/thirdparty/mbedtls/library/lmots.c
vendored
778
engine/thirdparty/mbedtls/library/lmots.c
vendored
|
|
@ -1,778 +0,0 @@
|
|||
/*
|
||||
* The LM-OTS one-time public-key signature scheme
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following sources were referenced in the design of this implementation
|
||||
* of the LM-OTS algorithm:
|
||||
*
|
||||
* [1] IETF RFC8554
|
||||
* D. McGrew, M. Curcio, S.Fluhrer
|
||||
* https://datatracker.ietf.org/doc/html/rfc8554
|
||||
*
|
||||
* [2] NIST Special Publication 800-208
|
||||
* David A. Cooper et. al.
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lmots.h"
|
||||
|
||||
#include "mbedtls/lms.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/* Define a local translating function to save code size by not using too many
|
||||
* arguments in each translating place. */
|
||||
static int local_err_translation(psa_status_t status)
|
||||
{
|
||||
return psa_status_to_mbedtls(status, psa_to_lms_errors,
|
||||
ARRAY_LENGTH(psa_to_lms_errors),
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
|
||||
|
||||
#define PUBLIC_KEY_TYPE_OFFSET (0)
|
||||
#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_Q_LEAF_ID_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN)
|
||||
#define PUBLIC_KEY_KEY_HASH_OFFSET (PUBLIC_KEY_Q_LEAF_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
|
||||
|
||||
/* We only support parameter sets that use 8-bit digits, as it does not require
|
||||
* translation logic between digits and bytes */
|
||||
#define W_WINTERNITZ_PARAMETER (8u)
|
||||
#define CHECKSUM_LEN (2)
|
||||
#define I_DIGIT_IDX_LEN (2)
|
||||
#define J_HASH_IDX_LEN (1)
|
||||
#define D_CONST_LEN (2)
|
||||
|
||||
#define DIGIT_MAX_VALUE ((1u << W_WINTERNITZ_PARAMETER) - 1u)
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_PUBLIC_CONSTANT_BYTES[D_CONST_LEN] = { 0x80, 0x80 };
|
||||
static const unsigned char D_MESSAGE_CONSTANT_BYTES[D_CONST_LEN] = { 0x81, 0x81 };
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
int (*mbedtls_lmots_sign_private_key_invalidated_hook)(unsigned char *) = NULL;
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/* Calculate the checksum digits that are appended to the end of the LMOTS digit
|
||||
* string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of
|
||||
* the checksum algorithm.
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* digest The digit string to create the digest from. As
|
||||
* this does not contain a checksum, it is the same
|
||||
* size as a hash output.
|
||||
*/
|
||||
static unsigned short lmots_checksum_calculate(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *digest)
|
||||
{
|
||||
size_t idx;
|
||||
unsigned sum = 0;
|
||||
|
||||
for (idx = 0; idx < MBEDTLS_LMOTS_N_HASH_LEN(params->type); idx++) {
|
||||
sum += DIGIT_MAX_VALUE - digest[idx];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Create the string of digest digits (in the base determined by the Winternitz
|
||||
* parameter with the checksum appended to the end (Q || cksm(Q)). See NIST
|
||||
* SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm
|
||||
* 4b step 3) for details.
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* msg The message that will be hashed to create the
|
||||
* digest.
|
||||
*
|
||||
* msg_size The size of the message.
|
||||
*
|
||||
* C_random_value The random value that will be combined with the
|
||||
* message digest. This is always the same size as a
|
||||
* hash output for whichever hash algorithm is
|
||||
* determined by the parameter set.
|
||||
*
|
||||
* output An output containing the digit string (+
|
||||
* checksum) of length P digits (in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of
|
||||
* size P bytes).
|
||||
*/
|
||||
static int create_digit_array_with_checksum(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_len,
|
||||
const unsigned char *C_random_value,
|
||||
unsigned char *out)
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned short checksum;
|
||||
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, D_MESSAGE_CONSTANT_BYTES, D_CONST_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, C_random_value,
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(params->type));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, msg, msg_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op, out,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
checksum = lmots_checksum_calculate(params, out);
|
||||
MBEDTLS_PUT_UINT16_BE(checksum, out, MBEDTLS_LMOTS_N_HASH_LEN(params->type));
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
/* Hash each element of the string of digits (+ checksum), producing a hash
|
||||
* output for each element. This is used in several places (by varying the
|
||||
* hash_idx_min/max_values) in order to calculate a public key from a private
|
||||
* key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554
|
||||
* Algorithm 3 step 5), and to calculate a public key candidate from a
|
||||
* signature and message (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* x_digit_array The array of digits (of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8).
|
||||
*
|
||||
* hash_idx_min_values An array of the starting values of the j iterator
|
||||
* for each of the members of the digit array. If
|
||||
* this value in NULL, then all iterators will start
|
||||
* at 0.
|
||||
*
|
||||
* hash_idx_max_values An array of the upper bound values of the j
|
||||
* iterator for each of the members of the digit
|
||||
* array. If this value in NULL, then iterator is
|
||||
* bounded to be less than 2^w - 1 (255 in the case
|
||||
* of MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* output An array containing a hash output for each member
|
||||
* of the digit string P. In the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 *
|
||||
* 34.
|
||||
*/
|
||||
static int hash_digit_array(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *x_digit_array,
|
||||
const unsigned char *hash_idx_min_values,
|
||||
const unsigned char *hash_idx_max_values,
|
||||
unsigned char *output)
|
||||
{
|
||||
unsigned int i_digit_idx;
|
||||
unsigned char i_digit_idx_bytes[I_DIGIT_IDX_LEN];
|
||||
unsigned int j_hash_idx;
|
||||
unsigned char j_hash_idx_bytes[J_HASH_IDX_LEN];
|
||||
unsigned int j_hash_idx_min;
|
||||
unsigned int j_hash_idx_max;
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char tmp_hash[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
|
||||
for (i_digit_idx = 0;
|
||||
i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type);
|
||||
i_digit_idx++) {
|
||||
|
||||
memcpy(tmp_hash,
|
||||
&x_digit_array[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type));
|
||||
|
||||
j_hash_idx_min = hash_idx_min_values != NULL ?
|
||||
hash_idx_min_values[i_digit_idx] : 0;
|
||||
j_hash_idx_max = hash_idx_max_values != NULL ?
|
||||
hash_idx_max_values[i_digit_idx] : DIGIT_MAX_VALUE;
|
||||
|
||||
for (j_hash_idx = j_hash_idx_min;
|
||||
j_hash_idx < j_hash_idx_max;
|
||||
j_hash_idx++) {
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op,
|
||||
params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op,
|
||||
params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0);
|
||||
status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
j_hash_idx_bytes[0] = (uint8_t) j_hash_idx;
|
||||
status = psa_hash_update(&op, j_hash_idx_bytes, J_HASH_IDX_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, tmp_hash,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op, tmp_hash, sizeof(tmp_hash),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
psa_hash_abort(&op);
|
||||
}
|
||||
|
||||
memcpy(&output[i_digit_idx * MBEDTLS_LMOTS_N_HASH_LEN(params->type)],
|
||||
tmp_hash, MBEDTLS_LMOTS_N_HASH_LEN(params->type));
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
mbedtls_platform_zeroize(tmp_hash, sizeof(tmp_hash));
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
/* Combine the hashes of the digit array into a public key. This is used in
|
||||
* in order to calculate a public key from a private key (RFC8554 Algorithm 1
|
||||
* step 4), and to calculate a public key candidate from a signature and message
|
||||
* (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* params The LMOTS parameter set, I and q values which describe
|
||||
* the key being used.
|
||||
* y_hashed_digits The array of hashes, one hash for each digit of the
|
||||
* symbol array (which is of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* pub_key The output public key (or candidate public key in
|
||||
* case this is being run as part of signature
|
||||
* verification), in the form of a hash output.
|
||||
*/
|
||||
static int public_key_from_hashed_digit_array(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *y_hashed_digits,
|
||||
unsigned char *pub_key)
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op,
|
||||
params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, params->q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, D_PUBLIC_CONSTANT_BYTES, D_CONST_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, y_hashed_digits,
|
||||
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(params->type) *
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op, pub_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->type),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
}
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
int mbedtls_lms_error_from_psa(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_SUCCESS:
|
||||
return 0;
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
default:
|
||||
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
void mbedtls_lmots_public_init(mbedtls_lmots_public_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void mbedtls_lmots_public_free(mbedtls_lmots_public_t *ctx)
|
||||
{
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
int mbedtls_lmots_import_public_key(mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *key, size_t key_len)
|
||||
{
|
||||
if (key_len < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->params.type = (mbedtls_lmots_algorithm_type_t)
|
||||
MBEDTLS_GET_UINT32_BE(key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
|
||||
|
||||
if (key_len != MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
memcpy(ctx->params.I_key_identifier,
|
||||
key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
|
||||
memcpy(ctx->params.q_leaf_identifier,
|
||||
key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
|
||||
memcpy(ctx->public_key,
|
||||
key + PUBLIC_KEY_KEY_HASH_OFFSET,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_export_public_key(const mbedtls_lmots_public_t *ctx,
|
||||
unsigned char *key, size_t key_size,
|
||||
size_t *key_len)
|
||||
{
|
||||
if (key_size < MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (!ctx->have_public_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
|
||||
|
||||
memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
|
||||
memcpy(key + PUBLIC_KEY_Q_LEAF_ID_OFFSET,
|
||||
ctx->params.q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
|
||||
memcpy(key + PUBLIC_KEY_KEY_HASH_OFFSET, ctx->public_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));
|
||||
|
||||
if (key_len != NULL) {
|
||||
*key_len = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_calculate_public_key_candidate(const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_size,
|
||||
const unsigned char *sig,
|
||||
size_t sig_size,
|
||||
unsigned char *out,
|
||||
size_t out_size,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
|
||||
unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (msg == NULL && msg_size != 0) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (sig_size != MBEDTLS_LMOTS_SIG_LEN(params->type) ||
|
||||
out_size < MBEDTLS_LMOTS_N_HASH_LEN(params->type)) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ret = create_digit_array_with_checksum(params, msg, msg_size,
|
||||
sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET,
|
||||
tmp_digit_array);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hash_digit_array(params,
|
||||
sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(params->type),
|
||||
tmp_digit_array, NULL, (unsigned char *) y_hashed_digits);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = public_key_from_hashed_digit_array(params,
|
||||
(unsigned char *) y_hashed_digits,
|
||||
out);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (out_len != NULL) {
|
||||
*out_len = MBEDTLS_LMOTS_N_HASH_LEN(params->type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_verify(const mbedtls_lmots_public_t *ctx,
|
||||
const unsigned char *msg, size_t msg_size,
|
||||
const unsigned char *sig, size_t sig_size)
|
||||
{
|
||||
unsigned char Kc_public_key_candidate[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (msg == NULL && msg_size != 0) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (!ctx->have_public_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->params.type != MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (sig_size < MBEDTLS_LMOTS_SIG_TYPE_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (MBEDTLS_GET_UINT32_BE(sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET) != MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key_candidate(&ctx->params,
|
||||
msg, msg_size, sig, sig_size,
|
||||
Kc_public_key_candidate,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
|
||||
NULL);
|
||||
if (ret) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (memcmp(&Kc_public_key_candidate, ctx->public_key,
|
||||
sizeof(ctx->public_key))) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
void mbedtls_lmots_private_init(mbedtls_lmots_private_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void mbedtls_lmots_private_free(mbedtls_lmots_private_t *ctx)
|
||||
{
|
||||
mbedtls_platform_zeroize(ctx,
|
||||
sizeof(*ctx));
|
||||
}
|
||||
|
||||
int mbedtls_lmots_generate_private_key(mbedtls_lmots_private_t *ctx,
|
||||
mbedtls_lmots_algorithm_type_t type,
|
||||
const unsigned char I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN],
|
||||
uint32_t q_leaf_identifier,
|
||||
const unsigned char *seed,
|
||||
size_t seed_size)
|
||||
{
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned int i_digit_idx;
|
||||
unsigned char i_digit_idx_bytes[2];
|
||||
unsigned char const_bytes[1] = { 0xFF };
|
||||
|
||||
if (ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (type != MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->params.type = type;
|
||||
|
||||
memcpy(ctx->params.I_key_identifier,
|
||||
I_key_identifier,
|
||||
sizeof(ctx->params.I_key_identifier));
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ctx->params.q_leaf_identifier, 0);
|
||||
|
||||
for (i_digit_idx = 0;
|
||||
i_digit_idx < MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type);
|
||||
i_digit_idx++) {
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op,
|
||||
ctx->params.I_key_identifier,
|
||||
sizeof(ctx->params.I_key_identifier));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op,
|
||||
ctx->params.q_leaf_identifier,
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE(i_digit_idx, i_digit_idx_bytes, 0);
|
||||
status = psa_hash_update(&op, i_digit_idx_bytes, I_DIGIT_IDX_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, const_bytes, sizeof(const_bytes));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, seed, seed_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op,
|
||||
ctx->private_key[i_digit_idx],
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
psa_hash_abort(&op);
|
||||
}
|
||||
|
||||
ctx->have_private_key = 1;
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
int mbedtls_lmots_calculate_public_key(mbedtls_lmots_public_t *ctx,
|
||||
const mbedtls_lmots_private_t *priv_ctx)
|
||||
{
|
||||
unsigned char y_hashed_digits[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* Check that a private key is loaded */
|
||||
if (!priv_ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ret = hash_digit_array(&priv_ctx->params,
|
||||
(unsigned char *) priv_ctx->private_key, NULL,
|
||||
NULL, (unsigned char *) y_hashed_digits);
|
||||
if (ret) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = public_key_from_hashed_digit_array(&priv_ctx->params,
|
||||
(unsigned char *) y_hashed_digits,
|
||||
ctx->public_key);
|
||||
if (ret) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(&ctx->params, &priv_ctx->params,
|
||||
sizeof(ctx->params));
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(y_hashed_digits, sizeof(y_hashed_digits));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_lmots_sign(mbedtls_lmots_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg, size_t msg_size,
|
||||
unsigned char *sig, size_t sig_size, size_t *sig_len)
|
||||
{
|
||||
unsigned char tmp_digit_array[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX];
|
||||
/* Create a temporary buffer to prepare the signature in. This allows us to
|
||||
* finish creating a signature (ensuring the process doesn't fail), and then
|
||||
* erase the private key **before** writing any data into the sig parameter
|
||||
* buffer. If data were directly written into the sig buffer, it might leak
|
||||
* a partial signature on failure, which effectively compromises the private
|
||||
* key.
|
||||
*/
|
||||
unsigned char tmp_sig[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char tmp_c_random[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (msg == NULL && msg_size != 0) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (sig_size < MBEDTLS_LMOTS_SIG_LEN(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Check that a private key is loaded */
|
||||
if (!ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ret = f_rng(p_rng, tmp_c_random,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = create_digit_array_with_checksum(&ctx->params,
|
||||
msg, msg_size,
|
||||
tmp_c_random,
|
||||
tmp_digit_array);
|
||||
if (ret) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = hash_digit_array(&ctx->params, (unsigned char *) ctx->private_key,
|
||||
NULL, tmp_digit_array, (unsigned char *) tmp_sig);
|
||||
if (ret) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, MBEDTLS_LMOTS_SIG_TYPE_OFFSET);
|
||||
|
||||
/* Test hook to check if sig is being written to before we invalidate the
|
||||
* private key.
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if (mbedtls_lmots_sign_private_key_invalidated_hook != NULL) {
|
||||
ret = (*mbedtls_lmots_sign_private_key_invalidated_hook)(sig);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/* We've got a valid signature now, so it's time to make sure the private
|
||||
* key can't be reused.
|
||||
*/
|
||||
ctx->have_private_key = 0;
|
||||
mbedtls_platform_zeroize(ctx->private_key,
|
||||
sizeof(ctx->private_key));
|
||||
|
||||
memcpy(sig + MBEDTLS_LMOTS_SIG_C_RANDOM_OFFSET, tmp_c_random,
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(ctx->params.type));
|
||||
|
||||
memcpy(sig + MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(ctx->params.type), tmp_sig,
|
||||
MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(ctx->params.type)
|
||||
* MBEDTLS_LMOTS_N_HASH_LEN(ctx->params.type));
|
||||
|
||||
if (sig_len != NULL) {
|
||||
*sig_len = MBEDTLS_LMOTS_SIG_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp_digit_array, sizeof(tmp_digit_array));
|
||||
mbedtls_platform_zeroize(tmp_sig, sizeof(tmp_sig));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
#endif /* defined(MBEDTLS_LMS_C) */
|
||||
761
engine/thirdparty/mbedtls/library/lms.c
vendored
761
engine/thirdparty/mbedtls/library/lms.c
vendored
|
|
@ -1,761 +0,0 @@
|
|||
/*
|
||||
* The LMS stateful-hash public-key signature scheme
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following sources were referenced in the design of this implementation
|
||||
* of the LMS algorithm:
|
||||
*
|
||||
* [1] IETF RFC8554
|
||||
* D. McGrew, M. Curcio, S.Fluhrer
|
||||
* https://datatracker.ietf.org/doc/html/rfc8554
|
||||
*
|
||||
* [2] NIST Special Publication 800-208
|
||||
* David A. Cooper et. al.
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lmots.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_util_internal.h"
|
||||
#include "mbedtls/lms.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/* Define a local translating function to save code size by not using too many
|
||||
* arguments in each translating place. */
|
||||
static int local_err_translation(psa_status_t status)
|
||||
{
|
||||
return psa_status_to_mbedtls(status, psa_to_lms_errors,
|
||||
ARRAY_LENGTH(psa_to_lms_errors),
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
|
||||
|
||||
#define SIG_Q_LEAF_ID_OFFSET (0)
|
||||
#define SIG_OTS_SIG_OFFSET (SIG_Q_LEAF_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_Q_LEAF_ID_LEN)
|
||||
#define SIG_TYPE_OFFSET(otstype) (SIG_OTS_SIG_OFFSET + \
|
||||
MBEDTLS_LMOTS_SIG_LEN(otstype))
|
||||
#define SIG_PATH_OFFSET(otstype) (SIG_TYPE_OFFSET(otstype) + \
|
||||
MBEDTLS_LMS_TYPE_LEN)
|
||||
|
||||
#define PUBLIC_KEY_TYPE_OFFSET (0)
|
||||
#define PUBLIC_KEY_OTSTYPE_OFFSET (PUBLIC_KEY_TYPE_OFFSET + \
|
||||
MBEDTLS_LMS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_I_KEY_ID_OFFSET (PUBLIC_KEY_OTSTYPE_OFFSET + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN)
|
||||
#define PUBLIC_KEY_ROOT_NODE_OFFSET (PUBLIC_KEY_I_KEY_ID_OFFSET + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN)
|
||||
|
||||
|
||||
/* Currently only support H=10 */
|
||||
#define H_TREE_HEIGHT_MAX 10
|
||||
#define MERKLE_TREE_NODE_AM(type) ((size_t) 1 << (MBEDTLS_LMS_H_TREE_HEIGHT(type) + 1u))
|
||||
#define MERKLE_TREE_LEAF_NODE_AM(type) ((size_t) 1 << MBEDTLS_LMS_H_TREE_HEIGHT(type))
|
||||
#define MERKLE_TREE_INTERNAL_NODE_AM(type) ((unsigned int) \
|
||||
(1u << MBEDTLS_LMS_H_TREE_HEIGHT(type)))
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = { 0x82, 0x82 };
|
||||
static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = { 0x83, 0x83 };
|
||||
|
||||
|
||||
/* Calculate the value of a leaf node of the Merkle tree (which is a hash of a
|
||||
* public key and some other parameters like the leaf index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r >= 2^h.
|
||||
*
|
||||
* params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* pub_key The public key of the private whose index
|
||||
* corresponds to the index of this leaf node. This
|
||||
* is a hash output.
|
||||
*
|
||||
* r_node_idx The index of this node in the Merkle tree. Note
|
||||
* that the root node of the Merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_leaf_value(const mbedtls_lms_parameters_t *params,
|
||||
unsigned char *pub_key,
|
||||
unsigned int r_node_idx,
|
||||
unsigned char *out)
|
||||
{
|
||||
psa_hash_operation_t op;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char r_node_idx_bytes[4];
|
||||
|
||||
op = psa_hash_operation_init();
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
|
||||
status = psa_hash_update(&op, r_node_idx_bytes, 4);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, D_LEAF_CONSTANT_BYTES, D_CONST_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, pub_key,
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(params->otstype));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
/* Calculate the value of an internal node of the Merkle tree (which is a hash
|
||||
* of a public key and some other parameters like the node index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r < 2^h.
|
||||
*
|
||||
* params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* left_node The value of the child of this node which is on
|
||||
* the left-hand side. As with all nodes on the
|
||||
* Merkle tree, this is a hash output.
|
||||
*
|
||||
* right_node The value of the child of this node which is on
|
||||
* the right-hand side. As with all nodes on the
|
||||
* Merkle tree, this is a hash output.
|
||||
*
|
||||
* r_node_idx The index of this node in the Merkle tree. Note
|
||||
* that the root node of the Merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_internal_value(const mbedtls_lms_parameters_t *params,
|
||||
const unsigned char *left_node,
|
||||
const unsigned char *right_node,
|
||||
unsigned int r_node_idx,
|
||||
unsigned char *out)
|
||||
{
|
||||
psa_hash_operation_t op;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t output_hash_len;
|
||||
unsigned char r_node_idx_bytes[4];
|
||||
|
||||
op = psa_hash_operation_init();
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, params->I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(r_node_idx, r_node_idx_bytes, 0);
|
||||
status = psa_hash_update(&op, r_node_idx_bytes, 4);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, D_INTR_CONSTANT_BYTES, D_CONST_LEN);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, left_node,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(params->type));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&op, right_node,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(params->type));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&op, out, MBEDTLS_LMS_M_NODE_BYTES(params->type),
|
||||
&output_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_hash_abort(&op);
|
||||
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx)
|
||||
{
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *key, size_t key_size)
|
||||
{
|
||||
mbedtls_lms_algorithm_type_t type;
|
||||
mbedtls_lmots_algorithm_type_t otstype;
|
||||
|
||||
type = (mbedtls_lms_algorithm_type_t) MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_TYPE_OFFSET);
|
||||
if (type != MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
ctx->params.type = type;
|
||||
|
||||
if (key_size != MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
otstype = (mbedtls_lmots_algorithm_type_t)
|
||||
MBEDTLS_GET_UINT32_BE(key, PUBLIC_KEY_OTSTYPE_OFFSET);
|
||||
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
ctx->params.otstype = otstype;
|
||||
|
||||
memcpy(ctx->params.I_key_identifier,
|
||||
key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
memcpy(ctx->T_1_pub_key, key + PUBLIC_KEY_ROOT_NODE_OFFSET,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type));
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx,
|
||||
unsigned char *key,
|
||||
size_t key_size, size_t *key_len)
|
||||
{
|
||||
if (key_size < MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (!ctx->have_public_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->params.type, key, PUBLIC_KEY_TYPE_OFFSET);
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->params.otstype, key, PUBLIC_KEY_OTSTYPE_OFFSET);
|
||||
memcpy(key + PUBLIC_KEY_I_KEY_ID_OFFSET,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
memcpy(key +PUBLIC_KEY_ROOT_NODE_OFFSET,
|
||||
ctx->T_1_pub_key,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type));
|
||||
|
||||
if (key_len != NULL) {
|
||||
*key_len = MBEDTLS_LMS_PUBLIC_KEY_LEN(ctx->params.type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *msg, size_t msg_size,
|
||||
const unsigned char *sig, size_t sig_size)
|
||||
{
|
||||
unsigned int q_leaf_identifier;
|
||||
unsigned char Kc_candidate_ots_pub_key[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char Tc_candidate_root_node[MBEDTLS_LMS_M_NODE_BYTES_MAX];
|
||||
unsigned int height;
|
||||
unsigned int curr_node_id;
|
||||
unsigned int parent_node_id;
|
||||
const unsigned char *left_node;
|
||||
const unsigned char *right_node;
|
||||
mbedtls_lmots_parameters_t ots_params;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (!ctx->have_public_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->params.type
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (sig_size != MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (sig_size < SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_TYPE_LEN) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (MBEDTLS_GET_UINT32_BE(sig, SIG_OTS_SIG_OFFSET + MBEDTLS_LMOTS_SIG_TYPE_OFFSET)
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (sig_size < SIG_TYPE_OFFSET(ctx->params.otstype) + MBEDTLS_LMS_TYPE_LEN) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
if (MBEDTLS_GET_UINT32_BE(sig, SIG_TYPE_OFFSET(ctx->params.otstype))
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
|
||||
q_leaf_identifier = MBEDTLS_GET_UINT32_BE(sig, SIG_Q_LEAF_ID_OFFSET);
|
||||
|
||||
if (q_leaf_identifier >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
memcpy(ots_params.I_key_identifier,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, ots_params.q_leaf_identifier, 0);
|
||||
ots_params.type = ctx->params.otstype;
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key_candidate(&ots_params,
|
||||
msg,
|
||||
msg_size,
|
||||
sig + SIG_OTS_SIG_OFFSET,
|
||||
MBEDTLS_LMOTS_SIG_LEN(ctx->params.otstype),
|
||||
Kc_candidate_ots_pub_key,
|
||||
sizeof(Kc_candidate_ots_pub_key),
|
||||
NULL);
|
||||
if (ret != 0) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
create_merkle_leaf_value(
|
||||
&ctx->params,
|
||||
Kc_candidate_ots_pub_key,
|
||||
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
|
||||
Tc_candidate_root_node);
|
||||
|
||||
curr_node_id = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) +
|
||||
q_leaf_identifier;
|
||||
|
||||
for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
|
||||
height++) {
|
||||
parent_node_id = curr_node_id / 2;
|
||||
|
||||
/* Left/right node ordering matters for the hash */
|
||||
if (curr_node_id & 1) {
|
||||
left_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
|
||||
height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
|
||||
right_node = Tc_candidate_root_node;
|
||||
} else {
|
||||
left_node = Tc_candidate_root_node;
|
||||
right_node = sig + SIG_PATH_OFFSET(ctx->params.otstype) +
|
||||
height * MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
|
||||
}
|
||||
|
||||
create_merkle_internal_value(&ctx->params, left_node, right_node,
|
||||
parent_node_id, Tc_candidate_root_node);
|
||||
|
||||
curr_node_id /= 2;
|
||||
}
|
||||
|
||||
if (memcmp(Tc_candidate_root_node, ctx->T_1_pub_key,
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type))) {
|
||||
return MBEDTLS_ERR_LMS_VERIFY_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
|
||||
/* Calculate a full Merkle tree based on a private key. This function
|
||||
* implements RFC8554 section 5.3, and is used to generate a public key (as the
|
||||
* public key is the root node of the Merkle tree).
|
||||
*
|
||||
* ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* tree The output tree, which is 2^(H + 1) hash outputs.
|
||||
* In the case of H=10 we have 2048 tree nodes (of
|
||||
* which 1024 of them are leaf nodes). Note that
|
||||
* because the Merkle tree root is 1-indexed, the 0
|
||||
* index tree node is never used.
|
||||
*/
|
||||
static int calculate_merkle_tree(const mbedtls_lms_private_t *ctx,
|
||||
unsigned char *tree)
|
||||
{
|
||||
unsigned int priv_key_idx;
|
||||
unsigned int r_node_idx;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* First create the leaf nodes, in ascending order */
|
||||
for (priv_key_idx = 0;
|
||||
priv_key_idx < MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type);
|
||||
priv_key_idx++) {
|
||||
r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + priv_key_idx;
|
||||
|
||||
ret = create_merkle_leaf_value(&ctx->params,
|
||||
ctx->ots_public_keys[priv_key_idx].public_key,
|
||||
r_node_idx,
|
||||
&tree[r_node_idx * MBEDTLS_LMS_M_NODE_BYTES(
|
||||
ctx->params.type)]);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then the internal nodes, in reverse order so that we can guarantee the
|
||||
* parent has been created */
|
||||
for (r_node_idx = MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) - 1;
|
||||
r_node_idx > 0;
|
||||
r_node_idx--) {
|
||||
ret = create_merkle_internal_value(&ctx->params,
|
||||
&tree[(r_node_idx * 2) *
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
|
||||
&tree[(r_node_idx * 2 + 1) *
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)],
|
||||
r_node_idx,
|
||||
&tree[r_node_idx *
|
||||
MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type)]);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate a path from a leaf node of the Merkle tree to the root of the tree,
|
||||
* and return the full path. This function implements RFC8554 section 5.4.1, as
|
||||
* the Merkle path is the main component of an LMS signature.
|
||||
*
|
||||
* ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* leaf_node_id Which leaf node to calculate the path from.
|
||||
*
|
||||
* path The output path, which is H hash outputs.
|
||||
*/
|
||||
static int get_merkle_path(mbedtls_lms_private_t *ctx,
|
||||
unsigned int leaf_node_id,
|
||||
unsigned char *path)
|
||||
{
|
||||
const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(ctx->params.type);
|
||||
unsigned int curr_node_id = leaf_node_id;
|
||||
unsigned int adjacent_node_id;
|
||||
unsigned char *tree = NULL;
|
||||
unsigned int height;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(ctx->params.type),
|
||||
node_bytes);
|
||||
if (tree == NULL) {
|
||||
return MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
ret = calculate_merkle_tree(ctx, tree);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (height = 0; height < MBEDTLS_LMS_H_TREE_HEIGHT(ctx->params.type);
|
||||
height++) {
|
||||
adjacent_node_id = curr_node_id ^ 1;
|
||||
|
||||
memcpy(&path[height * node_bytes],
|
||||
&tree[adjacent_node_id * node_bytes], node_bytes);
|
||||
|
||||
curr_node_id >>= 1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_zeroize_and_free(tree, node_bytes *
|
||||
(size_t) MERKLE_TREE_NODE_AM(ctx->params.type));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
if (ctx->have_private_key) {
|
||||
if (ctx->ots_private_keys != NULL) {
|
||||
for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
|
||||
mbedtls_lmots_private_free(&ctx->ots_private_keys[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->ots_public_keys != NULL) {
|
||||
for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
|
||||
mbedtls_lmots_public_free(&ctx->ots_public_keys[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_free(ctx->ots_private_keys);
|
||||
mbedtls_free(ctx->ots_public_keys);
|
||||
}
|
||||
|
||||
mbedtls_platform_zeroize(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx,
|
||||
mbedtls_lms_algorithm_type_t type,
|
||||
mbedtls_lmots_algorithm_type_t otstype,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *seed,
|
||||
size_t seed_size)
|
||||
{
|
||||
unsigned int idx = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (type != MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (otstype != MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ctx->params.type = type;
|
||||
ctx->params.otstype = otstype;
|
||||
ctx->have_private_key = 1;
|
||||
|
||||
ret = f_rng(p_rng,
|
||||
ctx->params.I_key_identifier,
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Requires a cast to size_t to avoid an implicit cast warning on certain
|
||||
* platforms (particularly Windows) */
|
||||
ctx->ots_private_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
|
||||
sizeof(*ctx->ots_private_keys));
|
||||
if (ctx->ots_private_keys == NULL) {
|
||||
ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Requires a cast to size_t to avoid an implicit cast warning on certain
|
||||
* platforms (particularly Windows) */
|
||||
ctx->ots_public_keys = mbedtls_calloc((size_t) MERKLE_TREE_LEAF_NODE_AM(ctx->params.type),
|
||||
sizeof(*ctx->ots_public_keys));
|
||||
if (ctx->ots_public_keys == NULL) {
|
||||
ret = MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
|
||||
mbedtls_lmots_private_init(&ctx->ots_private_keys[idx]);
|
||||
mbedtls_lmots_public_init(&ctx->ots_public_keys[idx]);
|
||||
}
|
||||
|
||||
|
||||
for (idx = 0; idx < MERKLE_TREE_LEAF_NODE_AM(ctx->params.type); idx++) {
|
||||
ret = mbedtls_lmots_generate_private_key(&ctx->ots_private_keys[idx],
|
||||
otstype,
|
||||
ctx->params.I_key_identifier,
|
||||
idx, seed, seed_size);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_lmots_calculate_public_key(&ctx->ots_public_keys[idx],
|
||||
&ctx->ots_private_keys[idx]);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->q_next_usable_key = 0;
|
||||
|
||||
exit:
|
||||
if (ret != 0) {
|
||||
mbedtls_lms_private_free(ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
|
||||
const mbedtls_lms_private_t *priv_ctx)
|
||||
{
|
||||
const size_t node_bytes = MBEDTLS_LMS_M_NODE_BYTES(priv_ctx->params.type);
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *tree = NULL;
|
||||
|
||||
if (!priv_ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (priv_ctx->params.type
|
||||
!= MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (priv_ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
tree = mbedtls_calloc((size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type),
|
||||
node_bytes);
|
||||
if (tree == NULL) {
|
||||
return MBEDTLS_ERR_LMS_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
memcpy(&ctx->params, &priv_ctx->params,
|
||||
sizeof(mbedtls_lmots_parameters_t));
|
||||
|
||||
ret = calculate_merkle_tree(priv_ctx, tree);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Root node is always at position 1, due to 1-based indexing */
|
||||
memcpy(ctx->T_1_pub_key, &tree[node_bytes], node_bytes);
|
||||
|
||||
ctx->have_public_key = 1;
|
||||
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
mbedtls_zeroize_and_free(tree, node_bytes *
|
||||
(size_t) MERKLE_TREE_NODE_AM(priv_ctx->params.type));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg,
|
||||
unsigned int msg_size, unsigned char *sig, size_t sig_size,
|
||||
size_t *sig_len)
|
||||
{
|
||||
uint32_t q_leaf_identifier;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (!ctx->have_private_key) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (sig_size < MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)) {
|
||||
return MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (ctx->params.type != MBEDTLS_LMS_SHA256_M32_H10) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->params.otstype
|
||||
!= MBEDTLS_LMOTS_SHA256_N32_W8) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
if (ctx->q_next_usable_key >= MERKLE_TREE_LEAF_NODE_AM(ctx->params.type)) {
|
||||
return MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS;
|
||||
}
|
||||
|
||||
|
||||
q_leaf_identifier = ctx->q_next_usable_key;
|
||||
/* This new value must _always_ be written back to the disk before the
|
||||
* signature is returned.
|
||||
*/
|
||||
ctx->q_next_usable_key += 1;
|
||||
|
||||
if (MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype)
|
||||
< SIG_OTS_SIG_OFFSET) {
|
||||
return MBEDTLS_ERR_LMS_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
ret = mbedtls_lmots_sign(&ctx->ots_private_keys[q_leaf_identifier],
|
||||
f_rng,
|
||||
p_rng,
|
||||
msg,
|
||||
msg_size,
|
||||
sig + SIG_OTS_SIG_OFFSET,
|
||||
MBEDTLS_LMS_SIG_LEN(ctx->params.type,
|
||||
ctx->params.otstype) - SIG_OTS_SIG_OFFSET,
|
||||
NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_PUT_UINT32_BE(ctx->params.type, sig, SIG_TYPE_OFFSET(ctx->params.otstype));
|
||||
MBEDTLS_PUT_UINT32_BE(q_leaf_identifier, sig, SIG_Q_LEAF_ID_OFFSET);
|
||||
|
||||
ret = get_merkle_path(ctx,
|
||||
MERKLE_TREE_INTERNAL_NODE_AM(ctx->params.type) + q_leaf_identifier,
|
||||
sig + SIG_PATH_OFFSET(ctx->params.otstype));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sig_len != NULL) {
|
||||
*sig_len = MBEDTLS_LMS_SIG_LEN(ctx->params.type, ctx->params.otstype);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
#endif /* defined(MBEDTLS_LMS_C) */
|
||||
6
engine/thirdparty/mbedtls/library/md.c
vendored
6
engine/thirdparty/mbedtls/library/md.c
vendored
|
|
@ -41,7 +41,7 @@
|
|||
#include "mbedtls/sha512.h"
|
||||
#include "mbedtls/sha3.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
#include <psa/crypto.h>
|
||||
#include "md_psa.h"
|
||||
#include "psa_util_internal.h"
|
||||
|
|
@ -761,13 +761,13 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
|
|||
return md_info->type;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
int mbedtls_md_error_from_psa(psa_status_t status)
|
||||
{
|
||||
return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors,
|
||||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
|
||||
/************************************************************************
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ void mbedtls_net_close(mbedtls_net_context *ctx)
|
|||
*/
|
||||
void mbedtls_net_free(mbedtls_net_context *ctx)
|
||||
{
|
||||
if (ctx->fd == -1) {
|
||||
if (ctx == NULL || ctx->fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
engine/thirdparty/mbedtls/library/nist_kw.c
vendored
4
engine/thirdparty/mbedtls/library/nist_kw.c
vendored
|
|
@ -102,6 +102,10 @@ int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx,
|
|||
*/
|
||||
void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_cipher_free(&ctx->cipher_ctx);
|
||||
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_nist_kw_context));
|
||||
}
|
||||
|
|
|
|||
4
engine/thirdparty/mbedtls/library/pem.c
vendored
4
engine/thirdparty/mbedtls/library/pem.c
vendored
|
|
@ -481,6 +481,10 @@ int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const
|
|||
|
||||
void mbedtls_pem_free(mbedtls_pem_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->buf != NULL) {
|
||||
mbedtls_zeroize_and_free(ctx->buf, ctx->buflen);
|
||||
}
|
||||
|
|
|
|||
46
engine/thirdparty/mbedtls/library/pk.c
vendored
46
engine/thirdparty/mbedtls/library/pk.c
vendored
|
|
@ -868,7 +868,6 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id,
|
|||
psa_status_t status;
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_algorithm_t alg_type;
|
||||
size_t key_bits;
|
||||
/* Use a buffer size large enough to contain either a key pair or public key. */
|
||||
unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE];
|
||||
|
|
@ -899,7 +898,6 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id,
|
|||
key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
|
||||
}
|
||||
key_bits = psa_get_key_bits(&key_attr);
|
||||
alg_type = psa_get_key_algorithm(&key_attr);
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) ||
|
||||
|
|
@ -919,6 +917,7 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
psa_algorithm_t alg_type = psa_get_key_algorithm(&key_attr);
|
||||
mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
|
||||
if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) {
|
||||
md_type = mbedtls_md_type_from_psa_alg(alg_type);
|
||||
|
|
@ -968,6 +967,7 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id,
|
|||
} else
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
{
|
||||
(void) key_bits;
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
|
|
@ -1327,43 +1327,19 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
|
|||
}
|
||||
|
||||
if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) {
|
||||
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t psa_alg, sign_alg;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_algorithm_t psa_enrollment_alg;
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_get_key_attributes(ctx->priv_id, &key_attr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
psa_alg = psa_get_key_algorithm(&key_attr);
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr);
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
psa_reset_key_attributes(&key_attr);
|
||||
|
||||
/* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between
|
||||
* alg and enrollment alg should be of type RSA_PSS. */
|
||||
if (PSA_ALG_IS_RSA_PSS(psa_alg)) {
|
||||
sign_alg = psa_alg;
|
||||
}
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) {
|
||||
sign_alg = psa_enrollment_alg;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
else {
|
||||
/* The opaque key has no RSA PSS algorithm associated. */
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Adjust the hashing algorithm. */
|
||||
sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg);
|
||||
|
||||
status = psa_sign_hash(ctx->priv_id, sign_alg,
|
||||
/* PSA_ALG_RSA_PSS() behaves the same as PSA_ALG_RSA_PSS_ANY_SALT() when
|
||||
* performing a signature, but they are encoded differently. Instead of
|
||||
* extracting the proper one from the wrapped key policy, just try both. */
|
||||
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg),
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
if (status == PSA_ERROR_NOT_PERMITTED) {
|
||||
status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg),
|
||||
hash, hash_len,
|
||||
sig, sig_size, sig_len);
|
||||
}
|
||||
return PSA_PK_RSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
|
|
|
|||
14
engine/thirdparty/mbedtls/library/pkwrite.c
vendored
14
engine/thirdparty/mbedtls/library/pkwrite.c
vendored
|
|
@ -65,17 +65,21 @@ static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
|
||||
uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
|
||||
size_t len = 0, tmp_len = 0;
|
||||
size_t tmp_len = 0;
|
||||
|
||||
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Ensure there's enough space in the provided buffer before copying data into it. */
|
||||
if (tmp_len > (size_t) (*p - buf)) {
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
*p -= tmp_len;
|
||||
memcpy(*p, tmp, tmp_len);
|
||||
len += tmp_len;
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
|
||||
return (int) len;
|
||||
return (int) tmp_len;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
|
||||
|
|
@ -125,6 +129,10 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start,
|
|||
if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) {
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
}
|
||||
/* Ensure there's enough space in the provided buffer before copying data into it. */
|
||||
if (len > (size_t) (*p - start)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
*p -= len;
|
||||
memcpy(*p, buf, len);
|
||||
return (int) len;
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ void mbedtls_zeroize_and_free(void *buf, size_t len)
|
|||
#include <time.h>
|
||||
#if !defined(_WIN32) && (defined(unix) || \
|
||||
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
|
||||
defined(__MACH__)) || defined__midipix__)
|
||||
defined(__MACH__)) || defined(__midipix__))
|
||||
#include <unistd.h>
|
||||
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
|
||||
* (__APPLE__ && __MACH__) || __midipix__) */
|
||||
|
|
|
|||
9233
engine/thirdparty/mbedtls/library/psa_crypto.c
vendored
Normal file
9233
engine/thirdparty/mbedtls/library/psa_crypto.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
649
engine/thirdparty/mbedtls/library/psa_crypto_aead.c
vendored
Normal file
649
engine/thirdparty/mbedtls/library/psa_crypto_aead.c
vendored
Normal file
|
|
@ -0,0 +1,649 @@
|
|||
/*
|
||||
* PSA AEAD entry points
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include "mbedtls/ccm.h"
|
||||
#include "mbedtls/chachapoly.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
static psa_status_t psa_aead_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_cipher_id_t cipher_id;
|
||||
mbedtls_cipher_mode_t mode;
|
||||
size_t key_bits = attributes->bits;
|
||||
(void) key_buffer_size;
|
||||
|
||||
status = mbedtls_cipher_values_from_psa(alg, attributes->type,
|
||||
&key_bits, &mode, &cipher_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
|
||||
operation->alg = PSA_ALG_CCM;
|
||||
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
|
||||
* The call to mbedtls_ccm_encrypt_and_tag or
|
||||
* mbedtls_ccm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_ccm_init(&operation->ctx.ccm);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
|
||||
key_buffer, (unsigned int) key_bits));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
|
||||
operation->alg = PSA_ALG_GCM;
|
||||
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
|
||||
* The call to mbedtls_gcm_crypt_and_tag or
|
||||
* mbedtls_gcm_auth_decrypt will validate the tag length. */
|
||||
if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_gcm_init(&operation->ctx.gcm);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
|
||||
key_buffer, (unsigned int) key_bits));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
|
||||
operation->alg = PSA_ALG_CHACHA20_POLY1305;
|
||||
/* We only support the default tag length. */
|
||||
if (alg != PSA_ALG_CHACHA20_POLY1305) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
mbedtls_chachapoly_init(&operation->ctx.chachapoly);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
|
||||
key_buffer));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
|
||||
default:
|
||||
(void) status;
|
||||
(void) key_buffer;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
operation->key_type = psa_get_key_type(attributes);
|
||||
|
||||
operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_aead_encrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *plaintext, size_t plaintext_length,
|
||||
uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
|
||||
uint8_t *tag;
|
||||
|
||||
status = psa_aead_setup(&operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* For all currently supported modes, the tag is at the end of the
|
||||
* ciphertext. */
|
||||
if (ciphertext_size < (plaintext_length + operation.tag_length)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
tag = ciphertext + plaintext_length;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation.alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm,
|
||||
plaintext_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
plaintext, ciphertext,
|
||||
tag, operation.tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation.alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm,
|
||||
MBEDTLS_GCM_ENCRYPT,
|
||||
plaintext_length,
|
||||
nonce, nonce_length,
|
||||
additional_data, additional_data_length,
|
||||
plaintext, ciphertext,
|
||||
operation.tag_length, tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (operation.tag_length != 16) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly,
|
||||
plaintext_length,
|
||||
nonce,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
plaintext,
|
||||
ciphertext,
|
||||
tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) tag;
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
(void) additional_data;
|
||||
(void) additional_data_length;
|
||||
(void) plaintext;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*ciphertext_length = plaintext_length + operation.tag_length;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_aead_abort(&operation);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Locate the tag in a ciphertext buffer containing the encrypted data
|
||||
* followed by the tag. Return the length of the part preceding the tag in
|
||||
* *plaintext_length. This is the size of the plaintext in modes where
|
||||
* the encrypted data has the same size as the plaintext, such as
|
||||
* CCM and GCM. */
|
||||
static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length,
|
||||
const uint8_t *ciphertext,
|
||||
size_t ciphertext_length,
|
||||
size_t plaintext_size,
|
||||
const uint8_t **p_tag)
|
||||
{
|
||||
size_t payload_length;
|
||||
if (tag_length > ciphertext_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
payload_length = ciphertext_length - tag_length;
|
||||
if (payload_length > plaintext_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
*p_tag = ciphertext + payload_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_aead_decrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *nonce, size_t nonce_length,
|
||||
const uint8_t *additional_data, size_t additional_data_length,
|
||||
const uint8_t *ciphertext, size_t ciphertext_length,
|
||||
uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
|
||||
const uint8_t *tag = NULL;
|
||||
|
||||
status = psa_aead_setup(&operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_aead_unpadded_locate_tag(operation.tag_length,
|
||||
ciphertext, ciphertext_length,
|
||||
plaintext_size, &tag);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation.alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_auth_decrypt(&operation.ctx.ccm,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
ciphertext, plaintext,
|
||||
tag, operation.tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation.alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_auth_decrypt(&operation.ctx.gcm,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce, nonce_length,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
tag, operation.tag_length,
|
||||
ciphertext, plaintext));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (operation.tag_length != 16) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly,
|
||||
ciphertext_length - operation.tag_length,
|
||||
nonce,
|
||||
additional_data,
|
||||
additional_data_length,
|
||||
tag,
|
||||
ciphertext,
|
||||
plaintext));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
(void) additional_data;
|
||||
(void) additional_data_length;
|
||||
(void) plaintext;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*plaintext_length = ciphertext_length - operation.tag_length;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_aead_abort(&operation);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*plaintext_length = ciphertext_length - operation.tag_length;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the key and algorithm for a multipart authenticated encryption
|
||||
* operation. */
|
||||
psa_status_t mbedtls_psa_aead_encrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_aead_setup(operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
operation->is_encrypt = 1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the key and algorithm for a multipart authenticated decryption
|
||||
* operation. */
|
||||
psa_status_t mbedtls_psa_aead_decrypt_setup(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
status = psa_aead_setup(operation, attributes, key_buffer,
|
||||
key_buffer_size, alg);
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
operation->is_encrypt = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set a nonce for the multipart AEAD operation*/
|
||||
psa_status_t mbedtls_psa_aead_set_nonce(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *nonce,
|
||||
size_t nonce_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_starts(&operation->ctx.gcm,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
|
||||
nonce,
|
||||
nonce_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_starts(&operation->ctx.ccm,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT,
|
||||
nonce,
|
||||
nonce_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
/* Note - ChaChaPoly allows an 8 byte nonce, but we would have to
|
||||
* allocate a buffer in the operation, copy the nonce to it and pad
|
||||
* it, so for now check the nonce is 12 bytes, as
|
||||
* mbedtls_chachapoly_starts() assumes it can read 12 bytes from the
|
||||
* passed in buffer. */
|
||||
if (nonce_length != 12) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_starts(&operation->ctx.chachapoly,
|
||||
nonce,
|
||||
operation->is_encrypt ?
|
||||
MBEDTLS_CHACHAPOLY_ENCRYPT :
|
||||
MBEDTLS_CHACHAPOLY_DECRYPT));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) nonce;
|
||||
(void) nonce_length;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Declare the lengths of the message and additional data for AEAD. */
|
||||
psa_status_t mbedtls_psa_aead_set_lengths(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
size_t ad_length,
|
||||
size_t plaintext_length)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_ccm_set_lengths(&operation->ctx.ccm,
|
||||
ad_length,
|
||||
plaintext_length,
|
||||
operation->tag_length));
|
||||
|
||||
}
|
||||
#else /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
(void) operation;
|
||||
(void) ad_length;
|
||||
(void) plaintext_length;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/* Pass additional data to an active multipart AEAD operation. */
|
||||
psa_status_t mbedtls_psa_aead_update_ad(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly,
|
||||
input,
|
||||
input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Encrypt or decrypt a message fragment in an active multipart AEAD
|
||||
* operation.*/
|
||||
psa_status_t mbedtls_psa_aead_update(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
size_t update_output_length;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
update_output_length = input_length;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_update(&operation->ctx.gcm,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
if (output_size < input_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_update(&operation->ctx.ccm,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
if (output_size < input_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_update(&operation->ctx.chachapoly,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) operation;
|
||||
(void) input;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
*output_length = update_output_length;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Finish encrypting a message in a multipart AEAD operation. */
|
||||
psa_status_t mbedtls_psa_aead_finish(
|
||||
mbedtls_psa_aead_operation_t *operation,
|
||||
uint8_t *ciphertext,
|
||||
size_t ciphertext_size,
|
||||
size_t *ciphertext_length,
|
||||
uint8_t *tag,
|
||||
size_t tag_size,
|
||||
size_t *tag_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t finish_output_size = 0;
|
||||
|
||||
if (tag_size < operation->tag_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
if (operation->alg == PSA_ALG_GCM) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_gcm_finish(&operation->ctx.gcm,
|
||||
ciphertext, ciphertext_size, ciphertext_length,
|
||||
tag, operation->tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
if (operation->alg == PSA_ALG_CCM) {
|
||||
/* tag must be big enough to store a tag of size passed into set
|
||||
* lengths. */
|
||||
if (tag_size < operation->tag_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ccm_finish(&operation->ctx.ccm,
|
||||
tag, operation->tag_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
|
||||
/* Belt and braces. Although the above tag_size check should have
|
||||
* already done this, if we later start supporting smaller tag sizes
|
||||
* for chachapoly, then passing a tag buffer smaller than 16 into here
|
||||
* could cause a buffer overflow, so better safe than sorry. */
|
||||
if (tag_size < 16) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_chachapoly_finish(&operation->ctx.chachapoly,
|
||||
tag));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
{
|
||||
(void) ciphertext;
|
||||
(void) ciphertext_size;
|
||||
(void) ciphertext_length;
|
||||
(void) tag;
|
||||
(void) tag_size;
|
||||
(void) tag_length;
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == PSA_SUCCESS) {
|
||||
/* This will be zero for all supported algorithms currently, but left
|
||||
* here for future support. */
|
||||
*ciphertext_length = finish_output_size;
|
||||
*tag_length = operation->tag_length;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Abort an AEAD operation */
|
||||
psa_status_t mbedtls_psa_aead_abort(
|
||||
mbedtls_psa_aead_operation_t *operation)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_CCM:
|
||||
mbedtls_ccm_free(&operation->ctx.ccm);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_GCM:
|
||||
mbedtls_gcm_free(&operation->ctx.gcm);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_CHACHA20_POLY1305:
|
||||
mbedtls_chachapoly_free(&operation->ctx.chachapoly);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
|
||||
}
|
||||
|
||||
operation->is_encrypt = 0;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
724
engine/thirdparty/mbedtls/library/psa_crypto_cipher.c
vendored
Normal file
724
engine/thirdparty/mbedtls/library/psa_crypto_cipher.c
vendored
Normal file
|
|
@ -0,0 +1,724 @@
|
|||
/*
|
||||
* PSA cipher driver entry points
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
|
||||
* are enabled, but it does not provide any compatibility check between them
|
||||
* (i.e. if the specified key works with the specified algorithm). This helper
|
||||
* function is meant to provide this support.
|
||||
* mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
|
||||
* requires CIPHER_C to be enabled.
|
||||
*/
|
||||
static psa_status_t mbedtls_cipher_validate_values(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type)
|
||||
{
|
||||
/* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
|
||||
eliminate bits of the logic below. */
|
||||
#if !defined(PSA_WANT_KEY_TYPE_AES)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_ARIA)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_KEY_TYPE_DES)
|
||||
MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CCM)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_GCM)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CTR)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CFB)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_OFB)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_XTS)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CBC_PKCS7)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
|
||||
#endif
|
||||
#if !defined(PSA_WANT_ALG_CMAC)
|
||||
MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
|
||||
#endif
|
||||
|
||||
if (alg == PSA_ALG_STREAM_CIPHER ||
|
||||
alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
|
||||
if (key_type == PSA_KEY_TYPE_CHACHA20) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
|
||||
alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
|
||||
alg == PSA_ALG_CCM_STAR_NO_TAG) {
|
||||
if (key_type == PSA_KEY_TYPE_AES ||
|
||||
key_type == PSA_KEY_TYPE_ARIA ||
|
||||
key_type == PSA_KEY_TYPE_CAMELLIA) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (alg == PSA_ALG_CTR ||
|
||||
alg == PSA_ALG_CFB ||
|
||||
alg == PSA_ALG_OFB ||
|
||||
alg == PSA_ALG_XTS ||
|
||||
alg == PSA_ALG_ECB_NO_PADDING ||
|
||||
alg == PSA_ALG_CBC_NO_PADDING ||
|
||||
alg == PSA_ALG_CBC_PKCS7 ||
|
||||
alg == PSA_ALG_CMAC) {
|
||||
if (key_type == PSA_KEY_TYPE_AES ||
|
||||
key_type == PSA_KEY_TYPE_ARIA ||
|
||||
key_type == PSA_KEY_TYPE_DES ||
|
||||
key_type == PSA_KEY_TYPE_CAMELLIA) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_cipher_values_from_psa(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type,
|
||||
size_t *key_bits,
|
||||
mbedtls_cipher_mode_t *mode,
|
||||
mbedtls_cipher_id_t *cipher_id)
|
||||
{
|
||||
mbedtls_cipher_id_t cipher_id_tmp;
|
||||
/* Only DES modifies key_bits */
|
||||
#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
(void) key_bits;
|
||||
#endif
|
||||
|
||||
if (PSA_ALG_IS_AEAD(alg)) {
|
||||
alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
|
||||
}
|
||||
|
||||
if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
|
||||
switch (alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
|
||||
case PSA_ALG_STREAM_CIPHER:
|
||||
*mode = MBEDTLS_MODE_STREAM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
|
||||
case PSA_ALG_CTR:
|
||||
*mode = MBEDTLS_MODE_CTR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
|
||||
case PSA_ALG_CFB:
|
||||
*mode = MBEDTLS_MODE_CFB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
|
||||
case PSA_ALG_OFB:
|
||||
*mode = MBEDTLS_MODE_OFB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
case PSA_ALG_ECB_NO_PADDING:
|
||||
*mode = MBEDTLS_MODE_ECB;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
*mode = MBEDTLS_MODE_CBC;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
|
||||
case PSA_ALG_CBC_PKCS7:
|
||||
*mode = MBEDTLS_MODE_CBC;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
|
||||
case PSA_ALG_CCM_STAR_NO_TAG:
|
||||
*mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
|
||||
*mode = MBEDTLS_MODE_CCM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
|
||||
*mode = MBEDTLS_MODE_GCM;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
|
||||
case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
|
||||
*mode = MBEDTLS_MODE_CHACHAPOLY;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
} else if (alg == PSA_ALG_CMAC) {
|
||||
*mode = MBEDTLS_MODE_ECB;
|
||||
} else {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
switch (key_type) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
|
||||
case PSA_KEY_TYPE_AES:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
|
||||
case PSA_KEY_TYPE_ARIA:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
case PSA_KEY_TYPE_DES:
|
||||
/* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
|
||||
* and 192 for three-key Triple-DES. */
|
||||
if (*key_bits == 64) {
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
|
||||
} else {
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
|
||||
}
|
||||
/* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
|
||||
* but two-key Triple-DES is functionally three-key Triple-DES
|
||||
* with K1=K3, so that's how we present it to mbedtls. */
|
||||
if (*key_bits == 128) {
|
||||
*key_bits = 192;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
|
||||
case PSA_KEY_TYPE_CAMELLIA:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
|
||||
case PSA_KEY_TYPE_CHACHA20:
|
||||
cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (cipher_id != NULL) {
|
||||
*cipher_id = cipher_id_tmp;
|
||||
}
|
||||
|
||||
return mbedtls_cipher_validate_values(alg, key_type);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
||||
psa_algorithm_t alg,
|
||||
psa_key_type_t key_type,
|
||||
size_t key_bits,
|
||||
mbedtls_cipher_id_t *cipher_id)
|
||||
{
|
||||
mbedtls_cipher_mode_t mode;
|
||||
psa_status_t status;
|
||||
mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
|
||||
|
||||
status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
if (cipher_id != NULL) {
|
||||
*cipher_id = cipher_id_tmp;
|
||||
}
|
||||
|
||||
return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
|
||||
|
||||
static psa_status_t psa_cipher_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
mbedtls_operation_t cipher_operation)
|
||||
{
|
||||
int ret = 0;
|
||||
size_t key_bits;
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
psa_key_type_t key_type = attributes->type;
|
||||
|
||||
(void) key_buffer_size;
|
||||
|
||||
mbedtls_cipher_init(&operation->ctx.cipher);
|
||||
|
||||
operation->alg = alg;
|
||||
key_bits = attributes->bits;
|
||||
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
|
||||
key_bits, NULL);
|
||||
if (cipher_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
|
||||
if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
|
||||
/* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
|
||||
uint8_t keys[24];
|
||||
memcpy(keys, key_buffer, 16);
|
||||
memcpy(keys + 16, key_buffer, 8);
|
||||
ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
|
||||
keys,
|
||||
192, cipher_operation);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
|
||||
(int) key_bits, cipher_operation);
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
|
||||
switch (alg) {
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
|
||||
MBEDTLS_PADDING_NONE);
|
||||
break;
|
||||
case PSA_ALG_CBC_PKCS7:
|
||||
ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
|
||||
MBEDTLS_PADDING_PKCS7);
|
||||
break;
|
||||
default:
|
||||
/* The algorithm doesn't involve padding. */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
|
||||
MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
|
||||
|
||||
operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
|
||||
PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
|
||||
operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
|
||||
|
||||
exit:
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_encrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_cipher_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg, MBEDTLS_ENCRYPT);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_decrypt_setup(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_cipher_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg, MBEDTLS_DECRYPT);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_set_iv(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *iv, size_t iv_length)
|
||||
{
|
||||
if (iv_length != operation->iv_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_cipher_set_iv(&operation->ctx.cipher,
|
||||
iv, iv_length));
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
/** Process input for which the algorithm is set to ECB mode.
|
||||
*
|
||||
* This requires manual processing, since the PSA API is defined as being
|
||||
* able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
|
||||
* but the underlying mbedtls_cipher_update only takes full blocks.
|
||||
*
|
||||
* \param ctx The mbedtls cipher context to use. It must have been
|
||||
* set up for ECB.
|
||||
* \param[in] input The input plaintext or ciphertext to process.
|
||||
* \param input_length The number of bytes to process from \p input.
|
||||
* This does not need to be aligned to a block boundary.
|
||||
* If there is a partial block at the end of the input,
|
||||
* it is stored in \p ctx for future processing.
|
||||
* \param output The buffer where the output is written. It must be
|
||||
* at least `BS * floor((p + input_length) / BS)` bytes
|
||||
* long, where `p` is the number of bytes in the
|
||||
* unprocessed partial block in \p ctx (with
|
||||
* `0 <= p <= BS - 1`) and `BS` is the block size.
|
||||
* \param output_length On success, the number of bytes written to \p output.
|
||||
* \c 0 on error.
|
||||
*
|
||||
* \return #PSA_SUCCESS or an error from a hardware accelerator
|
||||
*/
|
||||
static psa_status_t psa_cipher_update_ecb(
|
||||
mbedtls_cipher_context_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
|
||||
size_t internal_output_length = 0;
|
||||
*output_length = 0;
|
||||
|
||||
if (input_length == 0) {
|
||||
status = PSA_SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ctx->unprocessed_len > 0) {
|
||||
/* Fill up to block size, and run the block if there's a full one. */
|
||||
size_t bytes_to_copy = block_size - ctx->unprocessed_len;
|
||||
|
||||
if (input_length < bytes_to_copy) {
|
||||
bytes_to_copy = input_length;
|
||||
}
|
||||
|
||||
memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
|
||||
input, bytes_to_copy);
|
||||
input_length -= bytes_to_copy;
|
||||
input += bytes_to_copy;
|
||||
ctx->unprocessed_len += bytes_to_copy;
|
||||
|
||||
if (ctx->unprocessed_len == block_size) {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(ctx,
|
||||
ctx->unprocessed_data,
|
||||
block_size,
|
||||
output, &internal_output_length));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
output += internal_output_length;
|
||||
*output_length += internal_output_length;
|
||||
ctx->unprocessed_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (input_length >= block_size) {
|
||||
/* Run all full blocks we have, one by one */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(ctx, input,
|
||||
block_size,
|
||||
output, &internal_output_length));
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
input_length -= block_size;
|
||||
input += block_size;
|
||||
|
||||
output += internal_output_length;
|
||||
*output_length += internal_output_length;
|
||||
}
|
||||
|
||||
if (input_length > 0) {
|
||||
/* Save unprocessed bytes for later processing */
|
||||
memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
|
||||
input, input_length);
|
||||
ctx->unprocessed_len += input_length;
|
||||
}
|
||||
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_update(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
const uint8_t *input, size_t input_length,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t expected_output_size;
|
||||
|
||||
if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
|
||||
/* Take the unprocessed partial block left over from previous
|
||||
* update calls, if any, plus the input to this call. Remove
|
||||
* the last partial block, if any. You get the data that will be
|
||||
* output in this call. */
|
||||
expected_output_size =
|
||||
(operation->ctx.cipher.unprocessed_len + input_length)
|
||||
/ operation->block_length * operation->block_length;
|
||||
} else {
|
||||
expected_output_size = input_length;
|
||||
}
|
||||
|
||||
if (output_size < expected_output_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
|
||||
if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
|
||||
/* mbedtls_cipher_update has an API inconsistency: it will only
|
||||
* process a single block at a time in ECB mode. Abstract away that
|
||||
* inconsistency here to match the PSA API behaviour. */
|
||||
status = psa_cipher_update_ecb(&operation->ctx.cipher,
|
||||
input,
|
||||
input_length,
|
||||
output,
|
||||
output_length);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
|
||||
if (input_length == 0) {
|
||||
/* There is no input, nothing to be done */
|
||||
*output_length = 0;
|
||||
status = PSA_SUCCESS;
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_update(&operation->ctx.cipher, input,
|
||||
input_length, output, output_length));
|
||||
|
||||
if (*output_length > output_size) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_finish(
|
||||
mbedtls_psa_cipher_operation_t *operation,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
|
||||
|
||||
if (operation->ctx.cipher.unprocessed_len != 0) {
|
||||
if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
|
||||
operation->alg == PSA_ALG_CBC_NO_PADDING) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_cipher_finish(&operation->ctx.cipher,
|
||||
temp_output_buffer,
|
||||
output_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (*output_length == 0) {
|
||||
; /* Nothing to copy. Note that output may be NULL in this case. */
|
||||
} else if (output_size >= *output_length) {
|
||||
memcpy(output, temp_output_buffer, *output_length);
|
||||
} else {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(temp_output_buffer,
|
||||
sizeof(temp_output_buffer));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_abort(
|
||||
mbedtls_psa_cipher_operation_t *operation)
|
||||
{
|
||||
/* Sanity check (shouldn't happen: operation->alg should
|
||||
* always have been initialized to a valid value). */
|
||||
if (!PSA_ALG_IS_CIPHER(operation->alg)) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
mbedtls_cipher_free(&operation->ctx.cipher);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_encrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *iv,
|
||||
size_t iv_length,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
|
||||
size_t update_output_length, finish_output_length;
|
||||
|
||||
status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (iv_length > 0) {
|
||||
status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_update(&operation, input, input_length,
|
||||
output, output_size,
|
||||
&update_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_finish(
|
||||
&operation,
|
||||
mbedtls_buffer_offset(output, update_output_length),
|
||||
output_size - update_output_length, &finish_output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = update_output_length + finish_output_length;
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_cipher_abort(&operation);
|
||||
} else {
|
||||
mbedtls_psa_cipher_abort(&operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_cipher_decrypt(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
|
||||
size_t olength, accumulated_length;
|
||||
|
||||
status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
|
||||
key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (operation.iv_length > 0) {
|
||||
status = mbedtls_psa_cipher_set_iv(&operation,
|
||||
input, operation.iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_psa_cipher_update(
|
||||
&operation,
|
||||
mbedtls_buffer_offset_const(input, operation.iv_length),
|
||||
input_length - operation.iv_length,
|
||||
output, output_size, &olength);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
accumulated_length = olength;
|
||||
|
||||
status = mbedtls_psa_cipher_finish(
|
||||
&operation,
|
||||
mbedtls_buffer_offset(output, accumulated_length),
|
||||
output_size - accumulated_length, &olength);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*output_length = accumulated_length + olength;
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_cipher_abort(&operation);
|
||||
} else {
|
||||
mbedtls_psa_cipher_abort(&operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
22
engine/thirdparty/mbedtls/library/psa_crypto_client.c
vendored
Normal file
22
engine/thirdparty/mbedtls/library/psa_crypto_client.c
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* PSA crypto client code
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
void psa_reset_key_attributes(psa_key_attributes_t *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(*attributes));
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
128
engine/thirdparty/mbedtls/library/psa_crypto_core.h
vendored
128
engine/thirdparty/mbedtls/library/psa_crypto_core.h
vendored
|
|
@ -59,6 +59,8 @@ typedef enum {
|
|||
* and metadata for one key.
|
||||
*/
|
||||
typedef struct {
|
||||
/* This field is accessed in a lot of places. Putting it first
|
||||
* reduces the code size. */
|
||||
psa_key_attributes_t attr;
|
||||
|
||||
/*
|
||||
|
|
@ -78,35 +80,77 @@ typedef struct {
|
|||
* slots that are in a suitable state for the function.
|
||||
* For example, psa_get_and_lock_key_slot_in_memory, which finds a slot
|
||||
* containing a given key ID, will only check slots whose state variable is
|
||||
* PSA_SLOT_FULL. */
|
||||
* PSA_SLOT_FULL.
|
||||
*/
|
||||
psa_key_slot_state_t state;
|
||||
|
||||
/*
|
||||
* Number of functions registered as reading the material in the key slot.
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/* The index of the slice containing this slot.
|
||||
* This field must be filled if the slot contains a key
|
||||
* (including keys being created or destroyed), and can be either
|
||||
* filled or 0 when the slot is free.
|
||||
*
|
||||
* Library functions must not write directly to registered_readers
|
||||
*
|
||||
* A function must call psa_register_read(slot) before reading the current
|
||||
* contents of the slot for an operation.
|
||||
* They then must call psa_unregister_read(slot) once they have finished
|
||||
* reading the current contents of the slot. If the key slot mutex is not
|
||||
* held (when mutexes are enabled), this call must be done via a call to
|
||||
* psa_unregister_read_under_mutex(slot).
|
||||
* A function must call psa_key_slot_has_readers(slot) to check if
|
||||
* the slot is in use for reading.
|
||||
*
|
||||
* This counter is used to prevent resetting the key slot while the library
|
||||
* may access it. For example, such control is needed in the following
|
||||
* scenarios:
|
||||
* . In case of key slot starvation, all key slots contain the description
|
||||
* of a key, and the library asks for the description of a persistent
|
||||
* key not present in the key slots, the key slots currently accessed by
|
||||
* the library cannot be reclaimed to free a key slot to load the
|
||||
* persistent key.
|
||||
* . In case of a multi-threaded application where one thread asks to close
|
||||
* or purge or destroy a key while it is in use by the library through
|
||||
* another thread. */
|
||||
size_t registered_readers;
|
||||
* In most cases, the slice index can be deduced from the key identifer.
|
||||
* We keep it in a separate field for robustness (it reduces the chance
|
||||
* that a coding mistake in the key store will result in accessing the
|
||||
* wrong slice), and also so that it's available even on code paths
|
||||
* during creation or destruction where the key identifier might not be
|
||||
* filled in.
|
||||
* */
|
||||
uint8_t slice_index;
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
union {
|
||||
struct {
|
||||
/* The index of the next slot in the free list for this
|
||||
* slice, relative * to the next array element.
|
||||
*
|
||||
* That is, 0 means the next slot, 1 means the next slot
|
||||
* but one, etc. -1 would mean the slot itself. -2 means
|
||||
* the previous slot, etc.
|
||||
*
|
||||
* If this is beyond the array length, the free list ends with the
|
||||
* current element.
|
||||
*
|
||||
* The reason for this strange encoding is that 0 means the next
|
||||
* element. This way, when we allocate a slice and initialize it
|
||||
* to all-zero, the slice is ready for use, with a free list that
|
||||
* consists of all the slots in order.
|
||||
*/
|
||||
int32_t next_free_relative_to_next;
|
||||
} free;
|
||||
|
||||
struct {
|
||||
/*
|
||||
* Number of functions registered as reading the material in the key slot.
|
||||
*
|
||||
* Library functions must not write directly to registered_readers
|
||||
*
|
||||
* A function must call psa_register_read(slot) before reading
|
||||
* the current contents of the slot for an operation.
|
||||
* They then must call psa_unregister_read(slot) once they have
|
||||
* finished reading the current contents of the slot. If the key
|
||||
* slot mutex is not held (when mutexes are enabled), this call
|
||||
* must be done via a call to
|
||||
* psa_unregister_read_under_mutex(slot).
|
||||
* A function must call psa_key_slot_has_readers(slot) to check if
|
||||
* the slot is in use for reading.
|
||||
*
|
||||
* This counter is used to prevent resetting the key slot while
|
||||
* the library may access it. For example, such control is needed
|
||||
* in the following scenarios:
|
||||
* . In case of key slot starvation, all key slots contain the
|
||||
* description of a key, and the library asks for the
|
||||
* description of a persistent key not present in the
|
||||
* key slots, the key slots currently accessed by the
|
||||
* library cannot be reclaimed to free a key slot to load
|
||||
* the persistent key.
|
||||
* . In case of a multi-threaded application where one thread
|
||||
* asks to close or purge or destroy a key while it is in use
|
||||
* by the library through another thread. */
|
||||
size_t registered_readers;
|
||||
} occupied;
|
||||
} var;
|
||||
|
||||
/* Dynamically allocated key data buffer.
|
||||
* Format as specified in psa_export_key(). */
|
||||
|
|
@ -169,7 +213,7 @@ typedef struct {
|
|||
*/
|
||||
static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot)
|
||||
{
|
||||
return slot->registered_readers > 0;
|
||||
return slot->var.occupied.registered_readers > 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
|
@ -343,19 +387,18 @@ psa_status_t psa_export_public_key_internal(
|
|||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
/** Whether a key production parameters structure is the default.
|
||||
/** Whether a key custom production parameters structure is the default.
|
||||
*
|
||||
* Calls to a key generation driver with non-default production parameters
|
||||
* Calls to a key generation driver with non-default custom production parameters
|
||||
* require a driver supporting custom production parameters.
|
||||
*
|
||||
* \param[in] params The key production parameters to check.
|
||||
* \param params_data_length Size of `params->data` in bytes.
|
||||
* \param[in] custom The key custom production parameters to check.
|
||||
* \param custom_data_length Size of the associated variable-length data
|
||||
* in bytes.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
int psa_key_production_parameters_are_default(
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length);
|
||||
#endif
|
||||
int psa_custom_key_parameters_are_default(
|
||||
const psa_custom_key_parameters_t *custom,
|
||||
size_t custom_data_length);
|
||||
|
||||
/**
|
||||
* \brief Generate a key.
|
||||
|
|
@ -364,9 +407,9 @@ int psa_key_production_parameters_are_default(
|
|||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the key to generate.
|
||||
* \param[in] params The production parameters from
|
||||
* psa_generate_key_ext().
|
||||
* \param params_data_length The size of `params->data` in bytes.
|
||||
* \param[in] custom Custom parameters for the key generation.
|
||||
* \param[in] custom_data Variable-length data associated with \c custom.
|
||||
* \param custom_data_length Length of `custom_data` in bytes.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||
|
|
@ -380,14 +423,13 @@ int psa_key_production_parameters_are_default(
|
|||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
const psa_custom_key_parameters_t *custom,
|
||||
const uint8_t *custom_data,
|
||||
size_t custom_data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
#endif
|
||||
|
||||
/** Sign a message with a private key. For hash-and-sign algorithms,
|
||||
* this includes the hashing step.
|
||||
|
|
|
|||
|
|
@ -728,10 +728,10 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data(
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef __cplusplus
|
||||
static inline psa_status_t psa_driver_wrapper_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
const psa_custom_key_parameters_t *custom,
|
||||
const uint8_t *custom_data, size_t custom_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
|
@ -740,7 +740,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key(
|
|||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
int is_default_production =
|
||||
psa_key_production_parameters_are_default(params, params_data_length);
|
||||
psa_custom_key_parameters_are_default(custom, custom_data_length);
|
||||
if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_production )
|
||||
{
|
||||
/* We don't support passing custom production parameters
|
||||
|
|
@ -811,7 +811,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key(
|
|||
|
||||
/* Software fallback */
|
||||
status = psa_generate_key_internal(
|
||||
attributes, params, params_data_length,
|
||||
attributes, custom, custom_data, custom_data_length,
|
||||
key_buffer, key_buffer_size, key_buffer_length );
|
||||
break;
|
||||
|
||||
|
|
@ -833,7 +833,6 @@ static inline psa_status_t psa_driver_wrapper_generate_key(
|
|||
|
||||
return( status );
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline psa_status_t psa_driver_wrapper_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
|
|
|
|||
256
engine/thirdparty/mbedtls/library/psa_crypto_driver_wrappers_no_static.c
vendored
Normal file
256
engine/thirdparty/mbedtls/library/psa_crypto_driver_wrappers_no_static.c
vendored
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Functions to delegate cryptographic operations to an available
|
||||
* and appropriate accelerator.
|
||||
* Warning: This file is now auto-generated.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
/* BEGIN-common headers */
|
||||
#include "common.h"
|
||||
#include "psa_crypto_aead.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_driver_wrappers_no_static.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include "psa_crypto_pake.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
/* END-common headers */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* BEGIN-driver headers */
|
||||
/* Headers for mbedtls_test opaque driver */
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
#include "test/drivers/test_driver.h"
|
||||
|
||||
#endif
|
||||
/* Headers for mbedtls_test transparent driver */
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
#include "test/drivers/test_driver.h"
|
||||
|
||||
#endif
|
||||
/* Headers for p256 transparent driver */
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
#include "../3rdparty/p256-m/p256-m_driver_entrypoints.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* END-driver headers */
|
||||
|
||||
/* Auto-generated values depending on which drivers are registered.
|
||||
* ID 0 is reserved for unallocated operations.
|
||||
* ID 1 is reserved for the Mbed TLS software driver. */
|
||||
/* BEGIN-driver id definition */
|
||||
#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1)
|
||||
#define MBEDTLS_TEST_OPAQUE_DRIVER_ID (2)
|
||||
#define MBEDTLS_TEST_TRANSPARENT_DRIVER_ID (3)
|
||||
#define P256_TRANSPARENT_DRIVER_ID (4)
|
||||
|
||||
/* END-driver id */
|
||||
|
||||
/* BEGIN-Common Macro definitions */
|
||||
|
||||
/* END-Common Macro definitions */
|
||||
|
||||
/* Support the 'old' SE interface when asked to */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style
|
||||
* SE driver is present, to avoid unused argument errors at compile time. */
|
||||
#ifndef PSA_CRYPTO_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_DRIVER_PRESENT
|
||||
#endif
|
||||
#include "psa_crypto_se.h"
|
||||
#endif
|
||||
|
||||
/** Get the key buffer size required to store the key material of a key
|
||||
* associated with an opaque driver.
|
||||
*
|
||||
* \param[in] attributes The key attributes.
|
||||
* \param[out] key_buffer_size Minimum buffer size to contain the key material
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The minimum size for a buffer to contain the key material has been
|
||||
* returned successfully.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* The type and/or the size in bits of the key or the combination of
|
||||
* the two is not supported.
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* The key is declared with a lifetime not known to us.
|
||||
*/
|
||||
psa_status_t psa_driver_wrapper_get_key_buffer_size(
|
||||
const psa_key_attributes_t *attributes,
|
||||
size_t *key_buffer_size )
|
||||
{
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
|
||||
psa_key_type_t key_type = psa_get_key_type(attributes);
|
||||
size_t key_bits = psa_get_key_bits(attributes);
|
||||
|
||||
*key_buffer_size = 0;
|
||||
switch( location )
|
||||
{
|
||||
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||
case PSA_CRYPTO_TEST_DRIVER_LOCATION:
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
|
||||
/* Emulate property 'builtin_key_size' */
|
||||
if( psa_key_id_is_builtin(
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
|
||||
psa_get_key_id( attributes ) ) ) )
|
||||
{
|
||||
*key_buffer_size = sizeof( psa_drv_slot_number_t );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
|
||||
*key_buffer_size = mbedtls_test_opaque_size_function( key_type,
|
||||
key_bits );
|
||||
return( ( *key_buffer_size != 0 ) ?
|
||||
PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||
|
||||
default:
|
||||
(void)key_type;
|
||||
(void)key_bits;
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length )
|
||||
|
||||
{
|
||||
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
|
||||
psa_get_key_lifetime( attributes ) );
|
||||
|
||||
/* Try dynamically-registered SE interface first */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
|
||||
if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
|
||||
{
|
||||
if( ( drv->key_management == NULL ) ||
|
||||
( drv->key_management->p_export_public == NULL ) )
|
||||
{
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
return( drv->key_management->p_export_public(
|
||||
drv_context,
|
||||
*( (psa_key_slot_number_t *)key_buffer ),
|
||||
data, data_size, data_length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
switch( location )
|
||||
{
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
/* Key is stored in the slot in export representation, so
|
||||
* cycle through all known transparent accelerators */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
status = mbedtls_test_transparent_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
);
|
||||
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) )
|
||||
status = p256_transparent_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
);
|
||||
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
/* Fell through, meaning no accelerator supports this operation */
|
||||
return( psa_export_public_key_internal( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length ) );
|
||||
|
||||
/* Add cases for opaque driver here */
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
case 0x7fffff:
|
||||
return( mbedtls_test_opaque_export_public_key
|
||||
(attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
data,
|
||||
data_size,
|
||||
data_length
|
||||
));
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
default:
|
||||
/* Key is declared with a lifetime not known to us */
|
||||
return( status );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_builtin_key(
|
||||
psa_drv_slot_number_t slot_number,
|
||||
psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
|
||||
{
|
||||
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
|
||||
switch( location )
|
||||
{
|
||||
#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
|
||||
#if (defined(PSA_CRYPTO_DRIVER_TEST) )
|
||||
case 0x7fffff:
|
||||
return( mbedtls_test_opaque_get_builtin_key
|
||||
(slot_number,
|
||||
attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length
|
||||
));
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
|
||||
default:
|
||||
(void) slot_number;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) key_buffer_length;
|
||||
return( PSA_ERROR_DOES_NOT_EXIST );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
596
engine/thirdparty/mbedtls/library/psa_crypto_ecp.c
vendored
Normal file
596
engine/thirdparty/mbedtls/library/psa_crypto_ecp.c
vendored
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
/*
|
||||
* PSA ECP layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_ecp.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include <mbedtls/ecdsa.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#include <mbedtls/ecp.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
|
||||
/* Helper function to verify if the provided EC's family and key bit size are valid.
|
||||
*
|
||||
* Note: "bits" parameter is used both as input and output and it might be updated
|
||||
* in case provided input value is not multiple of 8 ("sloppy" bits).
|
||||
*/
|
||||
static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits)
|
||||
{
|
||||
switch (family) {
|
||||
case PSA_ECC_FAMILY_SECP_R1:
|
||||
switch (*bits) {
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
case 384:
|
||||
case 521:
|
||||
return PSA_SUCCESS;
|
||||
case 528:
|
||||
*bits = 521;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
|
||||
switch (*bits) {
|
||||
case 256:
|
||||
case 384:
|
||||
case 512:
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_MONTGOMERY:
|
||||
switch (*bits) {
|
||||
case 448:
|
||||
case 255:
|
||||
return PSA_SUCCESS;
|
||||
case 256:
|
||||
*bits = 255;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_SECP_K1:
|
||||
switch (*bits) {
|
||||
case 192:
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
case 256:
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_load_representation(
|
||||
psa_key_type_t type, size_t curve_bits,
|
||||
const uint8_t *data, size_t data_length,
|
||||
mbedtls_ecp_keypair **p_ecp)
|
||||
{
|
||||
mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
size_t curve_bytes = data_length;
|
||||
int explicit_bits = (curve_bits != 0);
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
/* A Weierstrass public key is represented as:
|
||||
* - The byte 0x04;
|
||||
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
|
||||
* So its data length is 2m+1 where m is the curve size in bits.
|
||||
*/
|
||||
if ((data_length & 1) == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
curve_bytes = data_length / 2;
|
||||
|
||||
/* Montgomery public keys are represented in compressed format, meaning
|
||||
* their curve_bytes is equal to the amount of input. */
|
||||
|
||||
/* Private keys are represented in uncompressed private random integer
|
||||
* format, meaning their curve_bytes is equal to the amount of input. */
|
||||
}
|
||||
|
||||
if (explicit_bits) {
|
||||
/* With an explicit bit-size, the data must have the matching length. */
|
||||
if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
} else {
|
||||
/* We need to infer the bit-size from the data. Since the only
|
||||
* information we have is the length in bytes, the value of curve_bits
|
||||
* at this stage is rounded up to the nearest multiple of 8. */
|
||||
curve_bits = PSA_BYTES_TO_BITS(curve_bytes);
|
||||
}
|
||||
|
||||
/* Allocate and initialize a key representation. */
|
||||
ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
|
||||
if (ecp == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
mbedtls_ecp_keypair_init(ecp);
|
||||
|
||||
status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Load the group. */
|
||||
grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
|
||||
curve_bits);
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_group_load(&ecp->grp, grp_id));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Load the key material. */
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
/* Load the public value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q,
|
||||
data,
|
||||
data_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Check that the point is on the curve. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
/* Load and validate the secret value. */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_read_key(ecp->grp.id,
|
||||
ecp,
|
||||
data,
|
||||
data_length));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
*p_ecp = ecp;
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
data,
|
||||
data_length,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
|
||||
PSA_ECC_FAMILY_MONTGOMERY) {
|
||||
*bits = ecp->grp.nbits + 1;
|
||||
} else {
|
||||
*bits = ecp->grp.nbits;
|
||||
}
|
||||
|
||||
/* Re-export the data to PSA export format. There is currently no support
|
||||
* for other input formats then the export format, so this is a 1-1
|
||||
* copy operation. */
|
||||
status = mbedtls_psa_ecp_export_key(attributes->type,
|
||||
ecp,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length);
|
||||
exit:
|
||||
/* Always free the PK object (will also free contained ECP context) */
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
|
||||
mbedtls_ecp_keypair *ecp,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
/* Check whether the public part is loaded */
|
||||
if (mbedtls_ecp_is_zero(&ecp->Q)) {
|
||||
/* Calculate the public key */
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
data_length,
|
||||
data,
|
||||
data_size));
|
||||
if (status != PSA_SUCCESS) {
|
||||
memset(data, 0, data_size);
|
||||
}
|
||||
|
||||
return status;
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->type, attributes->bits,
|
||||
key_buffer, key_buffer_size, &ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_ecp_export_key(
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
|
||||
ecp, data, data_size, data_length);
|
||||
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
|
||||
psa_status_t mbedtls_psa_ecp_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
|
||||
attributes->type);
|
||||
mbedtls_ecp_group_id grp_id =
|
||||
mbedtls_ecc_group_from_psa(curve, attributes->bits);
|
||||
|
||||
const mbedtls_ecp_curve_info *curve_info =
|
||||
mbedtls_ecp_curve_info_from_grp_id(grp_id);
|
||||
mbedtls_ecp_keypair ecp;
|
||||
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
mbedtls_ecp_keypair_init(&ecp);
|
||||
ret = mbedtls_ecp_gen_key(grp_id, &ecp,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
|
||||
key_buffer, key_buffer_size));
|
||||
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
|
||||
|
||||
/****************************************************************/
|
||||
/* ECDSA sign/verify */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
|
||||
psa_status_t mbedtls_psa_ecdsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t curve_bytes;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
if (signature_size < 2 * curve_bytes) {
|
||||
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
|
||||
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
|
||||
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
|
||||
&ecp->grp, &r, &s,
|
||||
&ecp->d, hash,
|
||||
hash_length, md_alg,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
#else
|
||||
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
goto cleanup;
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
|
||||
} else {
|
||||
(void) alg;
|
||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d,
|
||||
hash, hash_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r,
|
||||
signature,
|
||||
curve_bytes));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s,
|
||||
signature + curve_bytes,
|
||||
curve_bytes));
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
if (ret == 0) {
|
||||
*signature_length = 2 * curve_bytes;
|
||||
}
|
||||
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Check whether the public part is loaded. If not, load it. */
|
||||
if (mbedtls_ecp_is_zero(&ecp->Q)) {
|
||||
ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q,
|
||||
&ecp->d, &ecp->grp.G,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_ecdsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
size_t curve_bytes;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
(void) alg;
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
if (signature_length != 2 * curve_bytes) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r,
|
||||
signature,
|
||||
curve_bytes));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s,
|
||||
signature + curve_bytes,
|
||||
curve_bytes));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_psa_ecp_load_public_part(ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash,
|
||||
hash_length, &ecp->Q,
|
||||
&r, &s));
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
|
||||
|
||||
/****************************************************************/
|
||||
/* ECDH Key Agreement */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
|
||||
psa_status_t mbedtls_psa_key_agreement_ecdh(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
|
||||
uint8_t *shared_secret, size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
|
||||
!PSA_ALG_IS_ECDH(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
mbedtls_ecp_keypair *ecp = NULL;
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
attributes->type,
|
||||
attributes->bits,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&ecp);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
mbedtls_ecp_keypair *their_key = NULL;
|
||||
mbedtls_ecdh_context ecdh;
|
||||
size_t bits = 0;
|
||||
psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits);
|
||||
mbedtls_ecdh_init(&ecdh);
|
||||
|
||||
status = mbedtls_psa_ecp_load_representation(
|
||||
PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
|
||||
bits,
|
||||
peer_key,
|
||||
peer_key_length,
|
||||
&their_key);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_ecdh_calc_secret(&ecdh,
|
||||
shared_secret_length,
|
||||
shared_secret, shared_secret_size,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) {
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_platform_zeroize(shared_secret, shared_secret_size);
|
||||
}
|
||||
mbedtls_ecdh_free(&ecdh);
|
||||
mbedtls_ecp_keypair_free(their_key);
|
||||
mbedtls_free(their_key);
|
||||
mbedtls_ecp_keypair_free(ecp);
|
||||
mbedtls_free(ecp);
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
|
||||
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
321
engine/thirdparty/mbedtls/library/psa_crypto_ffdh.c
vendored
Normal file
321
engine/thirdparty/mbedtls/library/psa_crypto_ffdh.c
vendored
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* PSA FFDH layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
/* This header is only needed because it defines
|
||||
* MBEDTLS_DHM_RFC7919_FFDHEXXXX_[P|G]_BIN symbols that are used in
|
||||
* mbedtls_psa_ffdh_set_prime_generator(). Apart from that, this module
|
||||
* only uses bignum functions for arithmetic. */
|
||||
#include <mbedtls/dhm.h>
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_ffdh.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
|
||||
mbedtls_mpi *P,
|
||||
mbedtls_mpi *G)
|
||||
{
|
||||
const unsigned char *dhm_P = NULL;
|
||||
const unsigned char *dhm_G = NULL;
|
||||
size_t dhm_size_P = 0;
|
||||
size_t dhm_size_G = 0;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (P == NULL && G == NULL) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
|
||||
static const unsigned char dhm_P_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
|
||||
static const unsigned char dhm_G_2048[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
|
||||
static const unsigned char dhm_P_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
|
||||
static const unsigned char dhm_G_3072[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
|
||||
static const unsigned char dhm_P_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
|
||||
static const unsigned char dhm_G_4096[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
|
||||
static const unsigned char dhm_P_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
|
||||
static const unsigned char dhm_G_6144[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
|
||||
static const unsigned char dhm_P_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
|
||||
static const unsigned char dhm_G_8192[] =
|
||||
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
|
||||
|
||||
switch (key_size) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048)
|
||||
case sizeof(dhm_P_2048):
|
||||
dhm_P = dhm_P_2048;
|
||||
dhm_G = dhm_G_2048;
|
||||
dhm_size_P = sizeof(dhm_P_2048);
|
||||
dhm_size_G = sizeof(dhm_G_2048);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072)
|
||||
case sizeof(dhm_P_3072):
|
||||
dhm_P = dhm_P_3072;
|
||||
dhm_G = dhm_G_3072;
|
||||
dhm_size_P = sizeof(dhm_P_3072);
|
||||
dhm_size_G = sizeof(dhm_G_3072);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096)
|
||||
case sizeof(dhm_P_4096):
|
||||
dhm_P = dhm_P_4096;
|
||||
dhm_G = dhm_G_4096;
|
||||
dhm_size_P = sizeof(dhm_P_4096);
|
||||
dhm_size_G = sizeof(dhm_G_4096);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144)
|
||||
case sizeof(dhm_P_6144):
|
||||
dhm_P = dhm_P_6144;
|
||||
dhm_G = dhm_G_6144;
|
||||
dhm_size_P = sizeof(dhm_P_6144);
|
||||
dhm_size_G = sizeof(dhm_G_6144);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192)
|
||||
case sizeof(dhm_P_8192):
|
||||
dhm_P = dhm_P_8192;
|
||||
dhm_G = dhm_G_8192;
|
||||
dhm_size_P = sizeof(dhm_P_8192);
|
||||
dhm_size_G = sizeof(dhm_G_8192);
|
||||
break;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
|
||||
default:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (P != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
|
||||
dhm_size_P));
|
||||
}
|
||||
if (G != NULL) {
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
|
||||
dhm_size_G));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
|
||||
MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_ffdh_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi GX, G, X, P;
|
||||
psa_key_type_t type = attributes->type;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
|
||||
if (key_buffer_size > data_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(data, key_buffer, key_buffer_size);
|
||||
memset(data + key_buffer_size, 0,
|
||||
data_size - key_buffer_size);
|
||||
*data_length = key_buffer_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
||||
|
||||
size_t key_len = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, key_len));
|
||||
|
||||
*data_length = key_len;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT ||
|
||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE)
|
||||
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
mbedtls_mpi X, P;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
|
||||
(void) attributes;
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(key_buffer_size, &P, NULL);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* RFC7919: Traditional finite field Diffie-Hellman has each peer choose their
|
||||
secret exponent from the range [2, P-2].
|
||||
Select random value in range [3, P-1] and decrease it by 1. */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 3, &P, mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 1));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer, key_buffer_size));
|
||||
*key_buffer_length = key_buffer_size;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT)
|
||||
psa_status_t mbedtls_psa_ffdh_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
(void) attributes;
|
||||
|
||||
if (key_buffer_size < data_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
memcpy(key_buffer, data, data_length);
|
||||
*key_buffer_length = data_length;
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||
psa_status_t mbedtls_psa_ffdh_key_agreement(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *shared_secret,
|
||||
size_t shared_secret_size,
|
||||
size_t *shared_secret_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi P, G, X, GY, K;
|
||||
const size_t calculated_shared_secret_size = peer_key_length;
|
||||
|
||||
if (peer_key_length != key_buffer_size ||
|
||||
calculated_shared_secret_size > shared_secret_size) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_KEY_TYPE_IS_DH_KEY_PAIR(psa_get_key_type(attributes))) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
|
||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
|
||||
mbedtls_mpi_init(&K);
|
||||
|
||||
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||
PSA_BITS_TO_BYTES(attributes->bits), &P, &G);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||
key_buffer_size));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
|
||||
peer_key_length));
|
||||
|
||||
/* Calculate shared secret public key: K = G^(XY) mod P = GY^X mod P */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
|
||||
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
|
||||
calculated_shared_secret_size));
|
||||
|
||||
*shared_secret_length = calculated_shared_secret_size;
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
|
||||
mbedtls_mpi_free(&K);
|
||||
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
470
engine/thirdparty/mbedtls/library/psa_crypto_hash.c
vendored
Normal file
470
engine/thirdparty/mbedtls/library/psa_crypto_hash.c
vendored
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
* PSA hashing layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
|
||||
psa_status_t mbedtls_psa_hash_abort(
|
||||
mbedtls_psa_hash_operation_t *operation)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
case 0:
|
||||
/* The object has (apparently) been initialized but it is not
|
||||
* in use. It's ok to call abort on such an object, and there's
|
||||
* nothing to do. */
|
||||
break;
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_free(&operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_free(&operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_free(&operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_free(&operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_free(&operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_free(&operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_free(&operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
mbedtls_sha3_free(&operation->ctx.sha3);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
operation->alg = 0;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_setup(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* A context must be freshly initialized before it can be set up. */
|
||||
if (operation->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_init(&operation->ctx.md5);
|
||||
ret = mbedtls_md5_starts(&operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_init(&operation->ctx.ripemd160);
|
||||
ret = mbedtls_ripemd160_starts(&operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_init(&operation->ctx.sha1);
|
||||
ret = mbedtls_sha1_starts(&operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_init(&operation->ctx.sha256);
|
||||
ret = mbedtls_sha256_starts(&operation->ctx.sha256, 1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_init(&operation->ctx.sha256);
|
||||
ret = mbedtls_sha256_starts(&operation->ctx.sha256, 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_init(&operation->ctx.sha512);
|
||||
ret = mbedtls_sha512_starts(&operation->ctx.sha512, 1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_init(&operation->ctx.sha512);
|
||||
ret = mbedtls_sha512_starts(&operation->ctx.sha512, 0);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_224);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_384);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
mbedtls_sha3_init(&operation->ctx.sha3);
|
||||
ret = mbedtls_sha3_starts(&operation->ctx.sha3, MBEDTLS_SHA3_512);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return PSA_ALG_IS_HASH(alg) ?
|
||||
PSA_ERROR_NOT_SUPPORTED :
|
||||
PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (ret == 0) {
|
||||
operation->alg = alg;
|
||||
} else {
|
||||
mbedtls_psa_hash_abort(operation);
|
||||
}
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_clone(
|
||||
const mbedtls_psa_hash_operation_t *source_operation,
|
||||
mbedtls_psa_hash_operation_t *target_operation)
|
||||
{
|
||||
switch (source_operation->alg) {
|
||||
case 0:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
mbedtls_md5_clone(&target_operation->ctx.md5,
|
||||
&source_operation->ctx.md5);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
mbedtls_ripemd160_clone(&target_operation->ctx.ripemd160,
|
||||
&source_operation->ctx.ripemd160);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
mbedtls_sha1_clone(&target_operation->ctx.sha1,
|
||||
&source_operation->ctx.sha1);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
mbedtls_sha256_clone(&target_operation->ctx.sha256,
|
||||
&source_operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
mbedtls_sha256_clone(&target_operation->ctx.sha256,
|
||||
&source_operation->ctx.sha256);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
mbedtls_sha512_clone(&target_operation->ctx.sha512,
|
||||
&source_operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
mbedtls_sha512_clone(&target_operation->ctx.sha512,
|
||||
&source_operation->ctx.sha512);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
mbedtls_sha3_clone(&target_operation->ctx.sha3,
|
||||
&source_operation->ctx.sha3);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) source_operation;
|
||||
(void) target_operation;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
target_operation->alg = source_operation->alg;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_update(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
ret = mbedtls_md5_update(&operation->ctx.md5,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
ret = mbedtls_ripemd160_update(&operation->ctx.ripemd160,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
ret = mbedtls_sha1_update(&operation->ctx.sha1,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
ret = mbedtls_sha256_update(&operation->ctx.sha256,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
ret = mbedtls_sha256_update(&operation->ctx.sha256,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
ret = mbedtls_sha512_update(&operation->ctx.sha512,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
ret = mbedtls_sha512_update(&operation->ctx.sha512,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
ret = mbedtls_sha3_update(&operation->ctx.sha3,
|
||||
input, input_length);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_finish(
|
||||
mbedtls_psa_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t actual_hash_length = PSA_HASH_LENGTH(operation->alg);
|
||||
|
||||
/* Fill the output buffer with something that isn't a valid hash
|
||||
* (barring an attack on the hash and deliberately-crafted input),
|
||||
* in case the caller doesn't check the return status properly. */
|
||||
*hash_length = hash_size;
|
||||
/* If hash_size is 0 then hash may be NULL and then the
|
||||
* call to memset would have undefined behavior. */
|
||||
if (hash_size != 0) {
|
||||
memset(hash, '!', hash_size);
|
||||
}
|
||||
|
||||
if (hash_size < actual_hash_length) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (operation->alg) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5)
|
||||
case PSA_ALG_MD5:
|
||||
ret = mbedtls_md5_finish(&operation->ctx.md5, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160)
|
||||
case PSA_ALG_RIPEMD160:
|
||||
ret = mbedtls_ripemd160_finish(&operation->ctx.ripemd160, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1)
|
||||
case PSA_ALG_SHA_1:
|
||||
ret = mbedtls_sha1_finish(&operation->ctx.sha1, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224)
|
||||
case PSA_ALG_SHA_224:
|
||||
ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256)
|
||||
case PSA_ALG_SHA_256:
|
||||
ret = mbedtls_sha256_finish(&operation->ctx.sha256, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384)
|
||||
case PSA_ALG_SHA_384:
|
||||
ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512)
|
||||
case PSA_ALG_SHA_512:
|
||||
ret = mbedtls_sha512_finish(&operation->ctx.sha512, hash);
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224)
|
||||
case PSA_ALG_SHA3_224:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256)
|
||||
case PSA_ALG_SHA3_256:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384)
|
||||
case PSA_ALG_SHA3_384:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
case PSA_ALG_SHA3_512:
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_224) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_256) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_384) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_SHA3_512)
|
||||
ret = mbedtls_sha3_finish(&operation->ctx.sha3, hash, hash_size);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) hash;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
*hash_length = actual_hash_length;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_hash_compute(
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
mbedtls_psa_hash_operation_t operation = MBEDTLS_PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*hash_length = hash_size;
|
||||
status = mbedtls_psa_hash_setup(&operation, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_psa_hash_update(&operation, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = mbedtls_psa_hash_finish(&operation, hash, hash_size, hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
abort_status = mbedtls_psa_hash_abort(&operation);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return abort_status;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_HASH */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
496
engine/thirdparty/mbedtls/library/psa_crypto_mac.c
vendored
Normal file
496
engine/thirdparty/mbedtls/library/psa_crypto_mac.c
vendored
Normal file
|
|
@ -0,0 +1,496 @@
|
|||
/*
|
||||
* PSA MAC layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_cipher.h"
|
||||
#include "psa_crypto_mac.h"
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include "mbedtls/constant_time.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
static psa_status_t psa_hmac_abort_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac)
|
||||
{
|
||||
mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad));
|
||||
return psa_hash_abort(&hmac->hash_ctx);
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_setup_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *key,
|
||||
size_t key_length,
|
||||
psa_algorithm_t hash_alg)
|
||||
{
|
||||
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
|
||||
size_t i;
|
||||
size_t hash_size = PSA_HASH_LENGTH(hash_alg);
|
||||
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
|
||||
psa_status_t status;
|
||||
|
||||
hmac->alg = hash_alg;
|
||||
|
||||
/* Sanity checks on block_size, to guarantee that there won't be a buffer
|
||||
* overflow below. This should never trigger if the hash algorithm
|
||||
* is implemented correctly. */
|
||||
/* The size checks against the ipad and opad buffers cannot be written
|
||||
* `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
|
||||
* because that triggers -Wlogical-op on GCC 7.3. */
|
||||
if (block_size > sizeof(ipad)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (block_size > sizeof(hmac->opad)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (block_size < hash_size) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (key_length > block_size) {
|
||||
status = psa_hash_compute(hash_alg, key, key_length,
|
||||
ipad, sizeof(ipad), &key_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* A 0-length key is not commonly used in HMAC when used as a MAC,
|
||||
* but it is permitted. It is common when HMAC is used in HKDF, for
|
||||
* example. Don't call `memcpy` in the 0-length because `key` could be
|
||||
* an invalid pointer which would make the behavior undefined. */
|
||||
else if (key_length != 0) {
|
||||
memcpy(ipad, key, key_length);
|
||||
}
|
||||
|
||||
/* ipad contains the key followed by garbage. Xor and fill with 0x36
|
||||
* to create the ipad value. */
|
||||
for (i = 0; i < key_length; i++) {
|
||||
ipad[i] ^= 0x36;
|
||||
}
|
||||
memset(ipad + key_length, 0x36, block_size - key_length);
|
||||
|
||||
/* Copy the key material from ipad to opad, flipping the requisite bits,
|
||||
* and filling the rest of opad with the requisite constant. */
|
||||
for (i = 0; i < key_length; i++) {
|
||||
hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
|
||||
}
|
||||
memset(hmac->opad + key_length, 0x5C, block_size - key_length);
|
||||
|
||||
status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, ipad, block_size);
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(ipad, sizeof(ipad));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_update_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
return psa_hash_update(&hmac->hash_ctx, data, data_length);
|
||||
}
|
||||
|
||||
static psa_status_t psa_hmac_finish_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
uint8_t *mac,
|
||||
size_t mac_size)
|
||||
{
|
||||
uint8_t tmp[PSA_HASH_MAX_SIZE];
|
||||
psa_algorithm_t hash_alg = hmac->alg;
|
||||
size_t hash_size = 0;
|
||||
size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
/* From here on, tmp needs to be wiped. */
|
||||
|
||||
status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(mac, tmp, mac_size);
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize(tmp, hash_size);
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DES)
|
||||
/* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
|
||||
* to do CMAC with pure DES, so return NOT_SUPPORTED here. */
|
||||
if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
|
||||
(psa_get_key_bits(attributes) == 64 ||
|
||||
psa_get_key_bits(attributes) == 128)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
const mbedtls_cipher_info_t *cipher_info =
|
||||
mbedtls_cipher_info_from_psa(
|
||||
PSA_ALG_CMAC,
|
||||
psa_get_key_type(attributes),
|
||||
psa_get_key_bits(attributes),
|
||||
NULL);
|
||||
|
||||
if (cipher_info == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac,
|
||||
key_buffer,
|
||||
psa_get_key_bits(attributes));
|
||||
exit:
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
|
||||
/* Initialize this driver's MAC operation structure. Once this function has been
|
||||
* called, mbedtls_psa_mac_abort can run and will do the right thing. */
|
||||
static psa_status_t mac_init(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
operation->alg = alg;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
mbedtls_cipher_init(&operation->ctx.cmac);
|
||||
status = PSA_SUCCESS;
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
/* We'll set up the hash operation later in psa_hmac_setup_internal. */
|
||||
operation->ctx.hmac.alg = 0;
|
||||
status = PSA_SUCCESS;
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
(void) operation;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
|
||||
{
|
||||
if (operation->alg == 0) {
|
||||
/* The object has (apparently) been initialized but it is not
|
||||
* in use. It's ok to call abort on such an object, and there's
|
||||
* nothing to do. */
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
mbedtls_cipher_free(&operation->ctx.cmac);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
psa_hmac_abort_internal(&operation->ctx.hmac);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* Sanity check (shouldn't happen: operation->alg should
|
||||
* always have been initialized to a valid value). */
|
||||
goto bad_state;
|
||||
}
|
||||
|
||||
operation->alg = 0;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
|
||||
bad_state:
|
||||
/* If abort is called on an uninitialized object, we can't trust
|
||||
* anything. Wipe the object in case it contains confidential data.
|
||||
* This may result in a memory leak if a pointer gets overwritten,
|
||||
* but it's too late to do anything about this. */
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* A context must be freshly initialized before it can be set up. */
|
||||
if (operation->alg != 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
status = mac_init(operation, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
|
||||
/* Key buffer size for CMAC is dictated by the key bits set on the
|
||||
* attributes, and previously validated by the core on key import. */
|
||||
(void) key_buffer_size;
|
||||
status = cmac_setup(operation, attributes, key_buffer);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(alg)) {
|
||||
status = psa_hmac_setup_internal(&operation->ctx.hmac,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
PSA_ALG_HMAC_GET_HASH(alg));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
(void) attributes;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_psa_mac_abort(operation);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_sign_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_mac_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size, alg);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_verify_setup(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
return psa_mac_setup(operation, attributes,
|
||||
key_buffer, key_buffer_size, alg);
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_update(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
return mbedtls_to_psa_error(
|
||||
mbedtls_cipher_cmac_update(&operation->ctx.cmac,
|
||||
input, input_length));
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
return psa_hmac_update_internal(&operation->ctx.hmac,
|
||||
input, input_length);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* This shouldn't happen if `operation` was initialized by
|
||||
* a setup function. */
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
static psa_status_t psa_mac_finish_internal(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
uint8_t *mac, size_t mac_size)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
|
||||
if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
|
||||
uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
|
||||
int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp);
|
||||
if (ret == 0) {
|
||||
memcpy(mac, tmp, mac_size);
|
||||
}
|
||||
mbedtls_platform_zeroize(tmp, sizeof(tmp));
|
||||
return mbedtls_to_psa_error(ret);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
|
||||
if (PSA_ALG_IS_HMAC(operation->alg)) {
|
||||
return psa_hmac_finish_internal(&operation->ctx.hmac,
|
||||
mac, mac_size);
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
|
||||
{
|
||||
/* This shouldn't happen if `operation` was initialized by
|
||||
* a setup function. */
|
||||
(void) operation;
|
||||
(void) mac;
|
||||
(void) mac_size;
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_sign_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(operation, mac, mac_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = mac_size;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_verify_finish(
|
||||
mbedtls_psa_mac_operation_t *operation,
|
||||
const uint8_t *mac,
|
||||
size_t mac_length)
|
||||
{
|
||||
uint8_t actual_mac[PSA_MAC_MAX_SIZE];
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (operation->alg == 0) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
/* Consistency check: requested MAC length fits our local buffer */
|
||||
if (mac_length > sizeof(actual_mac)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(operation, actual_mac, mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_mac_compute(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
|
||||
|
||||
status = psa_mac_setup(&operation,
|
||||
attributes, key_buffer, key_buffer_size,
|
||||
alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (input_length > 0) {
|
||||
status = mbedtls_psa_mac_update(&operation, input, input_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
status = psa_mac_finish_internal(&operation, mac, mac_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*mac_length = mac_size;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_mac_abort(&operation);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
571
engine/thirdparty/mbedtls/library/psa_crypto_pake.c
vendored
Normal file
571
engine/thirdparty/mbedtls/library/psa_crypto_pake.c
vendored
Normal file
|
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* PSA PAKE layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_pake.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
#include <mbedtls/ecjpake.h>
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* State sequence:
|
||||
*
|
||||
* psa_pake_setup()
|
||||
* |
|
||||
* |-- In any order:
|
||||
* | | psa_pake_set_password_key()
|
||||
* | | psa_pake_set_user()
|
||||
* | | psa_pake_set_peer()
|
||||
* | | psa_pake_set_role()
|
||||
* |
|
||||
* |--- In any order: (First round input before or after first round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* |--- In any order: (Second round input before or after second round output)
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | | psa_pake_output(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_KEY_SHARE)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PUBLIC)
|
||||
* | | psa_pake_input(PSA_PAKE_STEP_ZK_PROOF)
|
||||
* |
|
||||
* psa_pake_get_implicit_key()
|
||||
* psa_pake_abort()
|
||||
*/
|
||||
|
||||
/*
|
||||
* Possible sequence of calls to implementation:
|
||||
*
|
||||
* |--- In any order:
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X1_STEP_ZK_PROOF)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X1_STEP_ZK_PROOF)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X2_STEP_ZK_PROOF)
|
||||
* |
|
||||
* |--- In any order:
|
||||
* | |
|
||||
* | |------ In Order
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_KEY_SHARE)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PUBLIC)
|
||||
* | | | mbedtls_psa_pake_output(PSA_JPAKE_X2S_STEP_ZK_PROOF)
|
||||
* | |
|
||||
* | |------ In Order:
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_KEY_SHARE)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PUBLIC)
|
||||
* | | mbedtls_psa_pake_input(PSA_JPAKE_X4S_STEP_ZK_PROOF)
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t mbedtls_ecjpake_to_psa_error(int ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_ECP_INVALID_KEY:
|
||||
case MBEDTLS_ERR_ECP_VERIFY_FAILED:
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_PAKE)
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
static psa_status_t psa_pake_ecjpake_setup(mbedtls_psa_pake_operation_t *operation)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_ecjpake_init(&operation->ctx.jpake);
|
||||
|
||||
ret = mbedtls_ecjpake_setup(&operation->ctx.jpake,
|
||||
operation->role,
|
||||
MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_ECP_DP_SECP256R1,
|
||||
operation->password,
|
||||
operation->password_len);
|
||||
|
||||
mbedtls_platform_zeroize(operation->password, operation->password_len);
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The only two JPAKE user/peer identifiers supported in built-in implementation. */
|
||||
static const uint8_t jpake_server_id[] = { 's', 'e', 'r', 'v', 'e', 'r' };
|
||||
static const uint8_t jpake_client_id[] = { 'c', 'l', 'i', 'e', 'n', 't' };
|
||||
|
||||
psa_status_t mbedtls_psa_pake_setup(mbedtls_psa_pake_operation_t *operation,
|
||||
const psa_crypto_driver_pake_inputs_t *inputs)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t user_len = 0, peer_len = 0, password_len = 0;
|
||||
uint8_t *peer = NULL, *user = NULL;
|
||||
size_t actual_user_len = 0, actual_peer_len = 0, actual_password_len = 0;
|
||||
psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init();
|
||||
|
||||
status = psa_crypto_driver_pake_get_password_len(inputs, &password_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_user_len(inputs, &user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_peer_len(inputs, &peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_cipher_suite(inputs, &cipher_suite);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
operation->password = mbedtls_calloc(1, password_len);
|
||||
if (operation->password == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
user = mbedtls_calloc(1, user_len);
|
||||
if (user == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
peer = mbedtls_calloc(1, peer_len);
|
||||
if (peer == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_password(inputs, operation->password,
|
||||
password_len, &actual_password_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_user(inputs, user,
|
||||
user_len, &actual_user_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = psa_crypto_driver_pake_get_peer(inputs, peer,
|
||||
peer_len, &actual_peer_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->password_len = actual_password_len;
|
||||
operation->alg = cipher_suite.algorithm;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (cipher_suite.algorithm == PSA_ALG_JPAKE) {
|
||||
if (cipher_suite.type != PSA_PAKE_PRIMITIVE_TYPE_ECC ||
|
||||
cipher_suite.family != PSA_ECC_FAMILY_SECP_R1 ||
|
||||
cipher_suite.bits != 256 ||
|
||||
cipher_suite.hash != PSA_ALG_SHA_256) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
const size_t user_peer_len = sizeof(jpake_client_id); // client and server have the same length
|
||||
if (actual_user_len != user_peer_len ||
|
||||
actual_peer_len != user_peer_len) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (memcmp(user, jpake_client_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_server_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_CLIENT;
|
||||
} else
|
||||
if (memcmp(user, jpake_server_id, actual_user_len) == 0 &&
|
||||
memcmp(peer, jpake_client_id, actual_peer_len) == 0) {
|
||||
operation->role = MBEDTLS_ECJPAKE_SERVER;
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
|
||||
status = psa_pake_ecjpake_setup(operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Role has been set, release user/peer buffers. */
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) operation;
|
||||
(void) inputs;
|
||||
#endif
|
||||
{ status = PSA_ERROR_NOT_SUPPORTED; }
|
||||
|
||||
error:
|
||||
mbedtls_free(user); mbedtls_free(peer);
|
||||
/* In case of failure of the setup of a multipart operation, the PSA driver interface
|
||||
* specifies that the core does not call any other driver entry point thus does not
|
||||
* call mbedtls_psa_pake_abort(). Therefore call it here to do the needed clean
|
||||
* up like freeing the memory that may have been allocated to store the password.
|
||||
*/
|
||||
mbedtls_psa_pake_abort(operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t mbedtls_psa_pake_output_internal(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t length;
|
||||
(void) step; // Unused parameter
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
|
||||
* handling of output sequencing.
|
||||
*
|
||||
* The Mbed TLS JPAKE API outputs the whole X1+X2 and X2S steps data
|
||||
* at once, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X2S to be
|
||||
* retrieved in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, the whole X1+X2 or X2S steps
|
||||
* data is stored in an intermediate buffer at first step output call,
|
||||
* and data is sliced down by parsing the ECPoint records in order
|
||||
* to return the right parts on each step.
|
||||
*/
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
/* Initialize & write round on KEY_SHARE sequences */
|
||||
if (step == PSA_JPAKE_X1_STEP_KEY_SHARE) {
|
||||
ret = mbedtls_ecjpake_write_round_one(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
sizeof(operation->buffer),
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
} else if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE) {
|
||||
ret = mbedtls_ecjpake_write_round_two(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
sizeof(operation->buffer),
|
||||
&operation->buffer_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mbedtls_ecjpake_write_round_xxx() outputs thing in the format
|
||||
* defined by draft-cragie-tls-ecjpake-01 section 7. The summary is
|
||||
* that the data for each step is prepended with a length byte, and
|
||||
* then they're concatenated. Additionally, the server's second round
|
||||
* output is prepended with a 3-bytes ECParameters structure.
|
||||
*
|
||||
* In PSA, we output each step separately, and don't prepend the
|
||||
* output with a length byte, even less a curve identifier, as that
|
||||
* information is already available.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X2S_STEP_KEY_SHARE &&
|
||||
operation->role == MBEDTLS_ECJPAKE_SERVER) {
|
||||
/* Skip ECParameters, with is 3 bytes (RFC 8422) */
|
||||
operation->buffer_offset += 3;
|
||||
}
|
||||
|
||||
/* Read the length byte then move past it to the data */
|
||||
length = operation->buffer[operation->buffer_offset];
|
||||
operation->buffer_offset += 1;
|
||||
|
||||
if (operation->buffer_offset + length > operation->buffer_length) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
if (output_size < length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(output,
|
||||
operation->buffer + operation->buffer_offset,
|
||||
length);
|
||||
*output_length = length;
|
||||
|
||||
operation->buffer_offset += length;
|
||||
|
||||
/* Reset buffer after ZK_PROOF sequence */
|
||||
if ((step == PSA_JPAKE_X2_STEP_ZK_PROOF) ||
|
||||
(step == PSA_JPAKE_X2S_STEP_ZK_PROOF)) {
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) step;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_output(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = mbedtls_psa_pake_output_internal(
|
||||
operation, step, output, output_size, output_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static psa_status_t mbedtls_psa_pake_input_internal(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
(void) step; // Unused parameter
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
/*
|
||||
* The PSA CRYPTO PAKE and Mbed TLS JPAKE API have a different
|
||||
* handling of input sequencing.
|
||||
*
|
||||
* The Mbed TLS JPAKE API takes the whole X1+X2 or X4S steps data
|
||||
* at once as input, on the other side the PSA CRYPTO PAKE api requires
|
||||
* the KEY_SHARE/ZP_PUBLIC/ZK_PROOF parts of X1, X2 & X4S to be
|
||||
* given in sequence.
|
||||
*
|
||||
* In order to achieve API compatibility, each X1+X2 or X4S step data
|
||||
* is stored sequentially in an intermediate buffer and given to the
|
||||
* Mbed TLS JPAKE API on the last step.
|
||||
*
|
||||
* This causes any input error to be only detected on the last step.
|
||||
*/
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
/*
|
||||
* Copy input to local buffer and format it as the Mbed TLS API
|
||||
* expects, i.e. as defined by draft-cragie-tls-ecjpake-01 section 7.
|
||||
* The summary is that the data for each step is prepended with a
|
||||
* length byte, and then they're concatenated. Additionally, the
|
||||
* server's second round output is prepended with a 3-bytes
|
||||
* ECParameters structure - which means we have to prepend that when
|
||||
* we're a client.
|
||||
*/
|
||||
if (step == PSA_JPAKE_X4S_STEP_KEY_SHARE &&
|
||||
operation->role == MBEDTLS_ECJPAKE_CLIENT) {
|
||||
/* We only support secp256r1. */
|
||||
/* This is the ECParameters structure defined by RFC 8422. */
|
||||
unsigned char ecparameters[3] = {
|
||||
3, /* named_curve */
|
||||
0, 23 /* secp256r1 */
|
||||
};
|
||||
|
||||
if (operation->buffer_length + sizeof(ecparameters) >
|
||||
sizeof(operation->buffer)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
memcpy(operation->buffer + operation->buffer_length,
|
||||
ecparameters, sizeof(ecparameters));
|
||||
operation->buffer_length += sizeof(ecparameters);
|
||||
}
|
||||
|
||||
/*
|
||||
* The core checks that input_length is smaller than
|
||||
* PSA_PAKE_INPUT_MAX_SIZE.
|
||||
* Thus no risk of integer overflow here.
|
||||
*/
|
||||
if (operation->buffer_length + input_length + 1 > sizeof(operation->buffer)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Write the length byte */
|
||||
operation->buffer[operation->buffer_length] = (uint8_t) input_length;
|
||||
operation->buffer_length += 1;
|
||||
|
||||
/* Finally copy the data */
|
||||
memcpy(operation->buffer + operation->buffer_length,
|
||||
input, input_length);
|
||||
operation->buffer_length += input_length;
|
||||
|
||||
/* Load buffer at each last round ZK_PROOF */
|
||||
if (step == PSA_JPAKE_X2_STEP_ZK_PROOF) {
|
||||
ret = mbedtls_ecjpake_read_round_one(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length);
|
||||
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
} else if (step == PSA_JPAKE_X4S_STEP_ZK_PROOF) {
|
||||
ret = mbedtls_ecjpake_read_round_two(&operation->ctx.jpake,
|
||||
operation->buffer,
|
||||
operation->buffer_length);
|
||||
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) step;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_input(mbedtls_psa_pake_operation_t *operation,
|
||||
psa_crypto_driver_pake_step_t step,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
psa_status_t status = mbedtls_psa_pake_input_internal(
|
||||
operation, step, input, input_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_get_implicit_key(
|
||||
mbedtls_psa_pake_operation_t *operation,
|
||||
uint8_t *output, size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
ret = mbedtls_ecjpake_write_shared_key(&operation->ctx.jpake,
|
||||
output,
|
||||
output_size,
|
||||
output_length,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
return mbedtls_ecjpake_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
} else
|
||||
#else
|
||||
(void) output;
|
||||
#endif
|
||||
{ return PSA_ERROR_NOT_SUPPORTED; }
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_pake_abort(mbedtls_psa_pake_operation_t *operation)
|
||||
{
|
||||
mbedtls_zeroize_and_free(operation->password, operation->password_len);
|
||||
operation->password = NULL;
|
||||
operation->password_len = 0;
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_JPAKE)
|
||||
if (operation->alg == PSA_ALG_JPAKE) {
|
||||
operation->role = MBEDTLS_ECJPAKE_NONE;
|
||||
mbedtls_platform_zeroize(operation->buffer, sizeof(operation->buffer));
|
||||
operation->buffer_length = 0;
|
||||
operation->buffer_offset = 0;
|
||||
mbedtls_ecjpake_free(&operation->ctx.jpake);
|
||||
}
|
||||
#endif
|
||||
|
||||
operation->alg = PSA_ALG_NONE;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_PAKE */
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
|
@ -21,13 +21,10 @@ typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
|
|||
#include "mbedtls/entropy.h"
|
||||
|
||||
/* Choose a DRBG based on configuration and availability */
|
||||
#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
|
||||
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
|
||||
#elif defined(MBEDTLS_CTR_DRBG_C)
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE
|
||||
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
|
||||
|
|
@ -49,17 +46,11 @@ typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
|
|||
#error "No hash algorithm available for HMAC_DBRG."
|
||||
#endif
|
||||
|
||||
#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
#else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#error "No DRBG module available for the psa_crypto module."
|
||||
|
||||
#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
|
|
|
|||
705
engine/thirdparty/mbedtls/library/psa_crypto_rsa.c
vendored
Normal file
705
engine/thirdparty/mbedtls/library/psa_crypto_rsa.c
vendored
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* PSA RSA layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "psa/crypto_values.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_random_impl.h"
|
||||
#include "psa_crypto_rsa.h"
|
||||
#include "psa_crypto_hash.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include "rsa_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
|
||||
* that are not a multiple of 8) well. For example, there is only
|
||||
* mbedtls_rsa_get_len(), which returns a number of bytes, and no
|
||||
* way to return the exact bit size of a key.
|
||||
* To keep things simple, reject non-byte-aligned key sizes. */
|
||||
static psa_status_t psa_check_rsa_key_byte_aligned(
|
||||
const mbedtls_rsa_context *rsa)
|
||||
{
|
||||
mbedtls_mpi n;
|
||||
psa_status_t status;
|
||||
mbedtls_mpi_init(&n);
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_export(rsa, &n, NULL, NULL, NULL, NULL));
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (mbedtls_mpi_bitlen(&n) % 8 != 0) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
mbedtls_mpi_free(&n);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_load_representation(
|
||||
psa_key_type_t type, const uint8_t *data, size_t data_length,
|
||||
mbedtls_rsa_context **p_rsa)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t bits;
|
||||
|
||||
*p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
|
||||
if (*p_rsa == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
mbedtls_rsa_init(*p_rsa);
|
||||
|
||||
/* Parse the data. */
|
||||
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
|
||||
} else {
|
||||
status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
|
||||
* supports non-byte-aligned key sizes, but not well. For example,
|
||||
* mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
|
||||
bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
|
||||
if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
status = psa_check_rsa_key_byte_aligned(*p_rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) && \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_rsa_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size,
|
||||
size_t *key_buffer_length, size_t *bits)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
/* Parse input */
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
data,
|
||||
data_length,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*bits = (psa_key_bits_t) PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(rsa));
|
||||
|
||||
/* Re-export the data to PSA export format, such that we can store export
|
||||
* representation in the key slot. Export representation in case of RSA is
|
||||
* the smallest representation that's allowed as input, so a straight-up
|
||||
* allocation of the same size as the input buffer will be large enough. */
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
rsa,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
key_buffer_length);
|
||||
exit:
|
||||
/* Always free the RSA object */
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT) &&
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT)) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type,
|
||||
mbedtls_rsa_context *rsa,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *end = data + data_size;
|
||||
|
||||
/* PSA Crypto API defines the format of an RSA key as a DER-encoded
|
||||
* representation of the non-encrypted PKCS#1 RSAPrivateKey for a
|
||||
* private key and of the RFC3279 RSAPublicKey for a public key. */
|
||||
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
|
||||
ret = mbedtls_rsa_write_key(rsa, data, &end);
|
||||
} else {
|
||||
ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
/* Clean up in case pk_write failed halfway through. */
|
||||
memset(data, 0, data_size);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
/* The mbedtls_pk_xxx functions write to the end of the buffer.
|
||||
* Move the data to the beginning and erase remaining data
|
||||
* at the original location. */
|
||||
if (2 * (size_t) ret <= data_size) {
|
||||
memcpy(data, data + data_size - ret, ret);
|
||||
memset(data + data_size - ret, 0, ret);
|
||||
} else if ((size_t) ret < data_size) {
|
||||
memmove(data, data + data_size - ret, ret);
|
||||
memset(data + ret, 0, data_size - ret);
|
||||
}
|
||||
|
||||
*data_length = ret;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(
|
||||
attributes->type, key_buffer, key_buffer_size, &rsa);
|
||||
if (status == PSA_SUCCESS) {
|
||||
status = mbedtls_psa_rsa_export_key(PSA_KEY_TYPE_RSA_PUBLIC_KEY,
|
||||
rsa,
|
||||
data,
|
||||
data_size,
|
||||
data_length);
|
||||
}
|
||||
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
static psa_status_t psa_rsa_read_exponent(const uint8_t *e_bytes,
|
||||
size_t e_length,
|
||||
int *exponent)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t acc = 0;
|
||||
|
||||
/* Mbed TLS encodes the public exponent as an int. For simplicity, only
|
||||
* support values that fit in a 32-bit integer, which is larger than
|
||||
* int on just about every platform anyway. */
|
||||
if (e_length > sizeof(acc)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
for (i = 0; i < e_length; i++) {
|
||||
acc = (acc << 8) | e_bytes[i];
|
||||
}
|
||||
if (acc > INT_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*exponent = acc;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *custom_data, size_t custom_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
mbedtls_rsa_context rsa;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int exponent = 65537;
|
||||
|
||||
if (custom_data_length != 0) {
|
||||
status = psa_rsa_read_exponent(custom_data, custom_data_length,
|
||||
&exponent);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_rsa_init(&rsa);
|
||||
ret = mbedtls_rsa_gen_key(&rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
(unsigned int) attributes->bits,
|
||||
exponent);
|
||||
if (ret != 0) {
|
||||
mbedtls_rsa_free(&rsa);
|
||||
return mbedtls_to_psa_error(ret);
|
||||
}
|
||||
|
||||
status = mbedtls_psa_rsa_export_key(attributes->type,
|
||||
&rsa, key_buffer, key_buffer_size,
|
||||
key_buffer_length);
|
||||
mbedtls_rsa_free(&rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) */
|
||||
|
||||
/****************************************************************/
|
||||
/* Sign/verify hashes */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
|
||||
/* Decode the hash algorithm from alg and store the mbedtls encoding in
|
||||
* md_alg. Verify that the hash length is acceptable. */
|
||||
static psa_status_t psa_rsa_decode_md_type(psa_algorithm_t alg,
|
||||
size_t hash_length,
|
||||
mbedtls_md_type_t *md_alg)
|
||||
{
|
||||
psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
|
||||
*md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
|
||||
/* The Mbed TLS RSA module uses an unsigned int for hash length
|
||||
* parameters. Validate that it fits so that we don't risk an
|
||||
* overflow later. */
|
||||
#if SIZE_MAX > UINT_MAX
|
||||
if (hash_length > UINT_MAX) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For signatures using a hash, the hash length must be correct. */
|
||||
if (alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
|
||||
if (*md_alg == MBEDTLS_MD_NONE) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (mbedtls_md_get_size_from_type(*md_alg) != hash_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_sign_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
uint8_t *signature, size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (signature_size < mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
|
||||
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
|
||||
MBEDTLS_MD_NONE);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_pkcs1_sign(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
md_alg,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
if (PSA_ALG_IS_RSA_PSS(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_rsassa_pss_sign(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
MBEDTLS_MD_NONE,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*signature_length = mbedtls_rsa_get_len(rsa);
|
||||
}
|
||||
status = mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
static int rsa_pss_expected_salt_len(psa_algorithm_t alg,
|
||||
const mbedtls_rsa_context *rsa,
|
||||
size_t hash_length)
|
||||
{
|
||||
if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
|
||||
return MBEDTLS_RSA_SALT_LEN_ANY;
|
||||
}
|
||||
/* Otherwise: standard salt length, i.e. largest possible salt length
|
||||
* up to the hash length. */
|
||||
int klen = (int) mbedtls_rsa_get_len(rsa); // known to fit
|
||||
int hlen = (int) hash_length; // known to fit
|
||||
int room = klen - 2 - hlen;
|
||||
if (room < 0) {
|
||||
return 0; // there is no valid signature in this case anyway
|
||||
} else if (room > hlen) {
|
||||
return hlen;
|
||||
} else {
|
||||
return room;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
|
||||
psa_status_t mbedtls_psa_rsa_verify_hash(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
|
||||
const uint8_t *signature, size_t signature_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_md_type_t md_alg;
|
||||
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_rsa_decode_md_type(alg, hash_length, &md_alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (signature_length != mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_INVALID_SIGNATURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
|
||||
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15,
|
||||
MBEDTLS_MD_NONE);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_rsa_pkcs1_verify(rsa,
|
||||
md_alg,
|
||||
(unsigned int) hash_length,
|
||||
hash,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
|
||||
if (PSA_ALG_IS_RSA_PSS(alg)) {
|
||||
ret = mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
if (ret == 0) {
|
||||
int slen = rsa_pss_expected_salt_len(alg, rsa, hash_length);
|
||||
ret = mbedtls_rsa_rsassa_pss_verify_ext(rsa,
|
||||
md_alg,
|
||||
(unsigned) hash_length,
|
||||
hash,
|
||||
md_alg,
|
||||
slen,
|
||||
signature);
|
||||
}
|
||||
} else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */
|
||||
{
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Mbed TLS distinguishes "invalid padding" from "valid padding but
|
||||
* the rest of the signature is invalid". This has little use in
|
||||
* practice and PSA doesn't report this distinction. */
|
||||
status = (ret == MBEDTLS_ERR_RSA_INVALID_PADDING) ?
|
||||
PSA_ERROR_INVALID_SIGNATURE :
|
||||
mbedtls_to_psa_error(ret);
|
||||
|
||||
exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */
|
||||
|
||||
/****************************************************************/
|
||||
/* Asymmetric cryptography */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
static int psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg,
|
||||
mbedtls_rsa_context *rsa)
|
||||
{
|
||||
psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH(alg);
|
||||
mbedtls_md_type_t md_alg = mbedtls_md_type_from_psa_alg(hash_alg);
|
||||
|
||||
/* Just to get the error status right, as rsa_set_padding() doesn't
|
||||
* distinguish between "bad RSA algorithm" and "unknown hash". */
|
||||
if (mbedtls_md_info_from_type(md_alg) == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, md_alg);
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
|
||||
psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
(void) salt;
|
||||
(void) salt_length;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
if (output_size < mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto rsa_exit;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_pkcs1_encrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
|
||||
} else
|
||||
if (PSA_ALG_IS_RSA_OAEP(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
status = mbedtls_to_psa_error(
|
||||
psa_rsa_oaep_set_padding_mode(alg, rsa));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_rsaes_oaep_encrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
salt, salt_length,
|
||||
input_length,
|
||||
input,
|
||||
output));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
|
||||
} else {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
rsa_exit:
|
||||
if (status == PSA_SUCCESS) {
|
||||
*output_length = mbedtls_rsa_get_len(rsa);
|
||||
}
|
||||
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
(void) key_buffer;
|
||||
(void) key_buffer_size;
|
||||
(void) input;
|
||||
(void) input_length;
|
||||
(void) salt;
|
||||
(void) salt_length;
|
||||
(void) output;
|
||||
(void) output_size;
|
||||
(void) output_length;
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
status = mbedtls_psa_rsa_load_representation(attributes->type,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
&rsa);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
if (input_length != mbedtls_rsa_get_len(rsa)) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto rsa_exit;
|
||||
}
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
|
||||
if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT)
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_pkcs1_decrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
output_length,
|
||||
input,
|
||||
output,
|
||||
output_size));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */
|
||||
} else
|
||||
if (PSA_ALG_IS_RSA_OAEP(alg)) {
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
status = mbedtls_to_psa_error(
|
||||
psa_rsa_oaep_set_padding_mode(alg, rsa));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto rsa_exit;
|
||||
}
|
||||
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_rsa_rsaes_oaep_decrypt(rsa,
|
||||
mbedtls_psa_get_random,
|
||||
MBEDTLS_PSA_RANDOM_STATE,
|
||||
salt, salt_length,
|
||||
output_length,
|
||||
input,
|
||||
output,
|
||||
output_size));
|
||||
#else
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */
|
||||
} else {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
|
||||
rsa_exit:
|
||||
mbedtls_rsa_free(rsa);
|
||||
mbedtls_free(rsa);
|
||||
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
|
||||
* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */
|
||||
} else {
|
||||
status = PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
|
@ -105,17 +105,11 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
|||
/**
|
||||
* \brief Generate an RSA key.
|
||||
*
|
||||
* \note The signature of the function is that of a PSA driver generate_key
|
||||
* entry point.
|
||||
*
|
||||
* \param[in] attributes The attributes for the RSA key to generate.
|
||||
* \param[in] params Production parameters for the key
|
||||
* generation. This function only uses
|
||||
* `params->data`,
|
||||
* which contains the public exponent.
|
||||
* \param[in] custom_data The public exponent to use.
|
||||
* This can be a null pointer if
|
||||
* \c params_data_length is 0.
|
||||
* \param params_data_length Length of `params->data` in bytes.
|
||||
* \param custom_data_length Length of \p custom_data in bytes.
|
||||
* This can be 0, in which case the
|
||||
* public exponent will be 65537.
|
||||
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||
|
|
@ -130,12 +124,10 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
|||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
const uint8_t *custom_data, size_t custom_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
#endif
|
||||
|
||||
/** Sign an already-calculated hash with an RSA private key.
|
||||
*
|
||||
|
|
|
|||
373
engine/thirdparty/mbedtls/library/psa_crypto_se.c
vendored
Normal file
373
engine/thirdparty/mbedtls/library/psa_crypto_se.c
vendored
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* 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;
|
||||
|
||||
struct psa_se_drv_table_entry_s {
|
||||
psa_key_location_t location;
|
||||
const psa_drv_se_t *methods;
|
||||
union {
|
||||
psa_drv_se_internal_context_t internal;
|
||||
psa_drv_se_context_t context;
|
||||
} u;
|
||||
};
|
||||
|
||||
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;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
|
||||
/* In the driver table, location=0 means an entry that isn't used.
|
||||
* No driver has a location of 0 because it's a reserved value
|
||||
* (which designates transparent keys). Make sure we never return
|
||||
* a driver entry for location 0. */
|
||||
if (location == 0) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == location) {
|
||||
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->u.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->u.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->location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* ITS file sizes are limited to 32 bits. */
|
||||
if (driver->u.internal.persistent_data_size > UINT32_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
|
||||
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
|
||||
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->u.internal.persistent_data_size,
|
||||
driver->u.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->u.internal.persistent_data_size,
|
||||
driver->u.internal.persistent_data,
|
||||
0);
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location)
|
||||
{
|
||||
psa_storage_uid_t uid;
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
|
||||
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;
|
||||
psa_key_location_t key_location =
|
||||
PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
|
||||
|
||||
/* If the location is wrong, it's a bug in the library. */
|
||||
if (driver->location != key_location) {
|
||||
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->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
attributes, method,
|
||||
*slot_number);
|
||||
} else if (method == PSA_KEY_CREATION_REGISTER) {
|
||||
/* The application didn't specify a slot number. This doesn't
|
||||
* make sense when registering a slot. */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
} 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->u.context,
|
||||
driver->u.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->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
slot_number);
|
||||
storage_status = psa_save_se_persistent_data(driver);
|
||||
return status == PSA_SUCCESS ? storage_status : status;
|
||||
}
|
||||
|
||||
psa_status_t psa_init_all_se_drivers(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
psa_se_drv_table_entry_t *driver = &driver_table[i];
|
||||
if (driver->location == 0) {
|
||||
continue; /* skipping unused entry */
|
||||
}
|
||||
const psa_drv_se_t *methods = psa_get_se_driver_methods(driver);
|
||||
if (methods->p_init != NULL) {
|
||||
psa_status_t status = methods->p_init(
|
||||
&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
driver->location);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
status = psa_save_se_persistent_data(driver);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver registration */
|
||||
/****************************************************************/
|
||||
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_location_t location,
|
||||
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
|
||||
* location because it means a transparent key. */
|
||||
MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
|
||||
"Secure element support requires 0 to mean a local key");
|
||||
|
||||
if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == 0) {
|
||||
break;
|
||||
}
|
||||
/* Check that location 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].location == location) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
}
|
||||
if (i == PSA_MAX_SE_DRIVERS) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
driver_table[i].location = location;
|
||||
driver_table[i].methods = methods;
|
||||
driver_table[i].u.internal.persistent_data_size =
|
||||
methods->persistent_data_size;
|
||||
|
||||
if (methods->persistent_data_size != 0) {
|
||||
driver_table[i].u.internal.persistent_data =
|
||||
mbedtls_calloc(1, methods->persistent_data_size);
|
||||
if (driver_table[i].u.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;
|
||||
}
|
||||
}
|
||||
|
||||
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].u.internal.persistent_data != NULL) {
|
||||
mbedtls_free(driver_table[i].u.internal.persistent_data);
|
||||
}
|
||||
}
|
||||
memset(driver_table, 0, sizeof(driver_table));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
1131
engine/thirdparty/mbedtls/library/psa_crypto_slot_management.c
vendored
Normal file
1131
engine/thirdparty/mbedtls/library/psa_crypto_slot_management.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -15,20 +15,26 @@
|
|||
|
||||
/** Range of volatile key identifiers.
|
||||
*
|
||||
* The last #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
|
||||
* The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
|
||||
* range of key identifiers are reserved for volatile key identifiers.
|
||||
* A volatile key identifier is equal to #PSA_KEY_ID_VOLATILE_MIN plus the
|
||||
* index of the key slot containing the volatile key definition.
|
||||
*
|
||||
* If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id
|
||||
* indicates the key slot containing the volatile key definition. See
|
||||
* psa_crypto_slot_management.c for details.
|
||||
*/
|
||||
|
||||
/** The minimum value for a volatile key identifier.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MIN (PSA_KEY_ID_VENDOR_MAX - \
|
||||
MBEDTLS_PSA_KEY_SLOT_COUNT + 1)
|
||||
#define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN
|
||||
|
||||
/** The maximum value for a volatile key identifier.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MAX PSA_KEY_ID_VENDOR_MAX
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1)
|
||||
#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
#define PSA_KEY_ID_VOLATILE_MAX \
|
||||
(PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1)
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Test whether a key identifier is a volatile key identifier.
|
||||
*
|
||||
|
|
@ -58,6 +64,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
|
|||
* It is the responsibility of the caller to call psa_unregister_read(slot)
|
||||
* when they have finished reading the contents of the slot.
|
||||
*
|
||||
* On failure, `*p_slot` is set to NULL. This ensures that it is always valid
|
||||
* to call psa_unregister_read on the returned slot.
|
||||
*
|
||||
* \param key Key identifier to query.
|
||||
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
|
||||
* key slot containing the description of the key
|
||||
|
|
@ -91,6 +100,24 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
|||
*/
|
||||
psa_status_t psa_initialize_key_slots(void);
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/* Allow test code to customize the key slice length. We use this in tests
|
||||
* that exhaust the key store to reach a full key store in reasonable time
|
||||
* and memory.
|
||||
*
|
||||
* The length of each slice must be between 1 and
|
||||
* (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive.
|
||||
*
|
||||
* The length for a given slice index must not change while
|
||||
* the key store is initialized.
|
||||
*/
|
||||
extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(
|
||||
size_t slice_idx);
|
||||
|
||||
/* The number of volatile key slices. */
|
||||
size_t psa_key_slot_volatile_slice_count(void);
|
||||
#endif
|
||||
|
||||
/** Delete all data from key slots in memory.
|
||||
* This function is not thread safe, it wipes every key slot regardless of
|
||||
* state and reader count. It should only be called when no slot is in use.
|
||||
|
|
@ -110,13 +137,22 @@ void psa_wipe_all_key_slots(void);
|
|||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[out] volatile_key_id On success, volatile key identifier
|
||||
* associated to the returned slot.
|
||||
* \param[out] volatile_key_id - If null, reserve a cache slot for
|
||||
* a persistent or built-in key.
|
||||
* - If non-null, allocate a slot for
|
||||
* a volatile key. On success,
|
||||
* \p *volatile_key_id is the
|
||||
* identifier corresponding to the
|
||||
* returned slot. It is the caller's
|
||||
* responsibility to set this key identifier
|
||||
* in the attributes.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* There were no free key slots.
|
||||
* When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not
|
||||
* enough memory to allocate more slots.
|
||||
* \retval #PSA_ERROR_BAD_STATE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
|
|
@ -125,6 +161,29 @@ void psa_wipe_all_key_slots(void);
|
|||
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/** Return a key slot to the free list.
|
||||
*
|
||||
* Call this function when a slot obtained from psa_reserve_free_key_slot()
|
||||
* is no longer in use.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param slice_idx The slice containing the slot.
|
||||
* This is `slot->slice_index` when the slot
|
||||
* is obtained from psa_reserve_free_key_slot().
|
||||
* \param slot The key slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
* unexpected state.
|
||||
*/
|
||||
psa_status_t psa_free_key_slot(size_t slice_idx,
|
||||
psa_key_slot_t *slot);
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Change the state of a key slot.
|
||||
*
|
||||
* This function changes the state of the key slot from expected_state to
|
||||
|
|
@ -171,10 +230,10 @@ static inline psa_status_t psa_key_slot_state_transition(
|
|||
static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
|
||||
{
|
||||
if ((slot->state != PSA_SLOT_FULL) ||
|
||||
(slot->registered_readers >= SIZE_MAX)) {
|
||||
(slot->var.occupied.registered_readers >= SIZE_MAX)) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
slot->registered_readers++;
|
||||
slot->var.occupied.registered_readers++;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
481
engine/thirdparty/mbedtls/library/psa_crypto_storage.c
vendored
Normal file
481
engine/thirdparty/mbedtls/library/psa_crypto_storage.c
vendored
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* PSA persistent key storage
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
#include "mbedtls/platform_util.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"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key storage */
|
||||
/****************************************************************/
|
||||
|
||||
/* Determine a file name (ITS file identifier) for the given key 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 is the random seed
|
||||
* file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
|
||||
* 0xFFFFFF52. */
|
||||
static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
|
||||
/* Encode the owner in the upper 32 bits. This means that if
|
||||
* owner values are nonzero (as they are on a PSA platform),
|
||||
* no key file will ever have a value less than 0x100000000, so
|
||||
* the whole range 0..0xffffffff is available for non-key files. */
|
||||
uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
|
||||
return ((uint64_t) unsigned_owner_id << 32) |
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
|
||||
#else
|
||||
/* Use the key id directly as a file name.
|
||||
* psa_is_key_id_valid() in psa_crypto_slot_management.c
|
||||
* is responsible for ensuring that key identifiers do not have a
|
||||
* value that is reserved for non-key files. */
|
||||
return key;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Load persistent data for the given key slot number.
|
||||
*
|
||||
* This function reads data from a storage backend and returns the data in a
|
||||
* buffer.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be loaded. This
|
||||
* should be an occupied storage location.
|
||||
* \param[out] data Buffer where the data is to be written.
|
||||
* \param data_size Size of the \c data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_load(
|
||||
const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
size_t data_length = 0;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
|
||||
if (data_size != data_length) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store persistent data for the given key slot number.
|
||||
*
|
||||
* This function stores the given data buffer to a persistent storage.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be stored. This
|
||||
* should be an unoccupied storage location.
|
||||
* \param[in] data Buffer containing the data to be stored.
|
||||
* \param data_length The number of bytes
|
||||
* that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
if (psa_is_key_present_in_storage(key) == 1) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (data_identifier_info.size != data_length) {
|
||||
status = PSA_ERROR_DATA_INVALID;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
/* Remove the file in case we managed to create it but something
|
||||
* went wrong. It's ok if the file doesn't exist. If the file exists
|
||||
* but the removal fails, we're already reporting an error so there's
|
||||
* nothing else we can do. */
|
||||
(void) psa_its_remove(data_identifier);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
if (psa_its_remove(data_identifier) != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get data length for given key slot number.
|
||||
*
|
||||
* \param key Persistent identifier whose stored data length
|
||||
* is to be obtained.
|
||||
* \param[out] data_length The number of bytes that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_get_data_length(
|
||||
const mbedtls_svc_key_id_t key,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*data_length = (size_t) data_identifier_info.size;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistent key storage magic header.
|
||||
*/
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
|
||||
|
||||
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[2];
|
||||
uint8_t bits[2];
|
||||
uint8_t policy[sizeof(psa_key_policy_t)];
|
||||
uint8_t data_len[4];
|
||||
uint8_t key_data[];
|
||||
} psa_persistent_key_storage_format;
|
||||
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_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);
|
||||
MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0);
|
||||
memcpy(storage_format->key_data, data, data_length);
|
||||
}
|
||||
|
||||
static psa_status_t check_magic_header(const uint8_t *data)
|
||||
{
|
||||
if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
|
||||
PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
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_attributes_t *attr)
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
(const psa_persistent_key_storage_format *) storage_data;
|
||||
uint32_t version;
|
||||
|
||||
if (storage_data_length < sizeof(*storage_format)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = check_magic_header(storage_data);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0);
|
||||
if (version != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
*key_data_length = MBEDTLS_GET_UINT32_LE(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_DATA_INVALID;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0);
|
||||
attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0);
|
||||
attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0);
|
||||
attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0);
|
||||
attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t));
|
||||
attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t));
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length)
|
||||
{
|
||||
size_t storage_data_length;
|
||||
uint8_t *storage_data;
|
||||
psa_status_t status;
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (data == NULL || data_length == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
|
||||
|
||||
storage_data = mbedtls_calloc(1, storage_data_length);
|
||||
if (storage_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
psa_format_key_data_for_storage(data, data_length, attr, storage_data);
|
||||
|
||||
status = psa_crypto_storage_store(attr->id,
|
||||
storage_data, storage_data_length);
|
||||
|
||||
mbedtls_zeroize_and_free(storage_data, storage_data_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
|
||||
{
|
||||
mbedtls_zeroize_and_free(key_data, key_data_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_load_persistent_key(psa_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;
|
||||
mbedtls_svc_key_id_t key = attr->id;
|
||||
|
||||
status = psa_crypto_storage_get_data_length(key, &storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
loaded_data = mbedtls_calloc(1, storage_data_length);
|
||||
|
||||
if (loaded_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
|
||||
data, data_length, attr);
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (status == PSA_SUCCESS &&
|
||||
(*data == NULL || *data_length == 0)) {
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_zeroize_and_free(loaded_data, storage_data_length);
|
||||
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_TRANSACTION_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_DATA_INVALID;
|
||||
}
|
||||
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)
|
||||
{
|
||||
psa_status_t status;
|
||||
struct psa_storage_info_t p_info;
|
||||
|
||||
status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
|
||||
|
||||
if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
|
||||
status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
|
||||
} else if (PSA_SUCCESS == status) {
|
||||
/* You should not be here. Seed needs to be injected only once */
|
||||
status = PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
254
engine/thirdparty/mbedtls/library/psa_its_file.c
vendored
Normal file
254
engine/thirdparty/mbedtls/library/psa_its_file.c
vendored
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* PSA ITS simulator over stdio files.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "psa_crypto_its.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(PSA_ITS_STORAGE_PREFIX)
|
||||
#define PSA_ITS_STORAGE_PREFIX ""
|
||||
#endif
|
||||
|
||||
#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08x%08x"
|
||||
#define PSA_ITS_STORAGE_SUFFIX ".psa_its"
|
||||
#define PSA_ITS_STORAGE_FILENAME_LENGTH \
|
||||
(sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \
|
||||
16 + /*UID (64-bit number in hex)*/ \
|
||||
sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \
|
||||
1 /*terminating null byte*/)
|
||||
#define PSA_ITS_STORAGE_TEMP \
|
||||
PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX
|
||||
|
||||
/* The maximum value of psa_storage_info_t.size */
|
||||
#define PSA_ITS_MAX_SIZE 0xffffffff
|
||||
|
||||
#define PSA_ITS_MAGIC_STRING "PSA\0ITS\0"
|
||||
#define PSA_ITS_MAGIC_LENGTH 8
|
||||
|
||||
/* As rename fails on Windows if the new filepath already exists,
|
||||
* use MoveFileExA with the MOVEFILE_REPLACE_EXISTING flag instead.
|
||||
* Returns 0 on success, nonzero on failure. */
|
||||
#if defined(_WIN32)
|
||||
#define rename_replace_existing(oldpath, newpath) \
|
||||
(!MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
||||
#else
|
||||
#define rename_replace_existing(oldpath, newpath) rename(oldpath, newpath)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[PSA_ITS_MAGIC_LENGTH];
|
||||
uint8_t size[sizeof(uint32_t)];
|
||||
uint8_t flags[sizeof(psa_storage_create_flags_t)];
|
||||
} psa_its_file_header_t;
|
||||
|
||||
static void psa_its_fill_filename(psa_storage_uid_t uid, char *filename)
|
||||
{
|
||||
/* Break up the UID into two 32-bit pieces so as not to rely on
|
||||
* long long support in snprintf. */
|
||||
mbedtls_snprintf(filename, PSA_ITS_STORAGE_FILENAME_LENGTH,
|
||||
"%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s",
|
||||
PSA_ITS_STORAGE_PREFIX,
|
||||
(unsigned) (uid >> 32),
|
||||
(unsigned) (uid & 0xffffffff),
|
||||
PSA_ITS_STORAGE_SUFFIX);
|
||||
}
|
||||
|
||||
static psa_status_t psa_its_read_file(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info,
|
||||
FILE **p_stream)
|
||||
{
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
psa_its_file_header_t header;
|
||||
size_t n;
|
||||
|
||||
*p_stream = NULL;
|
||||
psa_its_fill_filename(uid, filename);
|
||||
*p_stream = fopen(filename, "rb");
|
||||
if (*p_stream == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(*p_stream, NULL);
|
||||
|
||||
n = fread(&header, 1, sizeof(header), *p_stream);
|
||||
if (n != sizeof(header)) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
if (memcmp(header.magic, PSA_ITS_MAGIC_STRING,
|
||||
PSA_ITS_MAGIC_LENGTH) != 0) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
p_info->size = MBEDTLS_GET_UINT32_LE(header.size, 0);
|
||||
p_info->flags = MBEDTLS_GET_UINT32_LE(header.flags, 0);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info)
|
||||
{
|
||||
psa_status_t status;
|
||||
FILE *stream = NULL;
|
||||
status = psa_its_read_file(uid, p_info, &stream);
|
||||
if (stream != NULL) {
|
||||
fclose(stream);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get(psa_storage_uid_t uid,
|
||||
uint32_t data_offset,
|
||||
uint32_t data_length,
|
||||
void *p_data,
|
||||
size_t *p_data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
FILE *stream = NULL;
|
||||
size_t n;
|
||||
struct psa_storage_info_t info;
|
||||
|
||||
status = psa_its_read_file(uid, &info, &stream);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
if (data_offset + data_length < data_offset) {
|
||||
goto exit;
|
||||
}
|
||||
#if SIZE_MAX < 0xffffffff
|
||||
if (data_offset + data_length > SIZE_MAX) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
if (data_offset + data_length > info.size) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
#if LONG_MAX < 0xffffffff
|
||||
while (data_offset > LONG_MAX) {
|
||||
if (fseek(stream, LONG_MAX, SEEK_CUR) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
data_offset -= LONG_MAX;
|
||||
}
|
||||
#endif
|
||||
if (fseek(stream, data_offset, SEEK_CUR) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
n = fread(p_data, 1, data_length, stream);
|
||||
if (n != data_length) {
|
||||
goto exit;
|
||||
}
|
||||
status = PSA_SUCCESS;
|
||||
if (p_data_length != NULL) {
|
||||
*p_data_length = n;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (stream != NULL) {
|
||||
fclose(stream);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_set(psa_storage_uid_t uid,
|
||||
uint32_t data_length,
|
||||
const void *p_data,
|
||||
psa_storage_create_flags_t create_flags)
|
||||
{
|
||||
if (uid == 0) {
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
psa_status_t status = PSA_ERROR_STORAGE_FAILURE;
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
FILE *stream = NULL;
|
||||
psa_its_file_header_t header;
|
||||
size_t n;
|
||||
|
||||
memcpy(header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH);
|
||||
MBEDTLS_PUT_UINT32_LE(data_length, header.size, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(create_flags, header.flags, 0);
|
||||
|
||||
psa_its_fill_filename(uid, filename);
|
||||
stream = fopen(PSA_ITS_STORAGE_TEMP, "wb");
|
||||
|
||||
if (stream == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(stream, NULL);
|
||||
|
||||
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
n = fwrite(&header, 1, sizeof(header), stream);
|
||||
if (n != sizeof(header)) {
|
||||
goto exit;
|
||||
}
|
||||
if (data_length != 0) {
|
||||
n = fwrite(p_data, 1, data_length, stream);
|
||||
if (n != data_length) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (stream != NULL) {
|
||||
int ret = fclose(stream);
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
}
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (rename_replace_existing(PSA_ITS_STORAGE_TEMP, filename) != 0) {
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
}
|
||||
/* The temporary file may still exist, but only in failure cases where
|
||||
* we're already reporting an error. So there's nothing we can do on
|
||||
* failure. If the function succeeded, and in some error cases, the
|
||||
* temporary file doesn't exist and so remove() is expected to fail.
|
||||
* Thus we just ignore the return status of remove(). */
|
||||
(void) remove(PSA_ITS_STORAGE_TEMP);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t uid)
|
||||
{
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
FILE *stream;
|
||||
psa_its_fill_filename(uid, filename);
|
||||
stream = fopen(filename, "rb");
|
||||
if (stream == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
fclose(stream);
|
||||
if (remove(filename) != 0) {
|
||||
return PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_ITS_FILE_C */
|
||||
608
engine/thirdparty/mbedtls/library/psa_util.c
vendored
Normal file
608
engine/thirdparty/mbedtls/library/psa_util.c
vendored
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* PSA hashing layer on top of Mbed TLS software crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* This is needed for MBEDTLS_ERR_XXX macros */
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C)
|
||||
#include <mbedtls/asn1write.h>
|
||||
#include <psa/crypto_sizes.h>
|
||||
#endif
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
#include <mbedtls/md.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
#include <mbedtls/lms.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
|
||||
#include <mbedtls/ssl.h>
|
||||
#endif
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
#include <mbedtls/rsa.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#include <mbedtls/ecp.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
#include <mbedtls/pk.h>
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include <mbedtls/cipher.h>
|
||||
#endif
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
/* PSA_SUCCESS is kept at the top of each error table since
|
||||
* it's the most common status when everything functions properly. */
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
const mbedtls_error_pair_t psa_to_md_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_MD_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_MD_ALLOC_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
const mbedtls_error_pair_t psa_to_cipher_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_CIPHER_ALLOC_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_LMS_C)
|
||||
const mbedtls_error_pair_t psa_to_lms_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_LMS_BAD_INPUT_DATA }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS_C) && \
|
||||
(defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
|
||||
const mbedtls_error_pair_t psa_to_ssl_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_INSUFFICIENT_MEMORY, MBEDTLS_ERR_SSL_ALLOC_FAILED },
|
||||
{ PSA_ERROR_NOT_SUPPORTED, MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_SSL_INVALID_MAC },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_SSL_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_BAD_STATE, MBEDTLS_ERR_SSL_INTERNAL_ERROR },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \
|
||||
defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
const mbedtls_error_pair_t psa_to_pk_rsa_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_RSA_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE },
|
||||
{ PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_RSA_RNG_FAILED },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_RSA_VERIFY_FAILED },
|
||||
{ PSA_ERROR_INVALID_PADDING, MBEDTLS_ERR_RSA_INVALID_PADDING }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
const mbedtls_error_pair_t psa_to_pk_ecdsa_errors[] =
|
||||
{
|
||||
{ PSA_SUCCESS, 0 },
|
||||
{ PSA_ERROR_NOT_PERMITTED, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_ARGUMENT, MBEDTLS_ERR_ECP_BAD_INPUT_DATA },
|
||||
{ PSA_ERROR_INVALID_HANDLE, MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE },
|
||||
{ PSA_ERROR_BUFFER_TOO_SMALL, MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL },
|
||||
{ PSA_ERROR_INSUFFICIENT_ENTROPY, MBEDTLS_ERR_ECP_RANDOM_FAILED },
|
||||
{ PSA_ERROR_INVALID_SIGNATURE, MBEDTLS_ERR_ECP_VERIFY_FAILED }
|
||||
};
|
||||
#endif
|
||||
|
||||
int psa_generic_status_to_mbedtls(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_SUCCESS:
|
||||
return 0;
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
case PSA_ERROR_CORRUPTION_DETECTED:
|
||||
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
case PSA_ERROR_COMMUNICATION_FAILURE:
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
default:
|
||||
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int psa_status_to_mbedtls(psa_status_t status,
|
||||
const mbedtls_error_pair_t *local_translations,
|
||||
size_t local_errors_num,
|
||||
int (*fallback_f)(psa_status_t))
|
||||
{
|
||||
for (size_t i = 0; i < local_errors_num; i++) {
|
||||
if (status == local_translations[i].psa_status) {
|
||||
return local_translations[i].mbedtls_error;
|
||||
}
|
||||
}
|
||||
return fallback_f(status);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PK_C)
|
||||
int psa_pk_status_to_mbedtls(psa_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case PSA_ERROR_INVALID_HANDLE:
|
||||
return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return MBEDTLS_ERR_PK_INVALID_ALG;
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return MBEDTLS_ERR_PK_ALLOC_FAILED;
|
||||
case PSA_ERROR_BAD_STATE:
|
||||
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
case PSA_ERROR_DATA_CORRUPT:
|
||||
case PSA_ERROR_DATA_INVALID:
|
||||
case PSA_ERROR_STORAGE_FAILURE:
|
||||
return MBEDTLS_ERR_PK_FILE_IO_ERROR;
|
||||
default:
|
||||
return psa_generic_status_to_mbedtls(status);
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PK_C */
|
||||
|
||||
/****************************************************************/
|
||||
/* Key management */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
|
||||
size_t *bits)
|
||||
{
|
||||
switch (grpid) {
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP192R1)
|
||||
case MBEDTLS_ECP_DP_SECP192R1:
|
||||
*bits = 192;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP224R1)
|
||||
case MBEDTLS_ECP_DP_SECP224R1:
|
||||
*bits = 224;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP256R1)
|
||||
case MBEDTLS_ECP_DP_SECP256R1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP384R1)
|
||||
case MBEDTLS_ECP_DP_SECP384R1:
|
||||
*bits = 384;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP521R1)
|
||||
case MBEDTLS_ECP_DP_SECP521R1:
|
||||
*bits = 521;
|
||||
return PSA_ECC_FAMILY_SECP_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP256R1)
|
||||
case MBEDTLS_ECP_DP_BP256R1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP384R1)
|
||||
case MBEDTLS_ECP_DP_BP384R1:
|
||||
*bits = 384;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_BP512R1)
|
||||
case MBEDTLS_ECP_DP_BP512R1:
|
||||
*bits = 512;
|
||||
return PSA_ECC_FAMILY_BRAINPOOL_P_R1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_CURVE25519)
|
||||
case MBEDTLS_ECP_DP_CURVE25519:
|
||||
*bits = 255;
|
||||
return PSA_ECC_FAMILY_MONTGOMERY;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP192K1)
|
||||
case MBEDTLS_ECP_DP_SECP192K1:
|
||||
*bits = 192;
|
||||
return PSA_ECC_FAMILY_SECP_K1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP224K1)
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_SECP256K1)
|
||||
case MBEDTLS_ECP_DP_SECP256K1:
|
||||
*bits = 256;
|
||||
return PSA_ECC_FAMILY_SECP_K1;
|
||||
#endif
|
||||
#if defined(MBEDTLS_ECP_HAVE_CURVE448)
|
||||
case MBEDTLS_ECP_DP_CURVE448:
|
||||
*bits = 448;
|
||||
return PSA_ECC_FAMILY_MONTGOMERY;
|
||||
#endif
|
||||
default:
|
||||
*bits = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
|
||||
size_t bits)
|
||||
{
|
||||
switch (family) {
|
||||
case PSA_ECC_FAMILY_SECP_R1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_192)
|
||||
case 192:
|
||||
return MBEDTLS_ECP_DP_SECP192R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_224)
|
||||
case 224:
|
||||
return MBEDTLS_ECP_DP_SECP224R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_SECP256R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_384)
|
||||
case 384:
|
||||
return MBEDTLS_ECP_DP_SECP384R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_521)
|
||||
case 521:
|
||||
return MBEDTLS_ECP_DP_SECP521R1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_BRAINPOOL_P_R1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_BP256R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
|
||||
case 384:
|
||||
return MBEDTLS_ECP_DP_BP384R1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
|
||||
case 512:
|
||||
return MBEDTLS_ECP_DP_BP512R1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_MONTGOMERY:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
|
||||
case 255:
|
||||
return MBEDTLS_ECP_DP_CURVE25519;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
|
||||
case 448:
|
||||
return MBEDTLS_ECP_DP_CURVE448;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case PSA_ECC_FAMILY_SECP_K1:
|
||||
switch (bits) {
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_192)
|
||||
case 192:
|
||||
return MBEDTLS_ECP_DP_SECP192K1;
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_224)
|
||||
/* secp224k1 is not and will not be supported in PSA (#3541). */
|
||||
#endif
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_256)
|
||||
case 256:
|
||||
return MBEDTLS_ECP_DP_SECP256K1;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return MBEDTLS_ECP_DP_NONE;
|
||||
}
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/* Wrapper function allowing the classic API to use the PSA RNG.
|
||||
*
|
||||
* `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
|
||||
* `psa_generate_random(...)`. The state parameter is ignored since the
|
||||
* PSA API doesn't support passing an explicit state.
|
||||
*/
|
||||
int mbedtls_psa_get_random(void *p_rng,
|
||||
unsigned char *output,
|
||||
size_t output_size)
|
||||
{
|
||||
/* This function takes a pointer to the RNG state because that's what
|
||||
* classic mbedtls functions using an RNG expect. The PSA RNG manages
|
||||
* its own state internally and doesn't let the caller access that state.
|
||||
* So we just ignore the state parameter, and in practice we'll pass
|
||||
* NULL. */
|
||||
(void) p_rng;
|
||||
psa_status_t status = psa_generate_random(output, output_size);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return 0;
|
||||
} else {
|
||||
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
|
||||
|
||||
/**
|
||||
* \brief Convert a single raw coordinate to DER ASN.1 format. The output der
|
||||
* buffer is filled backward (i.e. starting from its end).
|
||||
*
|
||||
* \param raw_buf Buffer containing the raw coordinate to be
|
||||
* converted.
|
||||
* \param raw_len Length of raw_buf in bytes. This must be > 0.
|
||||
* \param der_buf_start Pointer to the beginning of the buffer which
|
||||
* will be filled with the DER converted data.
|
||||
* \param der_buf_end End of the buffer used to store the DER output.
|
||||
*
|
||||
* \return On success, the amount of data (in bytes) written to
|
||||
* the DER buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
|
||||
* buffer is too small to contain all the converted data.
|
||||
* \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
|
||||
* coordinate is null (i.e. all zeros).
|
||||
*
|
||||
* \warning Raw and der buffer must not be overlapping.
|
||||
*/
|
||||
static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
|
||||
unsigned char *der_buf_start,
|
||||
unsigned char *der_buf_end)
|
||||
{
|
||||
unsigned char *p = der_buf_end;
|
||||
int len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* ASN.1 DER encoding requires minimal length, so skip leading 0s.
|
||||
* Provided input MPIs should not be 0, but as a failsafe measure, still
|
||||
* detect that and return error in case. */
|
||||
while (*raw_buf == 0x00) {
|
||||
++raw_buf;
|
||||
--raw_len;
|
||||
if (raw_len == 0) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
len = (int) raw_len;
|
||||
|
||||
/* Copy the raw coordinate to the end of der_buf. */
|
||||
if ((p - der_buf_start) < len) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
p -= len;
|
||||
memcpy(p, raw_buf, len);
|
||||
|
||||
/* If MSb is 1, ASN.1 requires that we prepend a 0. */
|
||||
if (*p & 0x80) {
|
||||
if ((p - der_buf_start) < 1) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
--p;
|
||||
*p = 0x00;
|
||||
++len;
|
||||
}
|
||||
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
|
||||
unsigned char *der, size_t der_size, size_t *der_len)
|
||||
{
|
||||
unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
|
||||
const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
|
||||
size_t len = 0;
|
||||
unsigned char *p = der + der_size;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (raw_len != (2 * coordinate_len)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
if (coordinate_len > sizeof(r)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Since raw and der buffers might overlap, dump r and s before starting
|
||||
* the conversion. */
|
||||
memcpy(r, raw, coordinate_len);
|
||||
memcpy(s, raw + coordinate_len, coordinate_len);
|
||||
|
||||
/* der buffer will initially be written starting from its end so we pick s
|
||||
* first and then r. */
|
||||
ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p -= ret;
|
||||
len += ret;
|
||||
|
||||
ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p -= ret;
|
||||
len += ret;
|
||||
|
||||
/* Add ASN.1 header (len + tag). */
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
|
||||
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE));
|
||||
|
||||
/* memmove the content of der buffer to its beginnig. */
|
||||
memmove(der, p, len);
|
||||
*der_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert a single integer from ASN.1 DER format to raw.
|
||||
*
|
||||
* \param der Buffer containing the DER integer value to be
|
||||
* converted.
|
||||
* \param der_len Length of the der buffer in bytes.
|
||||
* \param raw Output buffer that will be filled with the
|
||||
* converted data. This should be at least
|
||||
* coordinate_size bytes and it must be zeroed before
|
||||
* calling this function.
|
||||
* \param coordinate_size Size (in bytes) of a single coordinate in raw
|
||||
* format.
|
||||
*
|
||||
* \return On success, the amount of DER data parsed from the
|
||||
* provided der buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
|
||||
* is missing in the der buffer.
|
||||
* \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
|
||||
* is null (i.e. all zeros) or if the output raw buffer
|
||||
* is too small to contain the converted raw value.
|
||||
*
|
||||
* \warning Der and raw buffers must not be overlapping.
|
||||
*/
|
||||
static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t coordinate_size)
|
||||
{
|
||||
unsigned char *p = der;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t unpadded_len, padding_len = 0;
|
||||
|
||||
/* Get the length of ASN.1 element (i.e. the integer we need to parse). */
|
||||
ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
|
||||
MBEDTLS_ASN1_INTEGER);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* It's invalid to have:
|
||||
* - unpadded_len == 0.
|
||||
* - MSb set without a leading 0x00 (leading 0x00 is checked below). */
|
||||
if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* Skip possible leading zero */
|
||||
if (*p == 0x00) {
|
||||
p++;
|
||||
unpadded_len--;
|
||||
/* It is not allowed to have more than 1 leading zero.
|
||||
* Ignore the case in which unpadded_len = 0 because that's a 0 encoded
|
||||
* in ASN.1 format (i.e. 020100). */
|
||||
if ((unpadded_len > 0) && (*p == 0x00)) {
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (unpadded_len > coordinate_size) {
|
||||
/* Parsed number is longer than the maximum expected value. */
|
||||
return MBEDTLS_ERR_ASN1_INVALID_DATA;
|
||||
}
|
||||
padding_len = coordinate_size - unpadded_len;
|
||||
/* raw buffer was already zeroed by the calling function so zero-padding
|
||||
* operation is skipped here. */
|
||||
memcpy(raw + padding_len, p, unpadded_len);
|
||||
p += unpadded_len;
|
||||
|
||||
return (int) (p - der);
|
||||
}
|
||||
|
||||
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t raw_size, size_t *raw_len)
|
||||
{
|
||||
unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
|
||||
unsigned char *p = (unsigned char *) der;
|
||||
size_t data_len;
|
||||
size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
|
||||
int ret;
|
||||
|
||||
/* The output raw buffer should be at least twice the size of a raw
|
||||
* coordinate in order to store r and s. */
|
||||
if (raw_size < coordinate_size * 2) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
if (2 * coordinate_size > sizeof(raw_tmp)) {
|
||||
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Check that the provided input DER buffer has the right header. */
|
||||
ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(raw_tmp, 0, 2 * coordinate_size);
|
||||
|
||||
/* Extract r */
|
||||
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p += ret;
|
||||
data_len -= ret;
|
||||
|
||||
/* Extract s */
|
||||
ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
|
||||
coordinate_size);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p += ret;
|
||||
data_len -= ret;
|
||||
|
||||
/* Check that we consumed all the input der data. */
|
||||
if ((size_t) (p - der) != der_len) {
|
||||
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
memcpy(raw, raw_tmp, 2 * coordinate_size);
|
||||
*raw_len = 2 * coordinate_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
|
||||
3
engine/thirdparty/mbedtls/library/rsa.c
vendored
3
engine/thirdparty/mbedtls/library/rsa.c
vendored
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "bignum_core.h"
|
||||
#include "bignum_internal.h"
|
||||
#include "rsa_alt_helpers.h"
|
||||
#include "rsa_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
|
|
@ -1259,7 +1260,7 @@ int mbedtls_rsa_public(mbedtls_rsa_context *ctx,
|
|||
}
|
||||
|
||||
olen = ctx->len;
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod_unsafe(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
|
||||
|
||||
cleanup:
|
||||
|
|
|
|||
4
engine/thirdparty/mbedtls/library/sha256.c
vendored
4
engine/thirdparty/mbedtls/library/sha256.c
vendored
|
|
@ -44,7 +44,9 @@
|
|||
#endif /* defined(__clang__) && (__clang_major__ >= 4) */
|
||||
|
||||
/* Ensure that SIG_SETMASK is defined when -std=c99 is used. */
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
|
@ -150,7 +152,9 @@ static int mbedtls_a64_crypto_sha256_determine_support(void)
|
|||
return 1;
|
||||
}
|
||||
#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long d
|
|||
|
||||
void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_destroy_key(ctx->psa_hmac_key);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ const char *mbedtls_ssl_named_group_to_str( uint16_t in )
|
|||
return "ffdhe8192";
|
||||
};
|
||||
|
||||
return "UNKOWN";
|
||||
return "UNKNOWN";
|
||||
}
|
||||
const char *mbedtls_ssl_sig_alg_to_str( uint16_t in )
|
||||
{
|
||||
|
|
|
|||
96
engine/thirdparty/mbedtls/library/ssl_misc.h
vendored
96
engine/thirdparty/mbedtls/library/ssl_misc.h
vendored
|
|
@ -1507,7 +1507,7 @@ int mbedtls_ssl_psk_derive_premaster(mbedtls_ssl_context *ssl,
|
|||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_CLI_C) || defined(MBEDTLS_SSL_SRV_C)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_conf_has_static_psk(mbedtls_ssl_config const *conf);
|
||||
#endif
|
||||
|
|
@ -1674,18 +1674,53 @@ static inline mbedtls_x509_crt *mbedtls_ssl_own_cert(mbedtls_ssl_context *ssl)
|
|||
}
|
||||
|
||||
/*
|
||||
* Check usage of a certificate wrt extensions:
|
||||
* keyUsage, extendedKeyUsage (later), and nSCertType (later).
|
||||
* Verify a certificate.
|
||||
*
|
||||
* Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we
|
||||
* check a cert we received from them)!
|
||||
* [in/out] ssl: misc. things read
|
||||
* ssl->session_negotiate->verify_result updated
|
||||
* [in] authmode: one of MBEDTLS_SSL_VERIFY_{NONE,OPTIONAL,REQUIRED}
|
||||
* [in] chain: the certificate chain to verify (ie the peer's chain)
|
||||
* [in] ciphersuite_info: For TLS 1.2, this session's ciphersuite;
|
||||
* for TLS 1.3, may be left NULL.
|
||||
* [in] rs_ctx: restart context if restartable ECC is in use;
|
||||
* leave NULL for no restartable behaviour.
|
||||
*
|
||||
* Return:
|
||||
* - 0 if the handshake should continue. Depending on the
|
||||
* authmode it means:
|
||||
* - REQUIRED: the certificate was found to be valid, trusted & acceptable.
|
||||
* ssl->session_negotiate->verify_result is 0.
|
||||
* - OPTIONAL: the certificate may or may not be acceptable, but
|
||||
* ssl->session_negotiate->verify_result was updated with the result.
|
||||
* - NONE: the certificate wasn't even checked.
|
||||
* - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED or MBEDTLS_ERR_SSL_BAD_CERTIFICATE if
|
||||
* the certificate was found to be invalid/untrusted/unacceptable and the
|
||||
* handshake should be aborted (can only happen with REQUIRED).
|
||||
* - another error code if another error happened (out-of-memory, etc.)
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
|
||||
int authmode,
|
||||
mbedtls_x509_crt *chain,
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
|
||||
void *rs_ctx);
|
||||
|
||||
/*
|
||||
* Check usage of a certificate wrt usage extensions:
|
||||
* keyUsage and extendedKeyUsage.
|
||||
* (Note: nSCertType is deprecated and not standard, we don't check it.)
|
||||
*
|
||||
* Note: if tls_version is 1.3, ciphersuite is ignored and can be NULL.
|
||||
*
|
||||
* Note: recv_endpoint is the receiver's endpoint.
|
||||
*
|
||||
* Return 0 if everything is OK, -1 if not.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite,
|
||||
int cert_endpoint,
|
||||
int recv_endpoint,
|
||||
mbedtls_ssl_protocol_version tls_version,
|
||||
uint32_t *flags);
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
|
|
@ -1891,6 +1926,26 @@ static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13(const mbedtls_ssl_confi
|
|||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
/** \brief Initialize the PSA crypto subsystem if necessary.
|
||||
*
|
||||
* Call this function before doing any cryptography in a TLS 1.3 handshake.
|
||||
*
|
||||
* This is necessary in Mbed TLS 3.x for backward compatibility.
|
||||
* Up to Mbed TLS 3.5, in the default configuration, you could perform
|
||||
* a TLS connection with default parameters without having called
|
||||
* psa_crypto_init(), since the TLS layer only supported TLS 1.2 and
|
||||
* did not use PSA crypto. (TLS 1.2 only uses PSA crypto if
|
||||
* MBEDTLS_USE_PSA_CRYPTO is enabled, which is not the case in the default
|
||||
* configuration.) Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled
|
||||
* by default, and the TLS 1.3 layer uses PSA crypto. This means that
|
||||
* applications that are not otherwise using PSA crypto and that worked
|
||||
* with Mbed TLS 3.5 started failing in TLS 3.6.0 if they connected to
|
||||
* a peer that supports TLS 1.3. See
|
||||
* https://github.com/Mbed-TLS/mbedtls/issues/9072
|
||||
*/
|
||||
int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl);
|
||||
|
||||
extern const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
|
||||
MBEDTLS_SERVER_HELLO_RANDOM_LEN];
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
|
|
@ -2914,8 +2969,37 @@ static inline void mbedtls_ssl_tls13_session_clear_ticket_flags(
|
|||
{
|
||||
session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT 0
|
||||
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT 1
|
||||
|
||||
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK \
|
||||
(1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT)
|
||||
#define MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK \
|
||||
(1 << MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT)
|
||||
|
||||
static inline int mbedtls_ssl_conf_get_session_tickets(
|
||||
const mbedtls_ssl_config *conf)
|
||||
{
|
||||
return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK ?
|
||||
MBEDTLS_SSL_SESSION_TICKETS_ENABLED :
|
||||
MBEDTLS_SSL_SESSION_TICKETS_DISABLED;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
static inline int mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(
|
||||
const mbedtls_ssl_config *conf)
|
||||
{
|
||||
return conf->session_tickets & MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK ?
|
||||
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED :
|
||||
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl);
|
||||
#endif
|
||||
|
|
|
|||
39
engine/thirdparty/mbedtls/library/ssl_msg.c
vendored
39
engine/thirdparty/mbedtls/library/ssl_msg.c
vendored
|
|
@ -5570,9 +5570,9 @@ static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
|
|||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_check_new_session_ticket(mbedtls_ssl_context *ssl)
|
||||
static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
|
||||
if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) ||
|
||||
|
|
@ -5580,15 +5580,9 @@ static int ssl_tls13_check_new_session_ticket(mbedtls_ssl_context *ssl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssl->keep_current_message = 1;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
|
||||
mbedtls_ssl_handshake_set_state(ssl,
|
||||
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
return 1;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
|
||||
|
|
@ -5596,14 +5590,29 @@ static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
|
|||
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message"));
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
int ret = ssl_tls13_check_new_session_ticket(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
if (ssl_tls13_is_new_session_ticket(ssl)) {
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
|
||||
if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) ==
|
||||
MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) {
|
||||
ssl->keep_current_message = 1;
|
||||
|
||||
mbedtls_ssl_handshake_set_state(ssl,
|
||||
MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled."));
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported."));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
|
||||
/* Fail in all other cases. */
|
||||
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
|
|
|
|||
|
|
@ -534,6 +534,10 @@ cleanup:
|
|||
*/
|
||||
void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_destroy_key(ctx->keys[0].key);
|
||||
psa_destroy_key(ctx->keys[1].key);
|
||||
|
|
|
|||
617
engine/thirdparty/mbedtls/library/ssl_tls.c
vendored
617
engine/thirdparty/mbedtls/library/ssl_tls.c
vendored
|
|
@ -132,7 +132,7 @@ int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl,
|
|||
|
||||
int mbedtls_ssl_get_own_cid(mbedtls_ssl_context *ssl,
|
||||
int *enabled,
|
||||
unsigned char own_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX],
|
||||
unsigned char own_cid[MBEDTLS_SSL_CID_IN_LEN_MAX],
|
||||
size_t *own_cid_len)
|
||||
{
|
||||
*enabled = MBEDTLS_SSL_CID_DISABLED;
|
||||
|
|
@ -1354,29 +1354,6 @@ static int ssl_conf_check(const mbedtls_ssl_context *ssl)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* RFC 8446 section 4.4.3
|
||||
*
|
||||
* If the verification fails, the receiver MUST terminate the handshake with
|
||||
* a "decrypt_error" alert.
|
||||
*
|
||||
* If the client is configured as TLS 1.3 only with optional verify, return
|
||||
* bad config.
|
||||
*
|
||||
*/
|
||||
if (mbedtls_ssl_conf_tls13_is_ephemeral_enabled(
|
||||
(mbedtls_ssl_context *) ssl) &&
|
||||
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
|
||||
ssl->conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
ssl->conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
|
||||
ssl->conf->authmode == MBEDTLS_SSL_VERIFY_OPTIONAL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
1, ("Optional verify auth mode "
|
||||
"is not available for TLS 1.3 client"));
|
||||
return MBEDTLS_ERR_SSL_BAD_CONFIG;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
if (ssl->conf->f_rng == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
|
||||
return MBEDTLS_ERR_SSL_NO_RNG;
|
||||
|
|
@ -1760,6 +1737,7 @@ int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session
|
|||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
|
||||
|
||||
|
|
@ -1770,6 +1748,14 @@ int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session
|
|||
session->ciphersuite));
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* If session tickets are not enabled, it is not possible to resume a
|
||||
* TLS 1.3 session, thus do not make any change to the SSL context in
|
||||
* the first place.
|
||||
*/
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
|
|
@ -2234,6 +2220,7 @@ static void ssl_remove_psk(mbedtls_ssl_context *ssl)
|
|||
mbedtls_zeroize_and_free(ssl->handshake->psk,
|
||||
ssl->handshake->psk_len);
|
||||
ssl->handshake->psk_len = 0;
|
||||
ssl->handshake->psk = NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
|
|
@ -2999,11 +2986,24 @@ void mbedtls_ssl_conf_renegotiation_period(mbedtls_ssl_config *conf,
|
|||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
|
||||
void mbedtls_ssl_conf_session_tickets(mbedtls_ssl_config *conf, int use_tickets)
|
||||
{
|
||||
conf->session_tickets = use_tickets;
|
||||
conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_MASK;
|
||||
conf->session_tickets |= (use_tickets != 0) <<
|
||||
MBEDTLS_SSL_SESSION_TICKETS_TLS1_2_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
void mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
|
||||
mbedtls_ssl_config *conf, int signal_new_session_tickets)
|
||||
{
|
||||
conf->session_tickets &= ~MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_MASK;
|
||||
conf->session_tickets |= (signal_new_session_tickets != 0) <<
|
||||
MBEDTLS_SSL_SESSION_TICKETS_TLS1_3_BIT;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
|
||||
|
|
@ -4049,7 +4049,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
|
|||
}
|
||||
|
||||
static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
|
||||
unsigned char *buf,
|
||||
const unsigned char *buf,
|
||||
size_t buf_len)
|
||||
{
|
||||
((void) session);
|
||||
|
|
@ -5868,7 +5868,33 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
|
|||
if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
|
||||
mbedtls_ssl_conf_session_tickets(conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* Contrary to TLS 1.2 tickets, TLS 1.3 NewSessionTicket message
|
||||
* handling is disabled by default in Mbed TLS 3.6.x for backward
|
||||
* compatibility with client applications developed using Mbed TLS 3.5
|
||||
* or earlier with the default configuration.
|
||||
*
|
||||
* Up to Mbed TLS 3.5, in the default configuration TLS 1.3 was
|
||||
* disabled, and a Mbed TLS client with the default configuration would
|
||||
* establish a TLS 1.2 connection with a TLS 1.2 and TLS 1.3 capable
|
||||
* server.
|
||||
*
|
||||
* Starting with Mbed TLS 3.6.0, TLS 1.3 is enabled by default, and thus
|
||||
* an Mbed TLS client with the default configuration establishes a
|
||||
* TLS 1.3 connection with a TLS 1.2 and TLS 1.3 capable server. If
|
||||
* following the handshake the TLS 1.3 server sends NewSessionTicket
|
||||
* messages and the Mbed TLS client processes them, this results in
|
||||
* Mbed TLS high level APIs (mbedtls_ssl_read(),
|
||||
* mbedtls_ssl_handshake(), ...) to eventually return an
|
||||
* #MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET non fatal error code
|
||||
* (see the documentation of mbedtls_ssl_read() for more information on
|
||||
* that error code). Applications unaware of that TLS 1.3 specific non
|
||||
* fatal error code are then failing.
|
||||
*/
|
||||
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(
|
||||
conf, MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_DISABLED);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -6030,6 +6056,10 @@ int mbedtls_ssl_config_defaults(mbedtls_ssl_config *conf,
|
|||
*/
|
||||
void mbedtls_ssl_config_free(mbedtls_ssl_config *conf)
|
||||
{
|
||||
if (conf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DHM_C)
|
||||
mbedtls_mpi_free(&conf->dhm_P);
|
||||
mbedtls_mpi_free(&conf->dhm_G);
|
||||
|
|
@ -6344,71 +6374,6 @@ const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite,
|
||||
int cert_endpoint,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int usage = 0;
|
||||
const char *ext_oid;
|
||||
size_t ext_len;
|
||||
|
||||
if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
/* Server part of the key exchange */
|
||||
switch (ciphersuite->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
|
||||
usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
|
||||
break;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
|
||||
break;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
|
||||
break;
|
||||
|
||||
/* Don't use default: we want warnings when adding new values */
|
||||
case MBEDTLS_KEY_EXCHANGE_NONE:
|
||||
case MBEDTLS_KEY_EXCHANGE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
|
||||
usage = 0;
|
||||
}
|
||||
} else {
|
||||
/* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
|
||||
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
|
||||
}
|
||||
|
||||
if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (cert_endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
ext_oid = MBEDTLS_OID_SERVER_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
|
||||
} else {
|
||||
ext_oid = MBEDTLS_OID_CLIENT_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
|
||||
}
|
||||
|
||||
if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
int mbedtls_ssl_get_handshake_transcript(mbedtls_ssl_context *ssl,
|
||||
const mbedtls_md_type_t md,
|
||||
|
|
@ -7927,196 +7892,6 @@ static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl,
|
|||
return SSL_CERTIFICATE_EXPECTED;
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
|
||||
int authmode,
|
||||
mbedtls_x509_crt *chain,
|
||||
void *rs_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
ssl->handshake->ciphersuite_info;
|
||||
int have_ca_chain = 0;
|
||||
|
||||
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
|
||||
void *p_vrfy;
|
||||
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl->f_vrfy != NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
|
||||
f_vrfy = ssl->f_vrfy;
|
||||
p_vrfy = ssl->p_vrfy;
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
|
||||
f_vrfy = ssl->conf->f_vrfy;
|
||||
p_vrfy = ssl->conf->p_vrfy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main check: verify certificate
|
||||
*/
|
||||
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
|
||||
if (ssl->conf->f_ca_cb != NULL) {
|
||||
((void) rs_ctx);
|
||||
have_ca_chain = 1;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
|
||||
ret = mbedtls_x509_crt_verify_with_ca_cb(
|
||||
chain,
|
||||
ssl->conf->f_ca_cb,
|
||||
ssl->conf->p_ca_cb,
|
||||
ssl->conf->cert_profile,
|
||||
ssl->hostname,
|
||||
&ssl->session_negotiate->verify_result,
|
||||
f_vrfy, p_vrfy);
|
||||
} else
|
||||
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
|
||||
{
|
||||
mbedtls_x509_crt *ca_chain;
|
||||
mbedtls_x509_crl *ca_crl;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if (ssl->handshake->sni_ca_chain != NULL) {
|
||||
ca_chain = ssl->handshake->sni_ca_chain;
|
||||
ca_crl = ssl->handshake->sni_ca_crl;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ca_chain = ssl->conf->ca_chain;
|
||||
ca_crl = ssl->conf->ca_crl;
|
||||
}
|
||||
|
||||
if (ca_chain != NULL) {
|
||||
have_ca_chain = 1;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_crt_verify_restartable(
|
||||
chain,
|
||||
ca_chain, ca_crl,
|
||||
ssl->conf->cert_profile,
|
||||
ssl->hostname,
|
||||
&ssl->session_negotiate->verify_result,
|
||||
f_vrfy, p_vrfy, rs_ctx);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
|
||||
return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Secondary checks: always done, but change 'ret' only if it was 0
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
{
|
||||
const mbedtls_pk_context *pk = &chain->pk;
|
||||
|
||||
/* If certificate uses an EC key, make sure the curve is OK.
|
||||
* This is a public key, so it can't be opaque, so can_do() is a good
|
||||
* enough check to ensure pk_ec() is safe to use here. */
|
||||
if (mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
|
||||
/* and in the unlikely case the above assumption no longer holds
|
||||
* we are making sure that pk_ec() here does not return a NULL
|
||||
*/
|
||||
mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk);
|
||||
if (grp_id == MBEDTLS_ECP_DP_NONE) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID"));
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
|
||||
ssl->session_negotiate->verify_result |=
|
||||
MBEDTLS_X509_BADCERT_BAD_KEY;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
|
||||
if (ret == 0) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
if (mbedtls_ssl_check_cert_usage(chain,
|
||||
ciphersuite_info,
|
||||
!ssl->conf->endpoint,
|
||||
&ssl->session_negotiate->verify_result) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
|
||||
if (ret == 0) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* mbedtls_x509_crt_verify_with_profile is supposed to report a
|
||||
* verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
|
||||
* with details encoded in the verification flags. All other kinds
|
||||
* of error codes, including those from the user provided f_vrfy
|
||||
* functions, are treated as fatal and lead to a failure of
|
||||
* ssl_parse_certificate even if verification was optional. */
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
|
||||
(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
|
||||
ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
|
||||
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
uint8_t alert;
|
||||
|
||||
/* The certificate may have been rejected for several reasons.
|
||||
Pick one and send the corresponding alert. Which alert to send
|
||||
may be a subject of debate in some cases. */
|
||||
if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
|
||||
} else {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
|
||||
}
|
||||
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
alert);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
if (ssl->session_negotiate->verify_result != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
|
||||
(unsigned int) ssl->session_negotiate->verify_result));
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
|
||||
}
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_remember_peer_crt_digest(mbedtls_ssl_context *ssl,
|
||||
|
|
@ -8173,6 +7948,7 @@ int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
|
|||
{
|
||||
int ret = 0;
|
||||
int crt_expected;
|
||||
/* Authmode: precedence order is SNI if used else configuration */
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
|
||||
? ssl->handshake->sni_authmode
|
||||
|
|
@ -8252,8 +8028,9 @@ crt_verify:
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = ssl_parse_certificate_verify(ssl, authmode,
|
||||
chain, rs_ctx);
|
||||
ret = mbedtls_ssl_verify_certificate(ssl, authmode, chain,
|
||||
ssl->handshake->ciphersuite_info,
|
||||
rs_ctx);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -9919,4 +9696,274 @@ int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session,
|
|||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */
|
||||
|
||||
/*
|
||||
* The following functions are used by 1.2 and 1.3, client and server.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
|
||||
int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert,
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite,
|
||||
int recv_endpoint,
|
||||
mbedtls_ssl_protocol_version tls_version,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int usage = 0;
|
||||
const char *ext_oid;
|
||||
size_t ext_len;
|
||||
|
||||
/*
|
||||
* keyUsage
|
||||
*/
|
||||
|
||||
/* Note: don't guard this with MBEDTLS_SSL_CLI_C because the server wants
|
||||
* to check what a compliant client will think while choosing which cert
|
||||
* to send to the client. */
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
|
||||
recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
/* TLS 1.2 server part of the key exchange */
|
||||
switch (ciphersuite->key_exchange) {
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
|
||||
usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
|
||||
break;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
|
||||
break;
|
||||
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
|
||||
usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
|
||||
break;
|
||||
|
||||
/* Don't use default: we want warnings when adding new values */
|
||||
case MBEDTLS_KEY_EXCHANGE_NONE:
|
||||
case MBEDTLS_KEY_EXCHANGE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
|
||||
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
|
||||
usage = 0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* This is either TLS 1.3 authentication, which always uses signatures,
|
||||
* or 1.2 client auth: rsa_sign and mbedtls_ecdsa_sign are the only
|
||||
* options we implement, both using signatures. */
|
||||
(void) tls_version;
|
||||
(void) ciphersuite;
|
||||
usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
|
||||
}
|
||||
|
||||
if (mbedtls_x509_crt_check_key_usage(cert, usage) != 0) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* extKeyUsage
|
||||
*/
|
||||
|
||||
if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
ext_oid = MBEDTLS_OID_SERVER_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
|
||||
} else {
|
||||
ext_oid = MBEDTLS_OID_CLIENT_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
|
||||
}
|
||||
|
||||
if (mbedtls_x509_crt_check_extended_key_usage(cert, ext_oid, ext_len) != 0) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
|
||||
int authmode,
|
||||
mbedtls_x509_crt *chain,
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
|
||||
void *rs_ctx)
|
||||
{
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_NONE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Primary check: use the appropriate X.509 verification function
|
||||
*/
|
||||
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
|
||||
void *p_vrfy;
|
||||
if (ssl->f_vrfy != NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Use context-specific verification callback"));
|
||||
f_vrfy = ssl->f_vrfy;
|
||||
p_vrfy = ssl->p_vrfy;
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Use configuration-specific verification callback"));
|
||||
f_vrfy = ssl->conf->f_vrfy;
|
||||
p_vrfy = ssl->conf->p_vrfy;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int have_ca_chain_or_callback = 0;
|
||||
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
|
||||
if (ssl->conf->f_ca_cb != NULL) {
|
||||
((void) rs_ctx);
|
||||
have_ca_chain_or_callback = 1;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("use CA callback for X.509 CRT verification"));
|
||||
ret = mbedtls_x509_crt_verify_with_ca_cb(
|
||||
chain,
|
||||
ssl->conf->f_ca_cb,
|
||||
ssl->conf->p_ca_cb,
|
||||
ssl->conf->cert_profile,
|
||||
ssl->hostname,
|
||||
&ssl->session_negotiate->verify_result,
|
||||
f_vrfy, p_vrfy);
|
||||
} else
|
||||
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
|
||||
{
|
||||
mbedtls_x509_crt *ca_chain;
|
||||
mbedtls_x509_crl *ca_crl;
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if (ssl->handshake->sni_ca_chain != NULL) {
|
||||
ca_chain = ssl->handshake->sni_ca_chain;
|
||||
ca_crl = ssl->handshake->sni_ca_crl;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ca_chain = ssl->conf->ca_chain;
|
||||
ca_crl = ssl->conf->ca_crl;
|
||||
}
|
||||
|
||||
if (ca_chain != NULL) {
|
||||
have_ca_chain_or_callback = 1;
|
||||
}
|
||||
|
||||
ret = mbedtls_x509_crt_verify_restartable(
|
||||
chain,
|
||||
ca_chain, ca_crl,
|
||||
ssl->conf->cert_profile,
|
||||
ssl->hostname,
|
||||
&ssl->session_negotiate->verify_result,
|
||||
f_vrfy, p_vrfy, rs_ctx);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
|
||||
if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
|
||||
return MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Secondary checks: always done, but change 'ret' only if it was 0
|
||||
*/
|
||||
|
||||
/* With TLS 1.2 and ECC certs, check that the curve used by the
|
||||
* certificate is on our list of acceptable curves.
|
||||
*
|
||||
* With TLS 1.3 this is not needed because the curve is part of the
|
||||
* signature algorithm (eg ecdsa_secp256r1_sha256) which is checked when
|
||||
* we validate the signature made with the key associated to this cert.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
|
||||
defined(MBEDTLS_PK_HAVE_ECC_KEYS)
|
||||
if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 &&
|
||||
mbedtls_pk_can_do(&chain->pk, MBEDTLS_PK_ECKEY)) {
|
||||
if (mbedtls_ssl_check_curve(ssl, mbedtls_pk_get_ec_group_id(&chain->pk)) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (EC key curve)"));
|
||||
ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
|
||||
if (ret == 0) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_PK_HAVE_ECC_KEYS */
|
||||
|
||||
/* Check X.509 usage extensions (keyUsage, extKeyUsage) */
|
||||
if (mbedtls_ssl_check_cert_usage(chain,
|
||||
ciphersuite_info,
|
||||
ssl->conf->endpoint,
|
||||
ssl->tls_version,
|
||||
&ssl->session_negotiate->verify_result) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
|
||||
if (ret == 0) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* With authmode optional, we want to keep going if the certificate was
|
||||
* unacceptable, but still fail on other errors (out of memory etc),
|
||||
* including fatal errors from the f_vrfy callback.
|
||||
*
|
||||
* The only acceptable errors are:
|
||||
* - MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: cert rejected by primary check;
|
||||
* - MBEDTLS_ERR_SSL_BAD_CERTIFICATE: cert rejected by secondary checks.
|
||||
* Anything else is a fatal error. */
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
|
||||
(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
|
||||
ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* Return a specific error as this is a user error: inconsistent
|
||||
* configuration - can't verify without trust anchors. */
|
||||
if (have_ca_chain_or_callback == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
|
||||
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
uint8_t alert;
|
||||
|
||||
/* The certificate may have been rejected for several reasons.
|
||||
Pick one and send the corresponding alert. Which alert to send
|
||||
may be a subject of debate in some cases. */
|
||||
if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
|
||||
} else if (ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
|
||||
} else {
|
||||
alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
|
||||
}
|
||||
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||
alert);
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
if (ssl->session_negotiate->verify_result != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
|
||||
(unsigned int) ssl->session_negotiate->verify_result));
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
|
||||
}
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS_C */
|
||||
|
|
|
|||
|
|
@ -364,7 +364,8 @@ static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
|
|||
|
||||
*olen = 0;
|
||||
|
||||
if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
|
||||
if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
|
||||
MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -787,7 +788,8 @@ static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
|
|||
const unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
|
||||
if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
|
||||
MBEDTLS_SSL_SESSION_TICKETS_DISABLED) ||
|
||||
len != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1,
|
||||
("non-matching session ticket extension"));
|
||||
|
|
|
|||
|
|
@ -756,7 +756,9 @@ static int ssl_pick_cert(mbedtls_ssl_context *ssl,
|
|||
* and decrypting with the same RSA key.
|
||||
*/
|
||||
if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info,
|
||||
MBEDTLS_SSL_IS_SERVER, &flags) != 0) {
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_VERSION_TLS1_2,
|
||||
&flags) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
|
||||
"(extended) key usage extension"));
|
||||
continue;
|
||||
|
|
@ -2631,13 +2633,8 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
|
|||
ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
|
||||
ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
|
||||
|
||||
if (pk_type == MBEDTLS_PK_OPAQUE) {
|
||||
/* Opaque key is created by the user (externally from Mbed TLS)
|
||||
* so we assume it already has the right algorithm and flags
|
||||
* set. Just copy its ID as reference. */
|
||||
ssl->handshake->xxdh_psa_privkey = pk->priv_id;
|
||||
ssl->handshake->xxdh_psa_privkey_is_external = 1;
|
||||
} else {
|
||||
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
if (pk_type != MBEDTLS_PK_OPAQUE) {
|
||||
/* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK
|
||||
* module and only have ECDSA capabilities. Since we need
|
||||
* them for ECDH later, we export and then re-import them with
|
||||
|
|
@ -2665,10 +2662,20 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
|
|||
/* Set this key as owned by the TLS library: it will be its duty
|
||||
* to clear it exit. */
|
||||
ssl->handshake->xxdh_psa_privkey_is_external = 0;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
|
||||
|
||||
/* Opaque key is created by the user (externally from Mbed TLS)
|
||||
* so we assume it already has the right algorithm and flags
|
||||
* set. Just copy its ID as reference. */
|
||||
ssl->handshake->xxdh_psa_privkey = pk->priv_id;
|
||||
ssl->handshake->xxdh_psa_privkey_is_external = 1;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
|
||||
case MBEDTLS_PK_ECKEY:
|
||||
case MBEDTLS_PK_ECKEY_DH:
|
||||
|
|
@ -3916,7 +3923,7 @@ static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
uint8_t ecpoint_len;
|
||||
size_t ecpoint_len;
|
||||
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
|
||||
|
|
|
|||
|
|
@ -666,6 +666,7 @@ static int ssl_tls13_write_psk_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
|
||||
|
|
@ -678,7 +679,6 @@ static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
|
|||
return PSA_ALG_NONE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
static int ssl_tls13_has_configured_ticket(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
mbedtls_ssl_session *session = ssl->session_negotiate;
|
||||
|
|
@ -1141,6 +1141,11 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
|
|||
|
||||
*out_len = 0;
|
||||
|
||||
ret = mbedtls_ssl_tls13_crypto_init(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write supported_versions extension
|
||||
*
|
||||
* Supported Versions Extension is mandatory with TLS 1.3.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "psa/crypto.h"
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
|
||||
/* Define a local translating function to save code size by not using too many
|
||||
* arguments in each translating place. */
|
||||
static int local_err_translation(psa_status_t status)
|
||||
|
|
@ -37,7 +36,16 @@ static int local_err_translation(psa_status_t status)
|
|||
psa_generic_status_to_mbedtls);
|
||||
}
|
||||
#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
|
||||
#endif
|
||||
|
||||
int mbedtls_ssl_tls13_crypto_init(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
(void) ssl; // unused when debugging is disabled
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "psa_crypto_init", status);
|
||||
}
|
||||
return PSA_TO_MBEDTLS_ERR(status);
|
||||
}
|
||||
|
||||
const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
|
||||
MBEDTLS_SERVER_HELLO_RANDOM_LEN] =
|
||||
|
|
@ -193,10 +201,12 @@ static void ssl_tls13_create_verify_structure(const unsigned char *transcript_ha
|
|||
idx = 64;
|
||||
|
||||
if (from == MBEDTLS_SSL_IS_CLIENT) {
|
||||
memcpy(verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(client_cv));
|
||||
memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.client_cv,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv));
|
||||
idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(client_cv);
|
||||
} else { /* from == MBEDTLS_SSL_IS_SERVER */
|
||||
memcpy(verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(server_cv));
|
||||
memcpy(verify_buffer + idx, mbedtls_ssl_tls13_labels.server_cv,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv));
|
||||
idx += MBEDTLS_SSL_TLS1_3_LBL_LEN(server_cv);
|
||||
}
|
||||
|
||||
|
|
@ -470,6 +480,7 @@ int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl,
|
|||
mbedtls_free(ssl->session_negotiate->peer_cert);
|
||||
}
|
||||
|
||||
/* This is used by ssl_tls13_validate_certificate() */
|
||||
if (certificate_list_len == 0) {
|
||||
ssl->session_negotiate->peer_cert = NULL;
|
||||
ret = 0;
|
||||
|
|
@ -625,25 +636,13 @@ int mbedtls_ssl_tls13_parse_certificate(mbedtls_ssl_context *ssl,
|
|||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
int authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
mbedtls_x509_crt *ca_chain;
|
||||
mbedtls_x509_crl *ca_crl;
|
||||
const char *ext_oid;
|
||||
size_t ext_len;
|
||||
uint32_t verify_result = 0;
|
||||
|
||||
/* If SNI was used, overwrite authentication mode
|
||||
* from the configuration. */
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
|
||||
authmode = ssl->handshake->sni_authmode;
|
||||
} else
|
||||
#endif
|
||||
authmode = ssl->conf->authmode;
|
||||
}
|
||||
/* Authmode: precedence order is SNI if used else configuration */
|
||||
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
|
||||
? ssl->handshake->sni_authmode
|
||||
: ssl->conf->authmode;
|
||||
#else
|
||||
const int authmode = ssl->conf->authmode;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -675,6 +674,11 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
|||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
/* Regardless of authmode, the server is not allowed to send an empty
|
||||
* certificate chain. (Last paragraph before 4.4.2.1 in RFC 8446: "The
|
||||
* server's certificate_list MUST always be non-empty.") With authmode
|
||||
* optional/none, we continue the handshake if we can't validate the
|
||||
* server's cert, but we still break it if no certificate was sent. */
|
||||
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_NO_CERT,
|
||||
MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE);
|
||||
|
|
@ -683,114 +687,9 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl)
|
|||
#endif /* MBEDTLS_SSL_CLI_C */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||
if (ssl->handshake->sni_ca_chain != NULL) {
|
||||
ca_chain = ssl->handshake->sni_ca_chain;
|
||||
ca_crl = ssl->handshake->sni_ca_crl;
|
||||
} else
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||
{
|
||||
ca_chain = ssl->conf->ca_chain;
|
||||
ca_crl = ssl->conf->ca_crl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main check: verify certificate
|
||||
*/
|
||||
ret = mbedtls_x509_crt_verify_with_profile(
|
||||
ssl->session_negotiate->peer_cert,
|
||||
ca_chain, ca_crl,
|
||||
ssl->conf->cert_profile,
|
||||
ssl->hostname,
|
||||
&verify_result,
|
||||
ssl->conf->f_vrfy, ssl->conf->p_vrfy);
|
||||
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "x509_verify_cert", ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Secondary checks: always done, but change 'ret' only if it was 0
|
||||
*/
|
||||
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
ext_oid = MBEDTLS_OID_SERVER_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
|
||||
} else {
|
||||
ext_oid = MBEDTLS_OID_CLIENT_AUTH;
|
||||
ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
|
||||
}
|
||||
|
||||
if ((mbedtls_x509_crt_check_key_usage(
|
||||
ssl->session_negotiate->peer_cert,
|
||||
MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0) ||
|
||||
(mbedtls_x509_crt_check_extended_key_usage(
|
||||
ssl->session_negotiate->peer_cert,
|
||||
ext_oid, ext_len) != 0)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)"));
|
||||
if (ret == 0) {
|
||||
ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* mbedtls_x509_crt_verify_with_profile is supposed to report a
|
||||
* verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
|
||||
* with details encoded in the verification flags. All other kinds
|
||||
* of error codes, including those from the user provided f_vrfy
|
||||
* functions, are treated as fatal and lead to a failure of
|
||||
* mbedtls_ssl_tls13_parse_certificate even if verification was optional.
|
||||
*/
|
||||
if (authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
|
||||
(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
|
||||
ret == MBEDTLS_ERR_SSL_BAD_CERTIFICATE)) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("got no CA chain"));
|
||||
ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
/* The certificate may have been rejected for several reasons.
|
||||
Pick one and send the corresponding alert. Which alert to send
|
||||
may be a subject of debate in some cases. */
|
||||
if (verify_result & MBEDTLS_X509_BADCERT_OTHER) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_BAD_CERT, ret);
|
||||
} else if (verify_result & (MBEDTLS_X509_BADCERT_KEY_USAGE |
|
||||
MBEDTLS_X509_BADCERT_EXT_KEY_USAGE |
|
||||
MBEDTLS_X509_BADCERT_NS_CERT_TYPE |
|
||||
MBEDTLS_X509_BADCERT_BAD_PK |
|
||||
MBEDTLS_X509_BADCERT_BAD_KEY)) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_EXPIRED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_REVOKED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED, ret);
|
||||
} else if (verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA, ret);
|
||||
} else {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN, ret);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
if (verify_result != 0) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("! Certificate verification flags %08x",
|
||||
(unsigned int) verify_result));
|
||||
} else {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Certificate verification flags clear"));
|
||||
}
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
ssl->session_negotiate->verify_result = verify_result;
|
||||
return ret;
|
||||
return mbedtls_ssl_verify_certificate(ssl, authmode,
|
||||
ssl->session_negotiate->peer_cert,
|
||||
NULL, NULL);
|
||||
}
|
||||
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
|
|
@ -1482,9 +1381,11 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
|
|||
ssl->total_early_data_size)) {
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
|
||||
ssl->total_early_data_size, early_data_len,
|
||||
ssl->session_negotiate->max_early_data_size));
|
||||
2, ("EarlyData: Too much early data received, "
|
||||
"%lu + %" MBEDTLS_PRINTF_SIZET " > %lu",
|
||||
(unsigned long) ssl->total_early_data_size,
|
||||
early_data_len,
|
||||
(unsigned long) ssl->session_negotiate->max_early_data_size));
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
|
|
|
|||
|
|
@ -92,8 +92,9 @@ static void ssl_tls13_select_ciphersuite(
|
|||
return;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x",
|
||||
(unsigned) psk_ciphersuite_id, psk_hash_alg));
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
|
||||
(unsigned) psk_ciphersuite_id,
|
||||
(unsigned long) psk_hash_alg));
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
|
||||
|
|
@ -172,12 +173,12 @@ static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
|
|||
#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1
|
||||
#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl);
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl);
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_identity_match_ticket(
|
||||
mbedtls_ssl_context *ssl,
|
||||
|
|
@ -575,10 +576,8 @@ static int ssl_tls13_parse_pre_shared_key_ext(
|
|||
psa_algorithm_t psk_hash_alg;
|
||||
int allowed_key_exchange_modes;
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_session session;
|
||||
mbedtls_ssl_session_init(&session);
|
||||
#endif
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p_identity_len, identities_end, 2 + 1 + 4);
|
||||
identity_len = MBEDTLS_GET_UINT16_BE(p_identity_len, 0);
|
||||
|
|
@ -1356,19 +1355,23 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
* compression methods and the length of the extensions.
|
||||
*
|
||||
* cipher_suites cipher_suites_len bytes
|
||||
* legacy_compression_methods 2 bytes
|
||||
* extensions_len 2 bytes
|
||||
* legacy_compression_methods length 1 byte
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 2 + 2);
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cipher_suites_len + 1);
|
||||
p += cipher_suites_len;
|
||||
cipher_suites_end = p;
|
||||
|
||||
/* Check if we have enough data for legacy_compression_methods
|
||||
* and the length of the extensions (2 bytes).
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p + 1, end, p[0] + 2);
|
||||
|
||||
/*
|
||||
* Search for the supported versions extension and parse it to determine
|
||||
* if the client supports TLS 1.3.
|
||||
*/
|
||||
ret = mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
|
||||
ssl, p + 2, end,
|
||||
ssl, p + 1 + p[0], end,
|
||||
&supported_versions_data, &supported_versions_data_end);
|
||||
if (ret < 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1,
|
||||
|
|
@ -1409,6 +1412,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
|||
ssl->session_negotiate->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
ssl->session_negotiate->endpoint = ssl->conf->endpoint;
|
||||
|
||||
/* Before doing any crypto, make sure we can. */
|
||||
ret = mbedtls_ssl_tls13_crypto_init(ssl);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are negotiating the version 1.3 of the protocol. Do what we have
|
||||
* postponed: copy of the client random bytes, copy of the legacy session
|
||||
|
|
@ -3109,6 +3118,7 @@ static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/*
|
||||
* Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
|
||||
*/
|
||||
|
|
@ -3138,7 +3148,6 @@ static int ssl_tls13_write_new_session_ticket_coordinate(mbedtls_ssl_context *ss
|
|||
return SSL_NEW_SESSION_TICKET_WRITE;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
||||
unsigned char *ticket_nonce,
|
||||
|
|
|
|||
|
|
@ -423,6 +423,9 @@ static const char * const features[] = {
|
|||
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
||||
"PSA_CRYPTO_SPM", //no-check-names
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SPM */
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
"PSA_KEY_STORE_DYNAMIC", //no-check-names
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
"PSA_P256M_DRIVER_ENABLED", //no-check-names
|
||||
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
|
||||
|
|
|
|||
2
engine/thirdparty/mbedtls/library/x509_crt.c
vendored
2
engine/thirdparty/mbedtls/library/x509_crt.c
vendored
|
|
@ -48,7 +48,9 @@
|
|||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@ void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx)
|
|||
|
||||
void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->issuer);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->extensions);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ void mbedtls_x509write_csr_init(mbedtls_x509write_csr *ctx)
|
|||
|
||||
void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_asn1_free_named_data_list(&ctx->subject);
|
||||
mbedtls_asn1_free_named_data_list(&ctx->extensions);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/thirdparty/mbedtls/include/psa/crypto.h b/thirdparty/mbedtls/include/psa/crypto.h
|
||||
index 92f9c824e9..1cc2e7e729 100644
|
||||
index 2bbcea3ee0..96baf8f3ed 100644
|
||||
--- a/thirdparty/mbedtls/include/psa/crypto.h
|
||||
+++ b/thirdparty/mbedtls/include/psa/crypto.h
|
||||
@@ -107,7 +107,9 @@ psa_status_t psa_crypto_init(void);
|
||||
|
|
@ -12,7 +12,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Declare a key as persistent and set its key identifier.
|
||||
*
|
||||
@@ -333,7 +335,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
|
||||
@@ -336,7 +338,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
|
||||
*
|
||||
* \return The key type stored in the attribute structure.
|
||||
*/
|
||||
|
|
@ -22,7 +22,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Retrieve the key size from key attributes.
|
||||
*
|
||||
@@ -936,7 +940,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
|
||||
@@ -939,7 +943,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
|
||||
|
||||
/** Return an initial value for a hash operation object.
|
||||
*/
|
||||
|
|
@ -32,7 +32,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Set up a multipart hash operation.
|
||||
*
|
||||
@@ -1295,7 +1301,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
|
||||
@@ -1298,7 +1304,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
|
||||
|
||||
/** Return an initial value for a MAC operation object.
|
||||
*/
|
||||
|
|
@ -42,7 +42,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Set up a multipart MAC calculation operation.
|
||||
*
|
||||
@@ -1708,7 +1716,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
|
||||
@@ -1711,7 +1719,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
|
||||
|
||||
/** Return an initial value for a cipher operation object.
|
||||
*/
|
||||
|
|
@ -52,7 +52,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Set the key for a multipart symmetric encryption operation.
|
||||
*
|
||||
@@ -2226,7 +2236,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
|
||||
@@ -2229,7 +2239,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
|
||||
|
||||
/** Return an initial value for an AEAD operation object.
|
||||
*/
|
||||
|
|
@ -62,7 +62,7 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
|
||||
/** Set the key for a multipart authenticated encryption operation.
|
||||
*
|
||||
@@ -3213,7 +3225,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
|
||||
@@ -3216,7 +3228,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
|
||||
|
||||
/** Return an initial value for a key derivation operation object.
|
||||
*/
|
||||
|
|
@ -73,10 +73,10 @@ index 92f9c824e9..1cc2e7e729 100644
|
|||
/** Set up a key derivation operation.
|
||||
*
|
||||
diff --git a/thirdparty/mbedtls/include/psa/crypto_extra.h b/thirdparty/mbedtls/include/psa/crypto_extra.h
|
||||
index 6ed1f6c43a..2686b9d74d 100644
|
||||
index 0cf42c6055..d276cd4c7f 100644
|
||||
--- a/thirdparty/mbedtls/include/psa/crypto_extra.h
|
||||
+++ b/thirdparty/mbedtls/include/psa/crypto_extra.h
|
||||
@@ -915,7 +915,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
|
||||
@@ -923,7 +923,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
|
||||
|
||||
/** Return an initial value for a PAKE cipher suite object.
|
||||
*/
|
||||
|
|
@ -86,7 +86,7 @@ index 6ed1f6c43a..2686b9d74d 100644
|
|||
|
||||
/** Retrieve the PAKE algorithm from a PAKE cipher suite.
|
||||
*
|
||||
@@ -1048,7 +1050,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
|
||||
@@ -1056,7 +1058,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
|
||||
|
||||
/** Return an initial value for a PAKE operation object.
|
||||
*/
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
diff --git a/thirdparty/mbedtls/include/psa/crypto.h b/thirdparty/mbedtls/include/psa/crypto.h
|
||||
index 7083bd911b..92f9c824e9 100644
|
||||
--- a/thirdparty/mbedtls/include/psa/crypto.h
|
||||
+++ b/thirdparty/mbedtls/include/psa/crypto.h
|
||||
@@ -3834,12 +3834,14 @@ psa_status_t psa_key_derivation_output_key(
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
psa_status_t psa_key_derivation_output_key_ext(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_derivation_operation_t *operation,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
+#endif
|
||||
|
||||
/** Compare output data from a key derivation operation to an expected value.
|
||||
*
|
||||
@@ -4180,10 +4182,12 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
mbedtls_svc_key_id_t *key);
|
||||
+#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
diff --git a/thirdparty/mbedtls/include/psa/crypto_struct.h b/thirdparty/mbedtls/include/psa/crypto_struct.h
|
||||
index 3913551aa8..e2c227b2eb 100644
|
||||
--- a/thirdparty/mbedtls/include/psa/crypto_struct.h
|
||||
+++ b/thirdparty/mbedtls/include/psa/crypto_struct.h
|
||||
@@ -223,11 +223,13 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
|
||||
return v;
|
||||
}
|
||||
|
||||
+#ifndef __cplusplus
|
||||
struct psa_key_production_parameters_s {
|
||||
/* Future versions may add other fields in this structure. */
|
||||
uint32_t flags;
|
||||
uint8_t data[];
|
||||
};
|
||||
+#endif
|
||||
|
||||
/** The default production parameters for key generation or key derivation.
|
||||
*
|
||||
diff --git a/thirdparty/mbedtls/include/psa/crypto_types.h b/thirdparty/mbedtls/include/psa/crypto_types.h
|
||||
index c21bad86cc..a36b6ee65d 100644
|
||||
--- a/thirdparty/mbedtls/include/psa/crypto_types.h
|
||||
+++ b/thirdparty/mbedtls/include/psa/crypto_types.h
|
||||
@@ -477,7 +477,9 @@ typedef uint16_t psa_key_derivation_step_t;
|
||||
* - Other key types: reserved for future use. \c flags must be 0.
|
||||
*
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
typedef struct psa_key_production_parameters_s psa_key_production_parameters_t;
|
||||
+#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
diff --git a/thirdparty/mbedtls/library/psa_crypto_core.h b/thirdparty/mbedtls/library/psa_crypto_core.h
|
||||
index 9462d2e8be..c059162efe 100644
|
||||
--- a/thirdparty/mbedtls/library/psa_crypto_core.h
|
||||
+++ b/thirdparty/mbedtls/library/psa_crypto_core.h
|
||||
@@ -351,9 +351,11 @@ psa_status_t psa_export_public_key_internal(
|
||||
* \param[in] params The key production parameters to check.
|
||||
* \param params_data_length Size of `params->data` in bytes.
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
int psa_key_production_parameters_are_default(
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length);
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* \brief Generate a key.
|
||||
@@ -378,12 +380,14 @@ int psa_key_production_parameters_are_default(
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params,
|
||||
size_t params_data_length,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
+#endif
|
||||
|
||||
/** Sign a message with a private key. For hash-and-sign algorithms,
|
||||
* this includes the hashing step.
|
||||
diff --git a/thirdparty/mbedtls/library/psa_crypto_driver_wrappers.h b/thirdparty/mbedtls/library/psa_crypto_driver_wrappers.h
|
||||
index ea6aee32eb..6919971aca 100644
|
||||
--- a/thirdparty/mbedtls/library/psa_crypto_driver_wrappers.h
|
||||
+++ b/thirdparty/mbedtls/library/psa_crypto_driver_wrappers.h
|
||||
@@ -728,6 +728,7 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data(
|
||||
}
|
||||
}
|
||||
|
||||
+#ifndef __cplusplus
|
||||
static inline psa_status_t psa_driver_wrapper_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
@@ -832,6 +833,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key(
|
||||
|
||||
return( status );
|
||||
}
|
||||
+#endif
|
||||
|
||||
static inline psa_status_t psa_driver_wrapper_import_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
diff --git a/thirdparty/mbedtls/library/psa_crypto_rsa.h b/thirdparty/mbedtls/library/psa_crypto_rsa.h
|
||||
index ffeef26be1..6d695ddf50 100644
|
||||
--- a/thirdparty/mbedtls/library/psa_crypto_rsa.h
|
||||
+++ b/thirdparty/mbedtls/library/psa_crypto_rsa.h
|
||||
@@ -130,10 +130,12 @@ psa_status_t mbedtls_psa_rsa_export_public_key(
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
* The size of \p key_buffer is too small.
|
||||
*/
|
||||
+#ifndef __cplusplus
|
||||
psa_status_t mbedtls_psa_rsa_generate_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_production_parameters_t *params, size_t params_data_length,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
+#endif
|
||||
|
||||
/** Sign an already-calculated hash with an RSA private key.
|
||||
*
|
||||
Loading…
Add table
Add a link
Reference in a new issue