diff --git a/connectivity/mbedtls/CMakeLists.txt b/connectivity/mbedtls/CMakeLists.txt index e857db00fa3..aa7eac9a205 100644 --- a/connectivity/mbedtls/CMakeLists.txt +++ b/connectivity/mbedtls/CMakeLists.txt @@ -84,6 +84,7 @@ target_sources(mbed-mbedtls source/ssl_srv.c source/ssl_ticket.c source/ssl_tls.c + source/ssl_tls13_keys.c source/threading.c source/timing.c source/version.c diff --git a/connectivity/mbedtls/VERSION.txt b/connectivity/mbedtls/VERSION.txt index 4961d31884b..098c5314fa4 100644 --- a/connectivity/mbedtls/VERSION.txt +++ b/connectivity/mbedtls/VERSION.txt @@ -1 +1 @@ -mbedtls-2.22.0 +v2.25.0 diff --git a/connectivity/mbedtls/include/mbedtls/bignum.h b/connectivity/mbedtls/include/mbedtls/bignum.h index 0d019b9c44e..637360e30f1 100644 --- a/connectivity/mbedtls/include/mbedtls/bignum.h +++ b/connectivity/mbedtls/include/mbedtls/bignum.h @@ -61,12 +61,12 @@ * Maximum window size used for modular exponentiation. Default: 6 * Minimum value: 1. Maximum value: 6. * - * Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used + * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used * for the sliding window calculation. (So 64 by default) * * Reduction in size, reduces speed. */ -#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ #endif /* !MBEDTLS_MPI_WINDOW_SIZE */ #if !defined(MBEDTLS_MPI_MAX_SIZE) diff --git a/connectivity/mbedtls/include/mbedtls/ccm.h b/connectivity/mbedtls/include/mbedtls/ccm.h index 81965ba4dfa..7193863c372 100644 --- a/connectivity/mbedtls/include/mbedtls/ccm.h +++ b/connectivity/mbedtls/include/mbedtls/ccm.h @@ -148,7 +148,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * than zero, \p output must be a writable buffer of at least * that length. * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * writable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -193,7 +193,7 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * than zero, \p output must be a writable buffer of at least * that length. * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * writable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * diff --git a/connectivity/mbedtls/include/mbedtls/check_config.h b/connectivity/mbedtls/include/mbedtls/check_config.h index 3a1929ba930..500b3cf8045 100644 --- a/connectivity/mbedtls/include/mbedtls/check_config.h +++ b/connectivity/mbedtls/include/mbedtls/check_config.h @@ -604,6 +604,11 @@ #error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) +#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO." +#endif + #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ !defined(MBEDTLS_OID_C) ) #error "MBEDTLS_RSA_C defined, but not all prerequisites" @@ -866,6 +871,10 @@ #endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites" +#endif + /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the diff --git a/connectivity/mbedtls/include/mbedtls/cipher.h b/connectivity/mbedtls/include/mbedtls/cipher.h index 014786ad519..1cafa6ec2e3 100644 --- a/connectivity/mbedtls/include/mbedtls/cipher.h +++ b/connectivity/mbedtls/include/mbedtls/cipher.h @@ -227,10 +227,30 @@ enum { }; /** Maximum length of any IV, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined + * in ssl_internal.h. */ #define MBEDTLS_MAX_IV_LENGTH 16 + /** Maximum block size of any cipher, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in ssl_internal.h. */ #define MBEDTLS_MAX_BLOCK_LENGTH 16 +/** Maximum key length, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * For now, only check whether XTS is enabled which uses 64 Byte keys, + * and use 32 Bytes as an upper bound for the maximum key length otherwise. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in ssl_internal.h, which however deliberately ignores the case of XTS + * since the latter isn't used in SSL/TLS. */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +#define MBEDTLS_MAX_KEY_LENGTH 64 +#else +#define MBEDTLS_MAX_KEY_LENGTH 32 +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + /** * Base cipher information (opaque struct). */ @@ -837,30 +857,52 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ); #if defined(MBEDTLS_CIPHER_MODE_AEAD) +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_WARNING */ /** - * \brief The generic autenticated encryption (AEAD) function. + * \brief The generic authenticated encryption (AEAD) function. + * + * \deprecated Superseded by mbedtls_cipher_auth_encrypt_ext(). + * + * \note This function only supports AEAD algorithms, not key + * wrapping algorithms such as NIST_KW; for this, see + * mbedtls_cipher_auth_encrypt_ext(). * * \param ctx The generic cipher context. This must be initialized and - * bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. + * bound to a key associated with an AEAD algorithm. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and must not be \c NULL. + * \param iv_len The length of the nonce. This must satisfy the + * constraints imposed by the AEAD cipher used. * \param ad The additional data to authenticate. This must be a - * readable buffer of at least \p ad_len Bytes. + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. * \param ad_len The length of \p ad. * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. * \param ilen The length of the input data. - * \param output The buffer for the output data. This must be able to - * hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p ilen Bytes, and must + * not be \c NULL. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. * \param tag The buffer for the authentication tag. This must be a - * writable buffer of at least \p tag_len Bytes. - * \param tag_len The desired length of the authentication tag. + * writable buffer of at least \p tag_len Bytes. See note + * below regarding restrictions with PSA-based contexts. + * \param tag_len The desired length of the authentication tag. This + * must match the constraints imposed by the AEAD cipher + * used, and in particular must not be \c 0. + * + * \note If the context is based on PSA (that is, it was set up + * with mbedtls_cipher_setup_psa()), then it is required + * that \c tag == output + ilen. That is, the tag must be + * appended to the ciphertext as recommended by RFC 5116. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on @@ -872,36 +914,53 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ); + unsigned char *tag, size_t tag_len ) + MBEDTLS_DEPRECATED; /** - * \brief The generic autenticated decryption (AEAD) function. + * \brief The generic authenticated decryption (AEAD) function. + * + * \deprecated Superseded by mbedtls_cipher_auth_decrypt_ext(). + * + * \note This function only supports AEAD algorithms, not key + * wrapping algorithms such as NIST_KW; for this, see + * mbedtls_cipher_auth_decrypt_ext(). * * \note If the data is not authentic, then the output buffer * is zeroed out to prevent the unauthentic plaintext being * used, making this interface safer. * * \param ctx The generic cipher context. This must be initialized and - * and bound to a key. - * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. - * This must be a readable buffer of at least \p iv_len - * Bytes. - * \param iv_len The IV length for ciphers with variable-size IV. - * This parameter is discarded by ciphers with fixed-size IV. - * \param ad The additional data to be authenticated. This must be a - * readable buffer of at least \p ad_len Bytes. + * bound to a key associated with an AEAD algorithm. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and must not be \c NULL. + * \param iv_len The length of the nonce. This must satisfy the + * constraints imposed by the AEAD cipher used. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. * \param ad_len The length of \p ad. * \param input The buffer holding the input data. This must be a - * readable buffer of at least \p ilen Bytes. + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. * \param ilen The length of the input data. - * \param output The buffer for the output data. - * This must be able to hold at least \p ilen Bytes. - * \param olen The length of the output data, to be updated with the - * actual number of Bytes written. This must not be - * \c NULL. - * \param tag The buffer holding the authentication tag. This must be - * a readable buffer of at least \p tag_len Bytes. - * \param tag_len The length of the authentication tag. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p ilen Bytes, and must + * not be \c NULL. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag The buffer for the authentication tag. This must be a + * readable buffer of at least \p tag_len Bytes. See note + * below regarding restrictions with PSA-based contexts. + * \param tag_len The length of the authentication tag. This must match + * the constraints imposed by the AEAD cipher used, and in + * particular must not be \c 0. + * + * \note If the context is based on PSA (that is, it was set up + * with mbedtls_cipher_setup_psa()), then it is required + * that \c tag == input + len. That is, the tag must be + * appended to the ciphertext as recommended by RFC 5116. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on @@ -914,9 +973,120 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ); + const unsigned char *tag, size_t tag_len ) + MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_CIPHER_MODE_AEAD */ +#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note For AEAD modes, the tag will be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * must not be \c NULL. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen + \p tag_len. + * For NIST_KW, this must be at least \p ilen + 8 + * (rounded up to a multiple of 8 if KWP is used); + * \p ilen + 15 is always a safe value. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The desired length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ); + +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext being + * used, making this interface safer. + * + * \note For AEAD modes, the tag must be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. For AEAD ciphers this + * must be at least \p tag_len. For NIST_KW this must be + * at least \c 8. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * may be \c NULL if \p output_len is \c 0. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen - \p tag_len. + * For NIST_KW, this must be at least \p ilen - 8. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The actual length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ #ifdef __cplusplus } #endif diff --git a/connectivity/mbedtls/include/mbedtls/cipher_internal.h b/connectivity/mbedtls/include/mbedtls/cipher_internal.h index d28310847a1..2484c01c7a4 100644 --- a/connectivity/mbedtls/include/mbedtls/cipher_internal.h +++ b/connectivity/mbedtls/include/mbedtls/cipher_internal.h @@ -134,7 +134,7 @@ typedef enum typedef struct { psa_algorithm_t alg; - psa_key_handle_t slot; + psa_key_id_t slot; mbedtls_cipher_psa_key_ownership slot_state; } mbedtls_cipher_context_psa; #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/connectivity/mbedtls/include/mbedtls/config.h b/connectivity/mbedtls/include/mbedtls/config.h index 5ab37d996a7..249e5e38fb5 100644 --- a/connectivity/mbedtls/include/mbedtls/config.h +++ b/connectivity/mbedtls/include/mbedtls/config.h @@ -880,7 +880,7 @@ * may result in a compromise of the long-term signing key. This is avoided by * the deterministic variant. * - * Requires: MBEDTLS_HMAC_DRBG_C + * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C * * Comment this macro to disable deterministic ECDSA. */ @@ -1274,20 +1274,17 @@ */ //#define MBEDTLS_ENTROPY_NV_SEED -/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER +/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER * - * In PSA key storage, encode the owner of the key. + * Enable key identifiers that encode a key owner identifier. * - * This is only meaningful when building the library as part of a - * multi-client service. When you activate this option, you must provide - * an implementation of the type psa_key_owner_id_t and a translation - * from psa_key_file_id_t to file name in all the storage backends that - * you wish to support. + * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t + * which is currently hard-coded to be int32_t. * * Note that this option is meant for internal use only and may be removed - * without notice. + * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO. */ -//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER +//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER /** * \def MBEDTLS_MEMORY_DEBUG @@ -1345,6 +1342,17 @@ */ #define MBEDTLS_PKCS1_V21 +/** \def MBEDTLS_PSA_CRYPTO_DRIVERS + * + * Enable support for the experimental PSA crypto driver interface. + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_DRIVERS + /** * \def MBEDTLS_PSA_CRYPTO_SPM * @@ -1820,6 +1828,37 @@ */ #define MBEDTLS_SSL_DTLS_HELLO_VERIFY +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +//#define MBEDTLS_SSL_DTLS_SRTP + /** * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE * @@ -2027,6 +2066,24 @@ */ //#define MBEDTLS_USE_PSA_CRYPTO +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG + * + * This setting allows support for cryptographic mechanisms through the PSA + * API to be configured separately from support through the mbedtls API. + * + * Uncomment this to enable use of PSA Crypto configuration settings which + * can be found in include/psa/crypto_config.h. + * + * If you enable this option and write your own configuration file, you must + * include mbedtls/config_psa.h in your configuration file. The default + * provided mbedtls/config.h contains the necessary inclusion. + * + * This feature is still experimental and is not ready for production since + * it is not completed. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG + /** * \def MBEDTLS_VERSION_FEATURES * @@ -3466,7 +3523,7 @@ */ /* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ #define MBEDTLS_MPI_MAX_SIZE 512 /* CTR_DRBG options */ @@ -3819,6 +3876,10 @@ #include MBEDTLS_USER_CONFIG_FILE #endif +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +#include "mbedtls/config_psa.h" +#endif + #include "mbedtls/check_config.h" diff --git a/connectivity/mbedtls/include/mbedtls/config_psa.h b/connectivity/mbedtls/include/mbedtls/config_psa.h new file mode 100644 index 00000000000..2b4c498b25d --- /dev/null +++ b/connectivity/mbedtls/include/mbedtls/config_psa.h @@ -0,0 +1,335 @@ +/** + * \file mbedtls/config_psa.h + * \brief PSA crypto configuration options (set of defines) + * + * This set of compile-time options takes settings defined in + * include/mbedtls/config.h and include/psa/crypto_config.h and uses + * those definitions to define symbols used in the library code. + * + * Users and integrators should not edit this file, please edit + * include/mbedtls/config.h for MBETLS_XXX settings or + * include/psa/crypto_config.h for PSA_WANT_XXX settings. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_CONFIG_PSA_H +#define MBEDTLS_CONFIG_PSA_H + +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +#include "psa/crypto_config.h" +#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) + +#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) +#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_ECDSA_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_MD_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA */ +#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */ + +#if defined(PSA_WANT_ALG_ECDH) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDH */ +#endif /* PSA_WANT_ALG_ECDH */ + +#if defined(PSA_WANT_ALG_ECDSA) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 +#define MBEDTLS_ECDSA_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_ECDSA */ +#endif /* PSA_WANT_ALG_ECDSA */ + +#if defined(PSA_WANT_ALG_HKDF) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF) +#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 */ + +#if defined(PSA_WANT_ALG_HMAC) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */ +#endif /* PSA_WANT_ALG_HMAC */ + +#if defined(PSA_WANT_ALG_MD2) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD2) +#define MBEDTLS_PSA_BUILTIN_ALG_MD2 1 +#define MBEDTLS_MD2_C +#endif + +#if defined(PSA_WANT_ALG_MD4) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD4) +#define MBEDTLS_PSA_BUILTIN_ALG_MD4 1 +#define MBEDTLS_MD4_C +#endif + +#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 +#define MBEDTLS_MD5_C +#endif + +#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 +#define MBEDTLS_RIPEMD160_C +#endif + +#if defined(PSA_WANT_ALG_RSA_OAEP) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V21 +#define MBEDTLS_MD_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */ +#endif /* PSA_WANT_ALG_RSA_OAEP */ + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V15 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */ +#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */ + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_MD_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */ +#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */ + +#if defined(PSA_WANT_ALG_RSA_PSS) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V21 +#define MBEDTLS_MD_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */ +#endif /* PSA_WANT_ALG_RSA_PSS */ + +#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 +#define MBEDTLS_SHA1_C +#endif + +#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 +#define MBEDTLS_SHA256_C +#endif + +#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 +#define MBEDTLS_SHA256_C +#endif + +#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 +#define MBEDTLS_SHA512_C +#endif + +#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 +#define MBEDTLS_SHA512_C +#endif + +#if defined(PSA_WANT_ALG_TLS12_PRF) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */ +#endif /* PSA_WANT_ALG_TLS12_PRF */ + +#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */ +#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1 +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR */ +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */ +#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_GENPRIME +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PK_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR */ +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PK_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */ +#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */ + +#else /* MBEDTLS_PSA_CRYPTO_CONFIG */ + +/* + * Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG + * is not defined + */ + +#if defined(MBEDTLS_ECDH_C) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 +#define PSA_WANT_ALG_ECDH 1 +#endif /* MBEDTLS_ECDH_C */ + +#if defined(MBEDTLS_ECDSA_C) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 +#define PSA_WANT_ALG_ECDSA 1 + +// Only add in DETERMINISTIC support if ECDSA is also enabled +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#endif /* MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_ECP_C) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_HKDF_C) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define PSA_WANT_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1 +#define PSA_WANT_ALG_HKDF 1 +#endif /* MBEDTLS_HKDF_C */ + +#if defined(MBEDTLS_MD_C) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define PSA_WANT_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 +#define PSA_WANT_ALG_TLS12_PRF 1 +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 +#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_MD2_C) +#define MBEDTLS_PSA_BUILTIN_ALG_MD2 1 +#define PSA_WANT_ALG_MD2 1 +#endif + +#if defined(MBEDTLS_MD4_C) +#define MBEDTLS_PSA_BUILTIN_ALG_MD4 1 +#define PSA_WANT_ALG_MD4 1 +#endif + +#if defined(MBEDTLS_MD5_C) +#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 +#define PSA_WANT_ALG_MD5 1 +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 +#define PSA_WANT_ALG_RIPEMD160 1 +#endif + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PKCS1_V15) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 +#endif /* MBEDTLSS_PKCS1_V15 */ +#if defined(MBEDTLS_PKCS1_V21) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 +#define PSA_WANT_ALG_RSA_OAEP 1 +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 +#define PSA_WANT_ALG_RSA_PSS 1 +#endif /* MBEDTLS_PKCS1_V21 */ +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_SHA1_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 +#define PSA_WANT_ALG_SHA_1 1 +#endif + +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 +#define PSA_WANT_ALG_SHA_256 1 +#endif + +#if defined(MBEDTLS_SHA512_C) +#if !defined(MBEDTLS_SHA512_NO_SHA384) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 +#define PSA_WANT_ALG_SHA_384 1 +#endif +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 +#define PSA_WANT_ALG_SHA_512 1 +#endif + +#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CONFIG_PSA_H */ diff --git a/connectivity/mbedtls/include/mbedtls/ctr_drbg.h b/connectivity/mbedtls/include/mbedtls/ctr_drbg.h index 6c48ec1edd1..7f1d23253c8 100644 --- a/connectivity/mbedtls/include/mbedtls/ctr_drbg.h +++ b/connectivity/mbedtls/include/mbedtls/ctr_drbg.h @@ -210,6 +210,11 @@ mbedtls_ctr_drbg_context; * and prepares it for mbedtls_ctr_drbg_seed() * or mbedtls_ctr_drbg_free(). * + * \note The reseed interval is + * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default. + * You can override it by calling + * mbedtls_ctr_drbg_set_reseed_interval(). + * * \param ctx The CTR_DRBG context to initialize. */ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); @@ -309,7 +314,8 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, size_t len ); /** - * \brief This function clears CTR_CRBG context data. + * \brief This function resets CTR_DRBG context to the state immediately + * after initial call of mbedtls_ctr_drbg_init(). * * \param ctx The CTR_DRBG context to clear. */ diff --git a/connectivity/mbedtls/include/mbedtls/gcm.h b/connectivity/mbedtls/include/mbedtls/gcm.h index ed23cb9c6ca..6b673616f94 100644 --- a/connectivity/mbedtls/include/mbedtls/gcm.h +++ b/connectivity/mbedtls/include/mbedtls/gcm.h @@ -155,7 +155,7 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, * than zero, this must be a writable buffer of at least that * size in Bytes. * \param tag_len The length of the tag to generate. - * \param tag The buffer for holding the tag. This must be a readable + * \param tag The buffer for holding the tag. This must be a writable * buffer of at least \p tag_len Bytes. * * \return \c 0 if the encryption or decryption was performed @@ -283,7 +283,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx, * tag. The tag can have a maximum length of 16 Bytes. * * \param ctx The GCM context. This must be initialized. - * \param tag The buffer for holding the tag. This must be a readable + * \param tag The buffer for holding the tag. This must be a writable * buffer of at least \p tag_len Bytes. * \param tag_len The length of the tag to generate. This must be at least * four. diff --git a/connectivity/mbedtls/include/mbedtls/hmac_drbg.h b/connectivity/mbedtls/include/mbedtls/hmac_drbg.h index 57ce9d98f43..91165415fb4 100644 --- a/connectivity/mbedtls/include/mbedtls/hmac_drbg.h +++ b/connectivity/mbedtls/include/mbedtls/hmac_drbg.h @@ -111,6 +111,10 @@ typedef struct mbedtls_hmac_drbg_context * This function makes the context ready for mbedtls_hmac_drbg_seed(), * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). * + * \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL + * by default. Override this value by calling + * mbedtls_hmac_drbg_set_reseed_interval(). + * * \param ctx HMAC_DRBG context to be initialized. */ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); @@ -334,7 +338,8 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); /** - * \brief Free an HMAC_DRBG context + * \brief This function resets HMAC_DRBG context to the state immediately + * after initial call of mbedtls_hmac_drbg_init(). * * \param ctx The HMAC_DRBG context to free. */ diff --git a/connectivity/mbedtls/include/mbedtls/pk.h b/connectivity/mbedtls/include/mbedtls/pk.h index 22fab13bdac..7d0f977d5d2 100644 --- a/connectivity/mbedtls/include/mbedtls/pk.h +++ b/connectivity/mbedtls/include/mbedtls/pk.h @@ -331,12 +331,13 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); * * \return \c 0 on success. * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input - * (context already used, invalid key handle). + * (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. */ -int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key ); +int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, + const psa_key_id_t key ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) @@ -858,9 +859,9 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); * * \param pk Input: the EC key to import to a PSA key. * Output: a PK context wrapping that PSA key. - * \param handle Output: a PSA key handle. + * \param key Output: a PSA key identifier. * It's the caller's responsibility to call - * psa_destroy_key() on that handle after calling + * psa_destroy_key() on that key identifier after calling * mbedtls_pk_free() on the PK context. * \param hash_alg The hash algorithm to allow for use with that key. * @@ -868,7 +869,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); * \return An Mbed TLS error code otherwise. */ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, - psa_key_handle_t *handle, + psa_key_id_t *key, psa_algorithm_t hash_alg ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/connectivity/mbedtls/include/mbedtls/psa_util.h b/connectivity/mbedtls/include/mbedtls/psa_util.h index 3c037068ed6..d8a32c59e52 100644 --- a/connectivity/mbedtls/include/mbedtls/psa_util.h +++ b/connectivity/mbedtls/include/mbedtls/psa_util.h @@ -83,6 +83,8 @@ static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode( { switch( mode ) { + case MBEDTLS_MODE_ECB: + return( PSA_ALG_ECB_NO_PADDING ); case MBEDTLS_MODE_GCM: return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, taglen ) ); case MBEDTLS_MODE_CCM: diff --git a/connectivity/mbedtls/include/mbedtls/sha512.h b/connectivity/mbedtls/include/mbedtls/sha512.h index 9036ed49904..4a8ab425646 100644 --- a/connectivity/mbedtls/include/mbedtls/sha512.h +++ b/connectivity/mbedtls/include/mbedtls/sha512.h @@ -131,8 +131,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, /** * \brief This function finishes the SHA-512 operation, and writes - * the result to the output buffer. This function is for - * internal use only. + * the result to the output buffer. * * \param ctx The SHA-512 context. This must be initialized * and have a hash operation started. @@ -148,6 +147,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, /** * \brief This function processes a single data block within * the ongoing SHA-512 computation. + * This function is for internal use only. * * \param ctx The SHA-512 context. This must be initialized. * \param data The buffer holding one block of data. This diff --git a/connectivity/mbedtls/include/mbedtls/ssl.h b/connectivity/mbedtls/include/mbedtls/ssl.h index f086bdfdce3..7815ad9d093 100644 --- a/connectivity/mbedtls/include/mbedtls/ssl.h +++ b/connectivity/mbedtls/include/mbedtls/ssl.h @@ -42,7 +42,12 @@ #include "mbedtls/dhm.h" #endif -#if defined(MBEDTLS_ECDH_C) +/* Adding guard for MBEDTLS_ECDSA_C to ensure no compile errors due + * to guards also being in ssl_srv.c and ssl_cli.c. There is a gap + * in functionality that access to ecdh_ctx structure is needed for + * MBEDTLS_ECDSA_C which does not seem correct. + */ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #include "mbedtls/ecdh.h" #endif @@ -214,6 +219,9 @@ #define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 #define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 +#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0 +#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1 + /* * Default range for DTLS retransmission timer value, in milliseconds. * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. @@ -393,6 +401,8 @@ #define MBEDTLS_TLS_EXT_SIG_ALG 13 +#define MBEDTLS_TLS_EXT_USE_SRTP 14 + #define MBEDTLS_TLS_EXT_ALPN 16 #define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ @@ -851,6 +861,41 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + +#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255 +#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4 +/* + * For code readability use a typedef for DTLS-SRTP profiles + * + * Use_srtp extension protection profiles values as defined in + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + * + * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value + * must be updated too. + */ +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ( (uint16_t) 0x0001) +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ( (uint16_t) 0x0002) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ( (uint16_t) 0x0005) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ( (uint16_t) 0x0006) +/* This one is not iana defined, but for code readability. */ +#define MBEDTLS_TLS_SRTP_UNSET ( (uint16_t) 0x0000) + +typedef uint16_t mbedtls_ssl_srtp_profile; + +typedef struct mbedtls_dtls_srtp_info_t +{ + /*! The SRTP profile that was negotiated. */ + mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; + /*! The length of mki_value. */ + uint16_t mki_len; + /*! The mki_value used, with max size of 256 bytes. */ + unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH]; +} +mbedtls_dtls_srtp_info; + +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * This structure is used for storing current session data. * @@ -1023,11 +1068,12 @@ struct mbedtls_ssl_config #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_handle_t psk_opaque; /*!< PSA key slot holding opaque PSK. - * This field should only be set via - * mbedtls_ssl_conf_psk_opaque(). - * If either no PSK or a raw PSK have - * been configured, this has value \c 0. */ + psa_key_id_t psk_opaque; /*!< PSA key slot holding opaque PSK. This field + * should only be set via + * mbedtls_ssl_conf_psk_opaque(). + * If either no PSK or a raw PSK have been + * configured, this has value \c 0. + */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *psk; /*!< The raw pre-shared key. This field should @@ -1057,6 +1103,13 @@ struct mbedtls_ssl_config const char **alpn_list; /*!< ordered list of protocols */ #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /*! ordered list of supported srtp profile */ + const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list; + /*! number of supported profiles */ + size_t dtls_srtp_profile_list_len; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Numerical settings (int then char) */ @@ -1137,9 +1190,12 @@ struct mbedtls_ssl_config * record with unexpected CID * should lead to failure. */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + unsigned int dtls_srtp_mki_support : 1; /* support having mki_value + in the use_srtp extension */ +#endif }; - struct mbedtls_ssl_context { const mbedtls_ssl_config *conf; /*!< configuration information */ @@ -1298,6 +1354,13 @@ struct mbedtls_ssl_context const char *alpn_chosen; /*!< negotiated protocol */ #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /* + * use_srtp extension + */ + mbedtls_dtls_srtp_info dtls_srtp_info; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Information for DTLS hello verify */ @@ -1559,7 +1622,7 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, * \note For DTLS, you need to provide either a non-NULL * f_recv_timeout callback, or a f_recv that doesn't block. * - * \note See the documentations of \c mbedtls_ssl_sent_t, + * \note See the documentations of \c mbedtls_ssl_send_t, * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for * the conventions those callbacks must follow. * @@ -2032,6 +2095,8 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, * (Default: none.) * * \note See \c mbedtls_ssl_export_keys_ext_t. + * \warning Exported key material must not be used for any purpose + * before the (D)TLS handshake is completed * * \param conf SSL configuration context * \param f_export_keys_ext Callback for exporting keys @@ -2755,7 +2820,7 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. */ int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, - psa_key_handle_t psk, + psa_key_id_t psk, const unsigned char *psk_identity, size_t psk_identity_len ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -2801,7 +2866,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. */ int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl, - psa_key_handle_t psk ); + psa_key_id_t psk ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ /** @@ -3120,6 +3185,105 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#if defined(MBEDTLS_DEBUG_C) +static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile ) +{ + switch( profile ) + { + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" ); + default: break; + } + return( "" ); +} +#endif /* MBEDTLS_DEBUG_C */ +/** + * \brief Manage support for mki(master key id) value + * in use_srtp extension. + * MKI is an optional part of SRTP used for key management + * and re-keying. See RFC3711 section 3.1 for details. + * The default value is + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED. + * + * \param conf The SSL configuration to manage mki support. + * \param support_mki_value Enable or disable mki usage. Values are + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED + * or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED. + */ +void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, + int support_mki_value ); + +/** + * \brief Set the supported DTLS-SRTP protection profiles. + * + * \param conf SSL configuration + * \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated + * supported protection profiles + * in decreasing preference order. + * The pointer to the list is recorded by the library + * for later reference as required, so the lifetime + * of the table must be at least as long as the lifetime + * of the SSL configuration structure. + * The list must not hold more than + * MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements + * (excluding the terminating MBEDTLS_TLS_SRTP_UNSET). + * + * \return 0 on success + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of + * protection profiles is incorrect. + */ +int mbedtls_ssl_conf_dtls_srtp_protection_profiles + ( mbedtls_ssl_config *conf, + const mbedtls_ssl_srtp_profile *profiles ); + +/** + * \brief Set the mki_value for the current DTLS-SRTP session. + * + * \param ssl SSL context to use. + * \param mki_value The MKI value to set. + * \param mki_len The length of the MKI value. + * + * \note This function is relevant on client side only. + * The server discovers the mki value during handshake. + * A mki value set on server side using this function + * is ignored. + * + * \return 0 on success + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE + */ +int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, + unsigned char *mki_value, + uint16_t mki_len ); +/** + * \brief Get the negotiated DTLS-SRTP informations: + * Protection profile and MKI value. + * + * \warning This function must be called after the handshake is + * completed. The value returned by this function must + * not be trusted or acted upon before the handshake completes. + * + * \param ssl The SSL context to query. + * \param dtls_srtp_info The negotiated DTLS-SRTP informations: + * - Protection profile in use. + * A direct mapping of the iana defined value for protection + * profile on an uint16_t. + http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + * #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated + * or peer's Hello packet was not parsed yet. + * - mki size and value( if size is > 0 ). + */ +void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, + mbedtls_dtls_srtp_info *dtls_srtp_info ); +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /** * \brief Set the maximum supported version sent from the client side * and/or accepted at the server side diff --git a/connectivity/mbedtls/include/mbedtls/ssl_internal.h b/connectivity/mbedtls/include/mbedtls/ssl_internal.h index b3d53d34aef..577c959b657 100644 --- a/connectivity/mbedtls/include/mbedtls/ssl_internal.h +++ b/connectivity/mbedtls/include/mbedtls/ssl_internal.h @@ -378,6 +378,49 @@ typedef int mbedtls_ssl_tls_prf_cb( const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen ); + +/* cipher.h exports the maximum IV, key and block length from + * all ciphers enabled in the config, regardless of whether those + * ciphers are actually usable in SSL/TLS. Notably, XTS is enabled + * in the default configuration and uses 64 Byte keys, but it is + * not used for record protection in SSL/TLS. + * + * In order to prevent unnecessary inflation of key structures, + * we introduce SSL-specific variants of the max-{key,block,IV} + * macros here which are meant to only take those ciphers into + * account which can be negotiated in SSL/TLS. + * + * Since the current definitions of MBEDTLS_MAX_{KEY|BLOCK|IV}_LENGTH + * in cipher.h are rough overapproximations of the real maxima, here + * we content ourselves with replicating those overapproximations + * for the maximum block and IV length, and excluding XTS from the + * computation of the maximum key length. */ +#define MBEDTLS_SSL_MAX_BLOCK_LENGTH 16 +#define MBEDTLS_SSL_MAX_IV_LENGTH 16 +#define MBEDTLS_SSL_MAX_KEY_LENGTH 32 + +/** + * \brief The data structure holding the cryptographic material (key and IV) + * used for record protection in TLS 1.3. + */ +struct mbedtls_ssl_key_set +{ + /*! The key for client->server records. */ + unsigned char client_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ]; + /*! The key for server->client records. */ + unsigned char server_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ]; + /*! The IV for client->server records. */ + unsigned char client_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ]; + /*! The IV for server->client records. */ + unsigned char server_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ]; + + size_t key_len; /*!< The length of client_write_key and + * server_write_key, in Bytes. */ + size_t iv_len; /*!< The length of client_write_iv and + * server_write_iv, in Bytes. */ +}; +typedef struct mbedtls_ssl_key_set mbedtls_ssl_key_set; + /* * This structure contains the parameters only needed during handshake. */ @@ -394,17 +437,22 @@ struct mbedtls_ssl_handshake_params #if defined(MBEDTLS_DHM_C) mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ #endif -#if defined(MBEDTLS_ECDH_C) +/* Adding guard for MBEDTLS_ECDSA_C to ensure no compile errors due + * to guards also being in ssl_srv.c and ssl_cli.c. There is a gap + * in functionality that access to ecdh_ctx structure is needed for + * MBEDTLS_ECDSA_C which does not seem correct. + */ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ #if defined(MBEDTLS_USE_PSA_CRYPTO) psa_key_type_t ecdh_psa_type; uint16_t ecdh_bits; - psa_key_handle_t ecdh_psa_privkey; + psa_key_id_t ecdh_psa_privkey; unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; size_t ecdh_psa_peerkey_len; #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_ECDH_C */ +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ @@ -419,7 +467,7 @@ struct mbedtls_ssl_handshake_params #endif #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_handle_t psk_opaque; /*!< Opaque PSK from the callback */ + psa_key_id_t psk_opaque; /*!< Opaque PSK from the callback */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *psk; /*!< PSK from the callback */ size_t psk_len; /*!< Length of PSK from callback */ @@ -1018,16 +1066,16 @@ static inline int mbedtls_ssl_get_psk( const mbedtls_ssl_context *ssl, * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque() * Return an opaque PSK */ -static inline psa_key_handle_t mbedtls_ssl_get_opaque_psk( +static inline psa_key_id_t mbedtls_ssl_get_opaque_psk( const mbedtls_ssl_context *ssl ) { - if( ssl->handshake->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) ) return( ssl->handshake->psk_opaque ); - if( ssl->conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) ) return( ssl->conf->psk_opaque ); - return( 0 ); + return( MBEDTLS_SVC_KEY_ID_INIT ); } #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -1052,6 +1100,23 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ); #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value + ( const uint16_t srtp_profile_value ) +{ + switch( srtp_profile_value ) + { + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: + return srtp_profile_value; + default: break; + } + return( MBEDTLS_TLS_SRTP_UNSET ); +} +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) { diff --git a/connectivity/mbedtls/include/mbedtls/version.h b/connectivity/mbedtls/include/mbedtls/version.h index 665a283e15e..10c4316676c 100644 --- a/connectivity/mbedtls/include/mbedtls/version.h +++ b/connectivity/mbedtls/include/mbedtls/version.h @@ -37,7 +37,7 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 24 +#define MBEDTLS_VERSION_MINOR 25 #define MBEDTLS_VERSION_PATCH 0 /** @@ -45,9 +45,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02180000 -#define MBEDTLS_VERSION_STRING "2.24.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.24.0" +#define MBEDTLS_VERSION_NUMBER 0x02190000 +#define MBEDTLS_VERSION_STRING "2.25.0" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.25.0" #if defined(MBEDTLS_VERSION_C) diff --git a/connectivity/mbedtls/source/aes.c b/connectivity/mbedtls/source/aes.c index ed48b24d3b4..3f616427ace 100644 --- a/connectivity/mbedtls/source/aes.c +++ b/connectivity/mbedtls/source/aes.c @@ -730,6 +730,7 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, return( ret ); } +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ #if defined(MBEDTLS_CIPHER_MODE_XTS) static int mbedtls_aes_xts_decode_keys( const unsigned char *key, @@ -808,8 +809,6 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, } #endif /* MBEDTLS_CIPHER_MODE_XTS */ -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ - #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ do \ { \ @@ -867,63 +866,56 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, unsigned char output[16] ) { int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; + uint32_t *RK = ctx->rk; + struct + { + uint32_t X[4]; + uint32_t Y[4]; + } t; - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++; + GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++; + GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++; + GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++; for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) { - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); + AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] ); } - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); - mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); - mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); - mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); - - mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); - mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); - mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); - mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); - - mbedtls_platform_zeroize( &RK, sizeof( RK ) ); + AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); + + t.X[0] = *RK++ ^ \ + ( (uint32_t) FSb[ ( t.Y[0] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 ); + + t.X[1] = *RK++ ^ \ + ( (uint32_t) FSb[ ( t.Y[1] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 ); + + t.X[2] = *RK++ ^ \ + ( (uint32_t) FSb[ ( t.Y[2] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 ); + + t.X[3] = *RK++ ^ \ + ( (uint32_t) FSb[ ( t.Y[3] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( t.X[0], output, 0 ); + PUT_UINT32_LE( t.X[1], output, 4 ); + PUT_UINT32_LE( t.X[2], output, 8 ); + PUT_UINT32_LE( t.X[3], output, 12 ); + + mbedtls_platform_zeroize( &t, sizeof( t ) ); return( 0 ); } @@ -947,63 +939,56 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, unsigned char output[16] ) { int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; + uint32_t *RK = ctx->rk; + struct + { + uint32_t X[4]; + uint32_t Y[4]; + } t; - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++; + GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++; + GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++; + GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++; for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) { - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); + AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] ); } - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); - - mbedtls_platform_zeroize( &X0, sizeof( X0 ) ); - mbedtls_platform_zeroize( &X1, sizeof( X1 ) ); - mbedtls_platform_zeroize( &X2, sizeof( X2 ) ); - mbedtls_platform_zeroize( &X3, sizeof( X3 ) ); - - mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) ); - mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) ); - mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) ); - mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) ); - - mbedtls_platform_zeroize( &RK, sizeof( RK ) ); + AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] ); + + t.X[0] = *RK++ ^ \ + ( (uint32_t) RSb[ ( t.Y[0] ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 ); + + t.X[1] = *RK++ ^ \ + ( (uint32_t) RSb[ ( t.Y[1] ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 ); + + t.X[2] = *RK++ ^ \ + ( (uint32_t) RSb[ ( t.Y[2] ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 ); + + t.X[3] = *RK++ ^ \ + ( (uint32_t) RSb[ ( t.Y[3] ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( t.X[0], output, 0 ); + PUT_UINT32_LE( t.X[1], output, 4 ); + PUT_UINT32_LE( t.X[2], output, 8 ); + PUT_UINT32_LE( t.X[3], output, 12 ); + + mbedtls_platform_zeroize( &t, sizeof( t ) ); return( 0 ); } diff --git a/connectivity/mbedtls/source/bignum.c b/connectivity/mbedtls/source/bignum.c index 9325632b42c..9cc5d66e3ab 100644 --- a/connectivity/mbedtls/source/bignum.c +++ b/connectivity/mbedtls/source/bignum.c @@ -1411,7 +1411,10 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi /* If we ran out of space for the carry, it means that the result * is negative. */ if( n == X->n ) - return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); + { + ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; + goto cleanup; + } --X->p[n]; } @@ -2101,7 +2104,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, size_t i, j, nblimbs; size_t bufsize, nbits; mbedtls_mpi_uint ei, mm, state; - mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; + mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; int neg; MPI_VALIDATE_RET( X != NULL ); @@ -2115,6 +2118,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS || + mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS ) + return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + /* * Init temps and window size */ @@ -2391,7 +2398,7 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); Xp = (unsigned char*) X->p; - f_rng( p_rng, Xp + overhead, size ); + MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) ); mpi_bigendian_to_host( X->p, limbs ); diff --git a/connectivity/mbedtls/source/ccm.c b/connectivity/mbedtls/source/ccm.c index e6ca588babf..424ee77b698 100644 --- a/connectivity/mbedtls/source/ccm.c +++ b/connectivity/mbedtls/source/ccm.c @@ -175,7 +175,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, if( iv_len < 7 || iv_len > 13 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); - if( add_len > 0xFF00 ) + if( add_len >= 0xFF00 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); q = 16 - 1 - (unsigned char) iv_len; diff --git a/connectivity/mbedtls/source/check_crypto_config.h b/connectivity/mbedtls/source/check_crypto_config.h new file mode 100644 index 00000000000..cac90a0df23 --- /dev/null +++ b/connectivity/mbedtls/source/check_crypto_config.h @@ -0,0 +1,72 @@ +/** + * \file check_crypto_config.h + * + * \brief Consistency checks for PSA configuration options + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * It is recommended to include this file from your crypto_config.h + * in order to catch dependency issues early. + */ + +#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H +#define MBEDTLS_CHECK_CRYPTO_CONFIG_H + +#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ + !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_ALG_ECDSA) && \ + !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \ + !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \ + !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_ALG_RSA_OAEP) && \ + !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_ALG_RSA_PSS) && \ + !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) ) +#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites" +#endif + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \ + !defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) +#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR defined, but not all prerequisites" +#endif + +#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */ diff --git a/connectivity/mbedtls/source/cipher.c b/connectivity/mbedtls/source/cipher.c index 853eeec2030..457f8f66012 100644 --- a/connectivity/mbedtls/source/cipher.c +++ b/connectivity/mbedtls/source/cipher.c @@ -1288,23 +1288,16 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, #if defined(MBEDTLS_CIPHER_MODE_AEAD) /* - * Packet-oriented encryption for AEAD modes + * Packet-oriented encryption for AEAD modes: internal function shared by + * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext(). */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, +static int mbedtls_cipher_aead_encrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, unsigned char *tag, size_t tag_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - #if defined(MBEDTLS_USE_PSA_CRYPTO) if( ctx->psa_enabled == 1 ) { @@ -1320,7 +1313,7 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, /* PSA Crypto API always writes the authentication tag * at the end of the encrypted message. */ - if( tag != output + ilen ) + if( output == NULL || tag != output + ilen ) return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); status = psa_aead_encrypt( cipher_psa->slot, @@ -1370,44 +1363,21 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, ilen, iv, ad, ad_len, input, output, tag ) ); } #endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) - { - mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? - MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ - if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); - } -#endif /* MBEDTLS_NIST_KW_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } /* - * Packet-oriented decryption for AEAD modes + * Packet-oriented encryption for AEAD modes: internal function shared by + * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext(). */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, +static int mbedtls_cipher_aead_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, const unsigned char *tag, size_t tag_len ) { - CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); - CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); - CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); - CIPHER_VALIDATE_RET( olen != NULL ); - CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); - #if defined(MBEDTLS_USE_PSA_CRYPTO) if( ctx->psa_enabled == 1 ) { @@ -1423,7 +1393,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, /* PSA Crypto API always writes the authentication tag * at the end of the encrypted message. */ - if( tag != input + ilen ) + if( input == NULL || tag != input + ilen ) return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); status = psa_aead_decrypt( cipher_psa->slot, @@ -1495,25 +1465,169 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( ret ); } #endif /* MBEDTLS_CHACHAPOLY_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +/* + * Packet-oriented encryption for AEAD modes: public legacy function. + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + + return( mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len, + input, ilen, output, olen, + tag, tag_len ) ); +} + +/* + * Packet-oriented decryption for AEAD modes: public legacy function. + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); + + return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len, + input, ilen, output, olen, + tag, tag_len ) ); +} +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) +/* + * Packet-oriented encryption for AEAD/NIST_KW: public function. + */ +int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + #if defined(MBEDTLS_NIST_KW_C) - if( MBEDTLS_MODE_KW == ctx->cipher_info->mode || - MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) + if( +#if defined(MBEDTLS_USE_PSA_CRYPTO) + ctx->psa_enabled == 0 && +#endif + ( MBEDTLS_MODE_KW == ctx->cipher_info->mode || + MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) ) { mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; - /* There is no iv, tag or ad associated with KW and KWP, these length should be 0 */ + /* There is no iv, tag or ad associated with KW and KWP, + * so these length should be 0 as documented. */ if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) - { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, output, olen, SIZE_MAX ) ); + (void) iv; + (void) ad; + + return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen, + output, olen, output_len ) ); } #endif /* MBEDTLS_NIST_KW_C */ +#if defined(MBEDTLS_CIPHER_MODE_AEAD) + /* AEAD case: check length before passing on to shared function */ + if( output_len < ilen + tag_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + int ret = mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len, + input, ilen, output, olen, + output + ilen, tag_len ); + *olen += tag_len; + return( ret ); +#else return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ } + +/* + * Packet-oriented decryption for AEAD/NIST_KW: public function. + */ +int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ) +{ + CIPHER_VALIDATE_RET( ctx != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); + CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); + CIPHER_VALIDATE_RET( output_len == 0 || output != NULL ); + CIPHER_VALIDATE_RET( olen != NULL ); + +#if defined(MBEDTLS_NIST_KW_C) + if( +#if defined(MBEDTLS_USE_PSA_CRYPTO) + ctx->psa_enabled == 0 && +#endif + ( MBEDTLS_MODE_KW == ctx->cipher_info->mode || + MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) ) + { + mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ? + MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; + + /* There is no iv, tag or ad associated with KW and KWP, + * so these length should be 0 as documented. */ + if( iv_len != 0 || tag_len != 0 || ad_len != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + (void) iv; + (void) ad; + + return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen, + output, olen, output_len ) ); + } +#endif /* MBEDTLS_NIST_KW_C */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) + /* AEAD case: check length before passing on to shared function */ + if( ilen < tag_len || output_len < ilen - tag_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len, + input, ilen - tag_len, output, olen, + input + ilen - tag_len, tag_len ) ); +#else + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); #endif /* MBEDTLS_CIPHER_MODE_AEAD */ +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ #endif /* MBEDTLS_CIPHER_C */ diff --git a/connectivity/mbedtls/source/cipher_wrap.c b/connectivity/mbedtls/source/cipher_wrap.c index 8eb2ec02b81..57eb3cb67fb 100644 --- a/connectivity/mbedtls/source/cipher_wrap.c +++ b/connectivity/mbedtls/source/cipher_wrap.c @@ -753,7 +753,7 @@ static const mbedtls_cipher_info_t camellia_128_ecb_info = { MBEDTLS_MODE_ECB, 128, "CAMELLIA-128-ECB", - 16, + 0, 0, 16, &camellia_info @@ -764,7 +764,7 @@ static const mbedtls_cipher_info_t camellia_192_ecb_info = { MBEDTLS_MODE_ECB, 192, "CAMELLIA-192-ECB", - 16, + 0, 0, 16, &camellia_info @@ -775,7 +775,7 @@ static const mbedtls_cipher_info_t camellia_256_ecb_info = { MBEDTLS_MODE_ECB, 256, "CAMELLIA-256-ECB", - 16, + 0, 0, 16, &camellia_info @@ -1129,7 +1129,7 @@ static const mbedtls_cipher_info_t aria_128_ecb_info = { MBEDTLS_MODE_ECB, 128, "ARIA-128-ECB", - 16, + 0, 0, 16, &aria_info @@ -1140,7 +1140,7 @@ static const mbedtls_cipher_info_t aria_192_ecb_info = { MBEDTLS_MODE_ECB, 192, "ARIA-192-ECB", - 16, + 0, 0, 16, &aria_info @@ -1151,7 +1151,7 @@ static const mbedtls_cipher_info_t aria_256_ecb_info = { MBEDTLS_MODE_ECB, 256, "ARIA-256-ECB", - 16, + 0, 0, 16, &aria_info @@ -1553,7 +1553,7 @@ static const mbedtls_cipher_info_t des_ecb_info = { MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES, "DES-ECB", - 8, + 0, 0, 8, &des_info @@ -1604,7 +1604,7 @@ static const mbedtls_cipher_info_t des_ede_ecb_info = { MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES_EDE, "DES-EDE-ECB", - 8, + 0, 0, 8, &des_ede_info @@ -1655,7 +1655,7 @@ static const mbedtls_cipher_info_t des_ede3_ecb_info = { MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES_EDE3, "DES-EDE3-ECB", - 8, + 0, 0, 8, &des_ede3_info @@ -1770,7 +1770,7 @@ static const mbedtls_cipher_info_t blowfish_ecb_info = { MBEDTLS_MODE_ECB, 128, "BLOWFISH-ECB", - 8, + 0, MBEDTLS_CIPHER_VARIABLE_KEY_LEN, 8, &blowfish_info diff --git a/connectivity/mbedtls/source/cmac.c b/connectivity/mbedtls/source/cmac.c index 816bf13da38..59ece155eeb 100644 --- a/connectivity/mbedtls/source/cmac.c +++ b/connectivity/mbedtls/source/cmac.c @@ -420,7 +420,7 @@ int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, */ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, const unsigned char *input, size_t in_len, - unsigned char *output ) + unsigned char output[16] ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_cipher_info_t *cipher_info; diff --git a/connectivity/mbedtls/source/ctr_drbg.c b/connectivity/mbedtls/source/ctr_drbg.c index 54843a7be6b..023aac51a3c 100644 --- a/connectivity/mbedtls/source/ctr_drbg.c +++ b/connectivity/mbedtls/source/ctr_drbg.c @@ -55,11 +55,17 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) * See mbedtls_ctr_drbg_set_nonce_len(). */ ctx->reseed_counter = -1; + ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; + #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &ctx->mutex ); #endif } +/* + * This function resets CTR_DRBG context to the state immediately + * after initial call of mbedtls_ctr_drbg_init(). + */ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) { if( ctx == NULL ) @@ -70,6 +76,11 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) #endif mbedtls_aes_free( &ctx->aes_ctx ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); + ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; + ctx->reseed_counter = -1; +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif } void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, @@ -468,8 +479,6 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, (size_t) ctx->reseed_counter : good_nonce_len( ctx->entropy_len ) ); - ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; - /* Initialize with an empty key. */ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 ) diff --git a/connectivity/mbedtls/source/ecp.c b/connectivity/mbedtls/source/ecp.c index 5d00de5cf97..05a0b0175c0 100644 --- a/connectivity/mbedtls/source/ecp.c +++ b/connectivity/mbedtls/source/ecp.c @@ -546,8 +546,11 @@ static const mbedtls_ecp_curve_info ecp_supported_curves[] = #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, #endif -#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" }, +#endif +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" }, #endif { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, }; diff --git a/connectivity/mbedtls/source/ecp_curves.c b/connectivity/mbedtls/source/ecp_curves.c index 05df307cbe3..839fb5e36e9 100644 --- a/connectivity/mbedtls/source/ecp_curves.c +++ b/connectivity/mbedtls/source/ecp_curves.c @@ -1033,7 +1033,7 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) STORE32; i++; \ cur = c > 0 ? c : 0; STORE32; \ cur = 0; while( ++i < MAX32 ) { STORE32; } \ - if( c < 0 ) fix_negative( N, c, &C, bits ); + if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) ); /* * If the result is negative, we get it in the form diff --git a/connectivity/mbedtls/source/entropy_poll.c b/connectivity/mbedtls/source/entropy_poll.c index 4bf660e055a..5250a7bfec9 100644 --- a/connectivity/mbedtls/source/entropy_poll.c +++ b/connectivity/mbedtls/source/entropy_poll.c @@ -17,7 +17,7 @@ * limitations under the License. */ -#if defined(__linux__) +#if defined(__linux__) && !defined(_GNU_SOURCE) /* Ensure that syscall() is available even when compiling with -std=c99 */ #define _GNU_SOURCE #endif diff --git a/connectivity/mbedtls/source/error.c b/connectivity/mbedtls/source/error.c index cba61e9e7e9..901a3699ae6 100644 --- a/connectivity/mbedtls/source/error.c +++ b/connectivity/mbedtls/source/error.c @@ -19,20 +19,20 @@ #include "common.h" -#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) -#include -#endif +#include "mbedtls/error.h" + +#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) + +#if defined(MBEDTLS_ERROR_C) #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #define mbedtls_snprintf snprintf -#define mbedtls_time_t time_t #endif -#if defined(MBEDTLS_ERROR_C) - #include +#include #if defined(MBEDTLS_AES_C) #include "mbedtls/aes.h" @@ -960,8 +960,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) #else /* MBEDTLS_ERROR_C */ -#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) - /* * Provide an non-function in case MBEDTLS_ERROR_C is not defined */ @@ -973,6 +971,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) buf[0] = '\0'; } -#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ - #endif /* MBEDTLS_ERROR_C */ + +#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */ diff --git a/connectivity/mbedtls/source/hmac_drbg.c b/connectivity/mbedtls/source/hmac_drbg.c index aa3e2510406..25a02258350 100644 --- a/connectivity/mbedtls/source/hmac_drbg.c +++ b/connectivity/mbedtls/source/hmac_drbg.c @@ -53,6 +53,8 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) { memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); + ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; + #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &ctx->mutex ); #endif @@ -266,8 +268,6 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, ctx->f_entropy = f_entropy; ctx->p_entropy = p_entropy; - ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; - if( ctx->entropy_len == 0 ) { /* @@ -412,7 +412,8 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len } /* - * Free an HMAC_DRBG context + * This function resets HMAC_DRBG context to the state immediately + * after initial call of mbedtls_hmac_drbg_init(). */ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) { @@ -424,6 +425,10 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) #endif mbedtls_md_free( &ctx->md_ctx ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); + ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif } #if defined(MBEDTLS_FS_IO) diff --git a/connectivity/mbedtls/source/md2.c b/connectivity/mbedtls/source/md2.c index 5ebf07232ac..7264e303130 100644 --- a/connectivity/mbedtls/source/md2.c +++ b/connectivity/mbedtls/source/md2.c @@ -147,6 +147,9 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) t = ctx->cksum[i]; } + /* Zeroise variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &t, sizeof( t ) ); + return( 0 ); } @@ -287,8 +290,7 @@ static const unsigned char md2_test_str[7][81] = { "message digest" }, { "abcdefghijklmnopqrstuvwxyz" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" } }; static const size_t md2_test_strlen[7] = diff --git a/connectivity/mbedtls/source/md4.c b/connectivity/mbedtls/source/md4.c index ac9507454b0..4fd6bc3e459 100644 --- a/connectivity/mbedtls/source/md4.c +++ b/connectivity/mbedtls/source/md4.c @@ -113,31 +113,34 @@ void mbedtls_md4_starts( mbedtls_md4_context *ctx ) int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] ) { - uint32_t X[16], A, B, C, D; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); + struct + { + uint32_t X[16], A, B, C, D; + } local; + + GET_UINT32_LE( local.X[ 0], data, 0 ); + GET_UINT32_LE( local.X[ 1], data, 4 ); + GET_UINT32_LE( local.X[ 2], data, 8 ); + GET_UINT32_LE( local.X[ 3], data, 12 ); + GET_UINT32_LE( local.X[ 4], data, 16 ); + GET_UINT32_LE( local.X[ 5], data, 20 ); + GET_UINT32_LE( local.X[ 6], data, 24 ); + GET_UINT32_LE( local.X[ 7], data, 28 ); + GET_UINT32_LE( local.X[ 8], data, 32 ); + GET_UINT32_LE( local.X[ 9], data, 36 ); + GET_UINT32_LE( local.X[10], data, 40 ); + GET_UINT32_LE( local.X[11], data, 44 ); + GET_UINT32_LE( local.X[12], data, 48 ); + GET_UINT32_LE( local.X[13], data, 52 ); + GET_UINT32_LE( local.X[14], data, 56 ); + GET_UINT32_LE( local.X[15], data, 60 ); #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; + local.A = ctx->state[0]; + local.B = ctx->state[1]; + local.C = ctx->state[2]; + local.D = ctx->state[3]; #define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) #define P(a,b,c,d,x,s) \ @@ -148,22 +151,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, } while( 0 ) - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); + P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 1], 7 ); + P( local.C, local.D, local.A, local.B, local.X[ 2], 11 ); + P( local.B, local.C, local.D, local.A, local.X[ 3], 19 ); + P( local.A, local.B, local.C, local.D, local.X[ 4], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 5], 7 ); + P( local.C, local.D, local.A, local.B, local.X[ 6], 11 ); + P( local.B, local.C, local.D, local.A, local.X[ 7], 19 ); + P( local.A, local.B, local.C, local.D, local.X[ 8], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 9], 7 ); + P( local.C, local.D, local.A, local.B, local.X[10], 11 ); + P( local.B, local.C, local.D, local.A, local.X[11], 19 ); + P( local.A, local.B, local.C, local.D, local.X[12], 3 ); + P( local.D, local.A, local.B, local.C, local.X[13], 7 ); + P( local.C, local.D, local.A, local.B, local.X[14], 11 ); + P( local.B, local.C, local.D, local.A, local.X[15], 19 ); #undef P #undef F @@ -176,22 +179,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, (a) = S((a),(s)); \ } while( 0 ) - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); + P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 4], 5 ); + P( local.C, local.D, local.A, local.B, local.X[ 8], 9 ); + P( local.B, local.C, local.D, local.A, local.X[12], 13 ); + P( local.A, local.B, local.C, local.D, local.X[ 1], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 5], 5 ); + P( local.C, local.D, local.A, local.B, local.X[ 9], 9 ); + P( local.B, local.C, local.D, local.A, local.X[13], 13 ); + P( local.A, local.B, local.C, local.D, local.X[ 2], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 6], 5 ); + P( local.C, local.D, local.A, local.B, local.X[10], 9 ); + P( local.B, local.C, local.D, local.A, local.X[14], 13 ); + P( local.A, local.B, local.C, local.D, local.X[ 3], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 7], 5 ); + P( local.C, local.D, local.A, local.B, local.X[11], 9 ); + P( local.B, local.C, local.D, local.A, local.X[15], 13 ); #undef P #undef F @@ -204,30 +207,33 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, (a) = S((a),(s)); \ } while( 0 ) - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); + P( local.A, local.B, local.C, local.D, local.X[ 0], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 8], 9 ); + P( local.C, local.D, local.A, local.B, local.X[ 4], 11 ); + P( local.B, local.C, local.D, local.A, local.X[12], 15 ); + P( local.A, local.B, local.C, local.D, local.X[ 2], 3 ); + P( local.D, local.A, local.B, local.C, local.X[10], 9 ); + P( local.C, local.D, local.A, local.B, local.X[ 6], 11 ); + P( local.B, local.C, local.D, local.A, local.X[14], 15 ); + P( local.A, local.B, local.C, local.D, local.X[ 1], 3 ); + P( local.D, local.A, local.B, local.C, local.X[ 9], 9 ); + P( local.C, local.D, local.A, local.B, local.X[ 5], 11 ); + P( local.B, local.C, local.D, local.A, local.X[13], 15 ); + P( local.A, local.B, local.C, local.D, local.X[ 3], 3 ); + P( local.D, local.A, local.B, local.C, local.X[11], 9 ); + P( local.C, local.D, local.A, local.B, local.X[ 7], 11 ); + P( local.B, local.C, local.D, local.A, local.X[15], 15 ); #undef F #undef P - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; + ctx->state[0] += local.A; + ctx->state[1] += local.B; + ctx->state[2] += local.C; + ctx->state[3] += local.D; + + /* Zeroise variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } @@ -408,8 +414,7 @@ static const unsigned char md4_test_str[7][81] = { "message digest" }, { "abcdefghijklmnopqrstuvwxyz" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" } }; static const size_t md4_test_strlen[7] = diff --git a/connectivity/mbedtls/source/md5.c b/connectivity/mbedtls/source/md5.c index 8cea902aea4..c4f2dbfac8f 100644 --- a/connectivity/mbedtls/source/md5.c +++ b/connectivity/mbedtls/source/md5.c @@ -112,128 +112,134 @@ void mbedtls_md5_starts( mbedtls_md5_context *ctx ) int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) { - uint32_t X[16], A, B, C, D; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); + struct + { + uint32_t X[16], A, B, C, D; + } local; + + GET_UINT32_LE( local.X[ 0], data, 0 ); + GET_UINT32_LE( local.X[ 1], data, 4 ); + GET_UINT32_LE( local.X[ 2], data, 8 ); + GET_UINT32_LE( local.X[ 3], data, 12 ); + GET_UINT32_LE( local.X[ 4], data, 16 ); + GET_UINT32_LE( local.X[ 5], data, 20 ); + GET_UINT32_LE( local.X[ 6], data, 24 ); + GET_UINT32_LE( local.X[ 7], data, 28 ); + GET_UINT32_LE( local.X[ 8], data, 32 ); + GET_UINT32_LE( local.X[ 9], data, 36 ); + GET_UINT32_LE( local.X[10], data, 40 ); + GET_UINT32_LE( local.X[11], data, 44 ); + GET_UINT32_LE( local.X[12], data, 48 ); + GET_UINT32_LE( local.X[13], data, 52 ); + GET_UINT32_LE( local.X[14], data, 56 ); + GET_UINT32_LE( local.X[15], data, 60 ); #define S(x,n) \ ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) -#define P(a,b,c,d,k,s,t) \ - do \ - { \ - (a) += F((b),(c),(d)) + X[(k)] + (t); \ - (a) = S((a),(s)) + (b); \ +#define P(a,b,c,d,k,s,t) \ + do \ + { \ + (a) += F((b),(c),(d)) + local.X[(k)] + (t); \ + (a) = S((a),(s)) + (b); \ } while( 0 ) - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; + local.A = ctx->state[0]; + local.B = ctx->state[1]; + local.C = ctx->state[2]; + local.D = ctx->state[3]; #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); + P( local.A, local.B, local.C, local.D, 0, 7, 0xD76AA478 ); + P( local.D, local.A, local.B, local.C, 1, 12, 0xE8C7B756 ); + P( local.C, local.D, local.A, local.B, 2, 17, 0x242070DB ); + P( local.B, local.C, local.D, local.A, 3, 22, 0xC1BDCEEE ); + P( local.A, local.B, local.C, local.D, 4, 7, 0xF57C0FAF ); + P( local.D, local.A, local.B, local.C, 5, 12, 0x4787C62A ); + P( local.C, local.D, local.A, local.B, 6, 17, 0xA8304613 ); + P( local.B, local.C, local.D, local.A, 7, 22, 0xFD469501 ); + P( local.A, local.B, local.C, local.D, 8, 7, 0x698098D8 ); + P( local.D, local.A, local.B, local.C, 9, 12, 0x8B44F7AF ); + P( local.C, local.D, local.A, local.B, 10, 17, 0xFFFF5BB1 ); + P( local.B, local.C, local.D, local.A, 11, 22, 0x895CD7BE ); + P( local.A, local.B, local.C, local.D, 12, 7, 0x6B901122 ); + P( local.D, local.A, local.B, local.C, 13, 12, 0xFD987193 ); + P( local.C, local.D, local.A, local.B, 14, 17, 0xA679438E ); + P( local.B, local.C, local.D, local.A, 15, 22, 0x49B40821 ); #undef F #define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + P( local.A, local.B, local.C, local.D, 1, 5, 0xF61E2562 ); + P( local.D, local.A, local.B, local.C, 6, 9, 0xC040B340 ); + P( local.C, local.D, local.A, local.B, 11, 14, 0x265E5A51 ); + P( local.B, local.C, local.D, local.A, 0, 20, 0xE9B6C7AA ); + P( local.A, local.B, local.C, local.D, 5, 5, 0xD62F105D ); + P( local.D, local.A, local.B, local.C, 10, 9, 0x02441453 ); + P( local.C, local.D, local.A, local.B, 15, 14, 0xD8A1E681 ); + P( local.B, local.C, local.D, local.A, 4, 20, 0xE7D3FBC8 ); + P( local.A, local.B, local.C, local.D, 9, 5, 0x21E1CDE6 ); + P( local.D, local.A, local.B, local.C, 14, 9, 0xC33707D6 ); + P( local.C, local.D, local.A, local.B, 3, 14, 0xF4D50D87 ); + P( local.B, local.C, local.D, local.A, 8, 20, 0x455A14ED ); + P( local.A, local.B, local.C, local.D, 13, 5, 0xA9E3E905 ); + P( local.D, local.A, local.B, local.C, 2, 9, 0xFCEFA3F8 ); + P( local.C, local.D, local.A, local.B, 7, 14, 0x676F02D9 ); + P( local.B, local.C, local.D, local.A, 12, 20, 0x8D2A4C8A ); #undef F #define F(x,y,z) ((x) ^ (y) ^ (z)) - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); + P( local.A, local.B, local.C, local.D, 5, 4, 0xFFFA3942 ); + P( local.D, local.A, local.B, local.C, 8, 11, 0x8771F681 ); + P( local.C, local.D, local.A, local.B, 11, 16, 0x6D9D6122 ); + P( local.B, local.C, local.D, local.A, 14, 23, 0xFDE5380C ); + P( local.A, local.B, local.C, local.D, 1, 4, 0xA4BEEA44 ); + P( local.D, local.A, local.B, local.C, 4, 11, 0x4BDECFA9 ); + P( local.C, local.D, local.A, local.B, 7, 16, 0xF6BB4B60 ); + P( local.B, local.C, local.D, local.A, 10, 23, 0xBEBFBC70 ); + P( local.A, local.B, local.C, local.D, 13, 4, 0x289B7EC6 ); + P( local.D, local.A, local.B, local.C, 0, 11, 0xEAA127FA ); + P( local.C, local.D, local.A, local.B, 3, 16, 0xD4EF3085 ); + P( local.B, local.C, local.D, local.A, 6, 23, 0x04881D05 ); + P( local.A, local.B, local.C, local.D, 9, 4, 0xD9D4D039 ); + P( local.D, local.A, local.B, local.C, 12, 11, 0xE6DB99E5 ); + P( local.C, local.D, local.A, local.B, 15, 16, 0x1FA27CF8 ); + P( local.B, local.C, local.D, local.A, 2, 23, 0xC4AC5665 ); #undef F #define F(x,y,z) ((y) ^ ((x) | ~(z))) - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); + P( local.A, local.B, local.C, local.D, 0, 6, 0xF4292244 ); + P( local.D, local.A, local.B, local.C, 7, 10, 0x432AFF97 ); + P( local.C, local.D, local.A, local.B, 14, 15, 0xAB9423A7 ); + P( local.B, local.C, local.D, local.A, 5, 21, 0xFC93A039 ); + P( local.A, local.B, local.C, local.D, 12, 6, 0x655B59C3 ); + P( local.D, local.A, local.B, local.C, 3, 10, 0x8F0CCC92 ); + P( local.C, local.D, local.A, local.B, 10, 15, 0xFFEFF47D ); + P( local.B, local.C, local.D, local.A, 1, 21, 0x85845DD1 ); + P( local.A, local.B, local.C, local.D, 8, 6, 0x6FA87E4F ); + P( local.D, local.A, local.B, local.C, 15, 10, 0xFE2CE6E0 ); + P( local.C, local.D, local.A, local.B, 6, 15, 0xA3014314 ); + P( local.B, local.C, local.D, local.A, 13, 21, 0x4E0811A1 ); + P( local.A, local.B, local.C, local.D, 4, 6, 0xF7537E82 ); + P( local.D, local.A, local.B, local.C, 11, 10, 0xBD3AF235 ); + P( local.C, local.D, local.A, local.B, 2, 15, 0x2AD7D2BB ); + P( local.B, local.C, local.D, local.A, 9, 21, 0xEB86D391 ); #undef F - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; + ctx->state[0] += local.A; + ctx->state[1] += local.B; + ctx->state[2] += local.C; + ctx->state[3] += local.D; + + /* Zeroise variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } @@ -422,8 +428,7 @@ static const unsigned char md5_test_buf[7][81] = { "message digest" }, { "abcdefghijklmnopqrstuvwxyz" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" } + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" } }; static const size_t md5_test_buflen[7] = diff --git a/connectivity/mbedtls/source/net_sockets.c b/connectivity/mbedtls/source/net_sockets.c index 3f96cabe46b..54c2b472f23 100644 --- a/connectivity/mbedtls/source/net_sockets.c +++ b/connectivity/mbedtls/source/net_sockets.c @@ -318,7 +318,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) || \ - defined(socklen_t) + defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); #else diff --git a/connectivity/mbedtls/source/pem.c b/connectivity/mbedtls/source/pem.c index 534d071b32b..969d492e3b6 100644 --- a/connectivity/mbedtls/source/pem.c +++ b/connectivity/mbedtls/source/pem.c @@ -478,8 +478,12 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, *p++ = '\0'; *olen = p - buf; + /* Clean any remaining data previously written to the buffer */ + memset( buf + *olen, 0, buf_len - *olen ); + mbedtls_free( encode_buf ); return( 0 ); } #endif /* MBEDTLS_PEM_WRITE_C */ #endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ + diff --git a/connectivity/mbedtls/source/pk.c b/connectivity/mbedtls/source/pk.c index 8ffbed2a9af..ecf002d452c 100644 --- a/connectivity/mbedtls/source/pk.c +++ b/connectivity/mbedtls/source/pk.c @@ -150,11 +150,12 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) /* * Initialise a PSA-wrapping context */ -int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key ) +int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, + const psa_key_id_t key ) { const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_handle_t *pk_ctx; + psa_key_id_t *pk_ctx; psa_key_type_t type; if( ctx == NULL || ctx->pk_info != NULL ) @@ -174,7 +175,7 @@ int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key ctx->pk_info = info; - pk_ctx = (psa_key_handle_t *) ctx->pk_ctx; + pk_ctx = (psa_key_id_t *) ctx->pk_ctx; *pk_ctx = key; return( 0 ); @@ -587,10 +588,13 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) * Currently only works for EC private keys. */ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, - psa_key_handle_t *handle, + psa_key_id_t *key, psa_algorithm_t hash_alg ) { #if !defined(MBEDTLS_ECP_C) + ((void) pk); + ((void) key); + ((void) hash_alg); return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); #else const mbedtls_ecp_keypair *ec; @@ -621,14 +625,14 @@ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) ); /* import private key into PSA */ - if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, handle ) ) + if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, key ) ) return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); /* make PK context wrap the key slot */ mbedtls_pk_free( pk ); mbedtls_pk_init( pk ); - return( mbedtls_pk_setup_opaque( pk, *handle ) ); + return( mbedtls_pk_setup_opaque( pk, *key ) ); #endif /* MBEDTLS_ECP_C */ } #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/connectivity/mbedtls/source/pk_wrap.c b/connectivity/mbedtls/source/pk_wrap.c index 6bf3169743b..107e912acee 100644 --- a/connectivity/mbedtls/source/pk_wrap.c +++ b/connectivity/mbedtls/source/pk_wrap.c @@ -543,7 +543,7 @@ static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, mbedtls_ecdsa_context *ctx = ctx_arg; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_handle_t key_handle = 0; + psa_key_id_t key_id = 0; psa_status_t status; mbedtls_pk_context key; int key_len; @@ -551,11 +551,12 @@ static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES]; unsigned char *p; mbedtls_pk_info_t pk_info = mbedtls_eckey_info; - psa_algorithm_t psa_sig_md, psa_md; + psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; size_t curve_bits; psa_ecc_family_t curve = mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits ); const size_t signature_part_size = ( ctx->grp.nbits + 7 ) / 8; + ((void) md_alg); if( curve == 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); @@ -569,18 +570,13 @@ static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, if( key_len <= 0 ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - psa_md = mbedtls_psa_translate_md( md_alg ); - if( psa_md == 0 ) - return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); - psa_sig_md = PSA_ALG_ECDSA( psa_md ); - psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH ); psa_set_key_algorithm( &attributes, psa_sig_md ); status = psa_import_key( &attributes, buf + sizeof( buf ) - key_len, key_len, - &key_handle ); + &key_id ); if( status != PSA_SUCCESS ) { ret = mbedtls_psa_err_translate_pk( status ); @@ -602,7 +598,7 @@ static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, goto cleanup; } - if( psa_verify_hash( key_handle, psa_sig_md, + if( psa_verify_hash( key_id, psa_sig_md, hash, hash_len, buf, 2 * signature_part_size ) != PSA_SUCCESS ) @@ -619,7 +615,7 @@ static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg, ret = 0; cleanup: - psa_destroy_key( key_handle ); + psa_destroy_key( key_id ); return( ret ); } #else /* MBEDTLS_USE_PSA_CRYPTO */ @@ -874,7 +870,7 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = { static void *pk_opaque_alloc_wrap( void ) { - void *ctx = mbedtls_calloc( 1, sizeof( psa_key_handle_t ) ); + void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) ); /* no _init() function to call, an calloc() already zeroized */ @@ -883,13 +879,13 @@ static void *pk_opaque_alloc_wrap( void ) static void pk_opaque_free_wrap( void *ctx ) { - mbedtls_platform_zeroize( ctx, sizeof( psa_key_handle_t ) ); + mbedtls_platform_zeroize( ctx, sizeof( psa_key_id_t ) ); mbedtls_free( ctx ); } static size_t pk_opaque_get_bitlen( const void *ctx ) { - const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; + const psa_key_id_t *key = (const psa_key_id_t *) ctx; size_t bits; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -910,6 +906,8 @@ static int pk_opaque_can_do( mbedtls_pk_type_t type ) type == MBEDTLS_PK_ECDSA ); } +#if defined(MBEDTLS_ECDSA_C) + /* * Simultaneously convert and move raw MPI from the beginning of a buffer * to an ASN.1 MPI at the end of the buffer. @@ -992,12 +990,25 @@ static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len, return( 0 ); } +#endif /* MBEDTLS_ECDSA_C */ + static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - const psa_key_handle_t *key = (const psa_key_handle_t *) ctx; +#if !defined(MBEDTLS_ECDSA_C) + ((void) ctx); + ((void) md_alg); + ((void) hash); + ((void) hash_len); + ((void) sig); + ((void) sig_len); + ((void) f_rng); + ((void) p_rng); + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); +#else /* !MBEDTLS_ECDSA_C */ + const psa_key_id_t *key = (const psa_key_id_t *) ctx; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) ); size_t buf_len; @@ -1027,6 +1038,7 @@ static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, /* transcode it to ASN.1 sequence */ return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) ); +#endif /* !MBEDTLS_ECDSA_C */ } const mbedtls_pk_info_t mbedtls_pk_opaque_info = { diff --git a/connectivity/mbedtls/source/pkcs5.c b/connectivity/mbedtls/source/pkcs5.c index f89cc643c38..e9e743fa90e 100644 --- a/connectivity/mbedtls/source/pkcs5.c +++ b/connectivity/mbedtls/source/pkcs5.c @@ -221,7 +221,8 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, unsigned int iteration_count, uint32_t key_length, unsigned char *output ) { - int ret, j; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int j; unsigned int i; unsigned char md1[MBEDTLS_MD_MAX_SIZE]; unsigned char work[MBEDTLS_MD_MAX_SIZE]; @@ -245,16 +246,16 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, // U1 ends up in work // if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 ) - return( ret ); + goto cleanup; memcpy( md1, work, md_size ); @@ -263,13 +264,13 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, // U2 ends up in md1 // if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) - return( ret ); + goto cleanup; if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 ) - return( ret ); + goto cleanup; // U1 xor U2 // @@ -288,7 +289,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, break; } - return( 0 ); +cleanup: + /* Zeroise buffers to clear sensitive data from memory. */ + mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE ); + mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE ); + + return( ret ); } #if defined(MBEDTLS_SELF_TEST) diff --git a/connectivity/mbedtls/source/pkparse.c b/connectivity/mbedtls/source/pkparse.c index a106dbe3edb..0590f2b0501 100644 --- a/connectivity/mbedtls/source/pkparse.c +++ b/connectivity/mbedtls/source/pkparse.c @@ -662,7 +662,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; if( ret == 0 && *p != end ) - ret = MBEDTLS_ERR_PK_INVALID_PUBKEY + ret = MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; if( ret != 0 ) diff --git a/connectivity/mbedtls/source/pkwrite.c b/connectivity/mbedtls/source/pkwrite.c index b317ccf223a..0da3698189e 100644 --- a/connectivity/mbedtls/source/pkwrite.c +++ b/connectivity/mbedtls/source/pkwrite.c @@ -198,13 +198,13 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE ) { size_t buffer_size; - psa_key_handle_t* key_slot = (psa_key_handle_t*) key->pk_ctx; + psa_key_id_t* key_id = (psa_key_id_t*) key->pk_ctx; if ( *p < start ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); buffer_size = (size_t)( *p - start ); - if ( psa_export_public_key( *key_slot, start, buffer_size, &len ) + if ( psa_export_public_key( *key_id, start, buffer_size, &len ) != PSA_SUCCESS ) { return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); @@ -265,12 +265,12 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_type_t key_type; - psa_key_handle_t handle; + psa_key_id_t key_id; psa_ecc_family_t curve; size_t bits; - handle = *((psa_key_handle_t*) key->pk_ctx ); - if( PSA_SUCCESS != psa_get_key_attributes( handle, &attributes ) ) + key_id = *((psa_key_id_t*) key->pk_ctx ); + if( PSA_SUCCESS != psa_get_key_attributes( key_id, &attributes ) ) return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED ); key_type = psa_get_key_type( &attributes ); bits = psa_get_key_bits( &attributes ); diff --git a/connectivity/mbedtls/source/platform_util.c b/connectivity/mbedtls/source/platform_util.c index 4e1d617bd15..98fe5deb2de 100644 --- a/connectivity/mbedtls/source/platform_util.c +++ b/connectivity/mbedtls/source/platform_util.c @@ -84,7 +84,7 @@ void mbedtls_platform_zeroize( void *buf, size_t len ) #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) /* * This is a convenience shorthand macro to avoid checking the long * preprocessor conditions above. Ideally, we could expose this macro in @@ -98,7 +98,7 @@ void mbedtls_platform_zeroize( void *buf, size_t len ) #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, struct tm *tm_buf ) diff --git a/connectivity/mbedtls/source/ripemd160.c b/connectivity/mbedtls/source/ripemd160.c index 830f61b3cd5..ae4dee4121d 100644 --- a/connectivity/mbedtls/source/ripemd160.c +++ b/connectivity/mbedtls/source/ripemd160.c @@ -117,30 +117,33 @@ void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] ) { - uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - - A = Ap = ctx->state[0]; - B = Bp = ctx->state[1]; - C = Cp = ctx->state[2]; - D = Dp = ctx->state[3]; - E = Ep = ctx->state[4]; + struct + { + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + } local; + + GET_UINT32_LE( local.X[ 0], data, 0 ); + GET_UINT32_LE( local.X[ 1], data, 4 ); + GET_UINT32_LE( local.X[ 2], data, 8 ); + GET_UINT32_LE( local.X[ 3], data, 12 ); + GET_UINT32_LE( local.X[ 4], data, 16 ); + GET_UINT32_LE( local.X[ 5], data, 20 ); + GET_UINT32_LE( local.X[ 6], data, 24 ); + GET_UINT32_LE( local.X[ 7], data, 28 ); + GET_UINT32_LE( local.X[ 8], data, 32 ); + GET_UINT32_LE( local.X[ 9], data, 36 ); + GET_UINT32_LE( local.X[10], data, 40 ); + GET_UINT32_LE( local.X[11], data, 44 ); + GET_UINT32_LE( local.X[12], data, 48 ); + GET_UINT32_LE( local.X[13], data, 52 ); + GET_UINT32_LE( local.X[14], data, 56 ); + GET_UINT32_LE( local.X[15], data, 60 ); + + local.A = local.Ap = ctx->state[0]; + local.B = local.Bp = ctx->state[1]; + local.C = local.Cp = ctx->state[2]; + local.D = local.Dp = ctx->state[3]; + local.E = local.Ep = ctx->state[4]; #define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) #define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) @@ -150,12 +153,12 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) -#define P( a, b, c, d, e, r, s, f, k ) \ - do \ - { \ - (a) += f( (b), (c), (d) ) + X[r] + (k); \ - (a) = S( (a), (s) ) + (e); \ - (c) = S( (c), 10 ); \ +#define P( a, b, c, d, e, r, s, f, k ) \ + do \ + { \ + (a) += f( (b), (c), (d) ) + local.X[r] + (k); \ + (a) = S( (a), (s) ) + (e); \ + (c) = S( (c), 10 ); \ } while( 0 ) #define P2( a, b, c, d, e, r, s, rp, sp ) \ @@ -170,22 +173,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define K 0x00000000 #define Fp F5 #define Kp 0x50A28BE6 - P2( A, B, C, D, E, 0, 11, 5, 8 ); - P2( E, A, B, C, D, 1, 14, 14, 9 ); - P2( D, E, A, B, C, 2, 15, 7, 9 ); - P2( C, D, E, A, B, 3, 12, 0, 11 ); - P2( B, C, D, E, A, 4, 5, 9, 13 ); - P2( A, B, C, D, E, 5, 8, 2, 15 ); - P2( E, A, B, C, D, 6, 7, 11, 15 ); - P2( D, E, A, B, C, 7, 9, 4, 5 ); - P2( C, D, E, A, B, 8, 11, 13, 7 ); - P2( B, C, D, E, A, 9, 13, 6, 7 ); - P2( A, B, C, D, E, 10, 14, 15, 8 ); - P2( E, A, B, C, D, 11, 15, 8, 11 ); - P2( D, E, A, B, C, 12, 6, 1, 14 ); - P2( C, D, E, A, B, 13, 7, 10, 14 ); - P2( B, C, D, E, A, 14, 9, 3, 12 ); - P2( A, B, C, D, E, 15, 8, 12, 6 ); + P2( local.A, local.B, local.C, local.D, local.E, 0, 11, 5, 8 ); + P2( local.E, local.A, local.B, local.C, local.D, 1, 14, 14, 9 ); + P2( local.D, local.E, local.A, local.B, local.C, 2, 15, 7, 9 ); + P2( local.C, local.D, local.E, local.A, local.B, 3, 12, 0, 11 ); + P2( local.B, local.C, local.D, local.E, local.A, 4, 5, 9, 13 ); + P2( local.A, local.B, local.C, local.D, local.E, 5, 8, 2, 15 ); + P2( local.E, local.A, local.B, local.C, local.D, 6, 7, 11, 15 ); + P2( local.D, local.E, local.A, local.B, local.C, 7, 9, 4, 5 ); + P2( local.C, local.D, local.E, local.A, local.B, 8, 11, 13, 7 ); + P2( local.B, local.C, local.D, local.E, local.A, 9, 13, 6, 7 ); + P2( local.A, local.B, local.C, local.D, local.E, 10, 14, 15, 8 ); + P2( local.E, local.A, local.B, local.C, local.D, 11, 15, 8, 11 ); + P2( local.D, local.E, local.A, local.B, local.C, 12, 6, 1, 14 ); + P2( local.C, local.D, local.E, local.A, local.B, 13, 7, 10, 14 ); + P2( local.B, local.C, local.D, local.E, local.A, 14, 9, 3, 12 ); + P2( local.A, local.B, local.C, local.D, local.E, 15, 8, 12, 6 ); #undef F #undef K #undef Fp @@ -195,22 +198,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define K 0x5A827999 #define Fp F4 #define Kp 0x5C4DD124 - P2( E, A, B, C, D, 7, 7, 6, 9 ); - P2( D, E, A, B, C, 4, 6, 11, 13 ); - P2( C, D, E, A, B, 13, 8, 3, 15 ); - P2( B, C, D, E, A, 1, 13, 7, 7 ); - P2( A, B, C, D, E, 10, 11, 0, 12 ); - P2( E, A, B, C, D, 6, 9, 13, 8 ); - P2( D, E, A, B, C, 15, 7, 5, 9 ); - P2( C, D, E, A, B, 3, 15, 10, 11 ); - P2( B, C, D, E, A, 12, 7, 14, 7 ); - P2( A, B, C, D, E, 0, 12, 15, 7 ); - P2( E, A, B, C, D, 9, 15, 8, 12 ); - P2( D, E, A, B, C, 5, 9, 12, 7 ); - P2( C, D, E, A, B, 2, 11, 4, 6 ); - P2( B, C, D, E, A, 14, 7, 9, 15 ); - P2( A, B, C, D, E, 11, 13, 1, 13 ); - P2( E, A, B, C, D, 8, 12, 2, 11 ); + P2( local.E, local.A, local.B, local.C, local.D, 7, 7, 6, 9 ); + P2( local.D, local.E, local.A, local.B, local.C, 4, 6, 11, 13 ); + P2( local.C, local.D, local.E, local.A, local.B, 13, 8, 3, 15 ); + P2( local.B, local.C, local.D, local.E, local.A, 1, 13, 7, 7 ); + P2( local.A, local.B, local.C, local.D, local.E, 10, 11, 0, 12 ); + P2( local.E, local.A, local.B, local.C, local.D, 6, 9, 13, 8 ); + P2( local.D, local.E, local.A, local.B, local.C, 15, 7, 5, 9 ); + P2( local.C, local.D, local.E, local.A, local.B, 3, 15, 10, 11 ); + P2( local.B, local.C, local.D, local.E, local.A, 12, 7, 14, 7 ); + P2( local.A, local.B, local.C, local.D, local.E, 0, 12, 15, 7 ); + P2( local.E, local.A, local.B, local.C, local.D, 9, 15, 8, 12 ); + P2( local.D, local.E, local.A, local.B, local.C, 5, 9, 12, 7 ); + P2( local.C, local.D, local.E, local.A, local.B, 2, 11, 4, 6 ); + P2( local.B, local.C, local.D, local.E, local.A, 14, 7, 9, 15 ); + P2( local.A, local.B, local.C, local.D, local.E, 11, 13, 1, 13 ); + P2( local.E, local.A, local.B, local.C, local.D, 8, 12, 2, 11 ); #undef F #undef K #undef Fp @@ -220,22 +223,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define K 0x6ED9EBA1 #define Fp F3 #define Kp 0x6D703EF3 - P2( D, E, A, B, C, 3, 11, 15, 9 ); - P2( C, D, E, A, B, 10, 13, 5, 7 ); - P2( B, C, D, E, A, 14, 6, 1, 15 ); - P2( A, B, C, D, E, 4, 7, 3, 11 ); - P2( E, A, B, C, D, 9, 14, 7, 8 ); - P2( D, E, A, B, C, 15, 9, 14, 6 ); - P2( C, D, E, A, B, 8, 13, 6, 6 ); - P2( B, C, D, E, A, 1, 15, 9, 14 ); - P2( A, B, C, D, E, 2, 14, 11, 12 ); - P2( E, A, B, C, D, 7, 8, 8, 13 ); - P2( D, E, A, B, C, 0, 13, 12, 5 ); - P2( C, D, E, A, B, 6, 6, 2, 14 ); - P2( B, C, D, E, A, 13, 5, 10, 13 ); - P2( A, B, C, D, E, 11, 12, 0, 13 ); - P2( E, A, B, C, D, 5, 7, 4, 7 ); - P2( D, E, A, B, C, 12, 5, 13, 5 ); + P2( local.D, local.E, local.A, local.B, local.C, 3, 11, 15, 9 ); + P2( local.C, local.D, local.E, local.A, local.B, 10, 13, 5, 7 ); + P2( local.B, local.C, local.D, local.E, local.A, 14, 6, 1, 15 ); + P2( local.A, local.B, local.C, local.D, local.E, 4, 7, 3, 11 ); + P2( local.E, local.A, local.B, local.C, local.D, 9, 14, 7, 8 ); + P2( local.D, local.E, local.A, local.B, local.C, 15, 9, 14, 6 ); + P2( local.C, local.D, local.E, local.A, local.B, 8, 13, 6, 6 ); + P2( local.B, local.C, local.D, local.E, local.A, 1, 15, 9, 14 ); + P2( local.A, local.B, local.C, local.D, local.E, 2, 14, 11, 12 ); + P2( local.E, local.A, local.B, local.C, local.D, 7, 8, 8, 13 ); + P2( local.D, local.E, local.A, local.B, local.C, 0, 13, 12, 5 ); + P2( local.C, local.D, local.E, local.A, local.B, 6, 6, 2, 14 ); + P2( local.B, local.C, local.D, local.E, local.A, 13, 5, 10, 13 ); + P2( local.A, local.B, local.C, local.D, local.E, 11, 12, 0, 13 ); + P2( local.E, local.A, local.B, local.C, local.D, 5, 7, 4, 7 ); + P2( local.D, local.E, local.A, local.B, local.C, 12, 5, 13, 5 ); #undef F #undef K #undef Fp @@ -245,22 +248,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define K 0x8F1BBCDC #define Fp F2 #define Kp 0x7A6D76E9 - P2( C, D, E, A, B, 1, 11, 8, 15 ); - P2( B, C, D, E, A, 9, 12, 6, 5 ); - P2( A, B, C, D, E, 11, 14, 4, 8 ); - P2( E, A, B, C, D, 10, 15, 1, 11 ); - P2( D, E, A, B, C, 0, 14, 3, 14 ); - P2( C, D, E, A, B, 8, 15, 11, 14 ); - P2( B, C, D, E, A, 12, 9, 15, 6 ); - P2( A, B, C, D, E, 4, 8, 0, 14 ); - P2( E, A, B, C, D, 13, 9, 5, 6 ); - P2( D, E, A, B, C, 3, 14, 12, 9 ); - P2( C, D, E, A, B, 7, 5, 2, 12 ); - P2( B, C, D, E, A, 15, 6, 13, 9 ); - P2( A, B, C, D, E, 14, 8, 9, 12 ); - P2( E, A, B, C, D, 5, 6, 7, 5 ); - P2( D, E, A, B, C, 6, 5, 10, 15 ); - P2( C, D, E, A, B, 2, 12, 14, 8 ); + P2( local.C, local.D, local.E, local.A, local.B, 1, 11, 8, 15 ); + P2( local.B, local.C, local.D, local.E, local.A, 9, 12, 6, 5 ); + P2( local.A, local.B, local.C, local.D, local.E, 11, 14, 4, 8 ); + P2( local.E, local.A, local.B, local.C, local.D, 10, 15, 1, 11 ); + P2( local.D, local.E, local.A, local.B, local.C, 0, 14, 3, 14 ); + P2( local.C, local.D, local.E, local.A, local.B, 8, 15, 11, 14 ); + P2( local.B, local.C, local.D, local.E, local.A, 12, 9, 15, 6 ); + P2( local.A, local.B, local.C, local.D, local.E, 4, 8, 0, 14 ); + P2( local.E, local.A, local.B, local.C, local.D, 13, 9, 5, 6 ); + P2( local.D, local.E, local.A, local.B, local.C, 3, 14, 12, 9 ); + P2( local.C, local.D, local.E, local.A, local.B, 7, 5, 2, 12 ); + P2( local.B, local.C, local.D, local.E, local.A, 15, 6, 13, 9 ); + P2( local.A, local.B, local.C, local.D, local.E, 14, 8, 9, 12 ); + P2( local.E, local.A, local.B, local.C, local.D, 5, 6, 7, 5 ); + P2( local.D, local.E, local.A, local.B, local.C, 6, 5, 10, 15 ); + P2( local.C, local.D, local.E, local.A, local.B, 2, 12, 14, 8 ); #undef F #undef K #undef Fp @@ -270,33 +273,36 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, #define K 0xA953FD4E #define Fp F1 #define Kp 0x00000000 - P2( B, C, D, E, A, 4, 9, 12, 8 ); - P2( A, B, C, D, E, 0, 15, 15, 5 ); - P2( E, A, B, C, D, 5, 5, 10, 12 ); - P2( D, E, A, B, C, 9, 11, 4, 9 ); - P2( C, D, E, A, B, 7, 6, 1, 12 ); - P2( B, C, D, E, A, 12, 8, 5, 5 ); - P2( A, B, C, D, E, 2, 13, 8, 14 ); - P2( E, A, B, C, D, 10, 12, 7, 6 ); - P2( D, E, A, B, C, 14, 5, 6, 8 ); - P2( C, D, E, A, B, 1, 12, 2, 13 ); - P2( B, C, D, E, A, 3, 13, 13, 6 ); - P2( A, B, C, D, E, 8, 14, 14, 5 ); - P2( E, A, B, C, D, 11, 11, 0, 15 ); - P2( D, E, A, B, C, 6, 8, 3, 13 ); - P2( C, D, E, A, B, 15, 5, 9, 11 ); - P2( B, C, D, E, A, 13, 6, 11, 11 ); + P2( local.B, local.C, local.D, local.E, local.A, 4, 9, 12, 8 ); + P2( local.A, local.B, local.C, local.D, local.E, 0, 15, 15, 5 ); + P2( local.E, local.A, local.B, local.C, local.D, 5, 5, 10, 12 ); + P2( local.D, local.E, local.A, local.B, local.C, 9, 11, 4, 9 ); + P2( local.C, local.D, local.E, local.A, local.B, 7, 6, 1, 12 ); + P2( local.B, local.C, local.D, local.E, local.A, 12, 8, 5, 5 ); + P2( local.A, local.B, local.C, local.D, local.E, 2, 13, 8, 14 ); + P2( local.E, local.A, local.B, local.C, local.D, 10, 12, 7, 6 ); + P2( local.D, local.E, local.A, local.B, local.C, 14, 5, 6, 8 ); + P2( local.C, local.D, local.E, local.A, local.B, 1, 12, 2, 13 ); + P2( local.B, local.C, local.D, local.E, local.A, 3, 13, 13, 6 ); + P2( local.A, local.B, local.C, local.D, local.E, 8, 14, 14, 5 ); + P2( local.E, local.A, local.B, local.C, local.D, 11, 11, 0, 15 ); + P2( local.D, local.E, local.A, local.B, local.C, 6, 8, 3, 13 ); + P2( local.C, local.D, local.E, local.A, local.B, 15, 5, 9, 11 ); + P2( local.B, local.C, local.D, local.E, local.A, 13, 6, 11, 11 ); #undef F #undef K #undef Fp #undef Kp - C = ctx->state[1] + C + Dp; - ctx->state[1] = ctx->state[2] + D + Ep; - ctx->state[2] = ctx->state[3] + E + Ap; - ctx->state[3] = ctx->state[4] + A + Bp; - ctx->state[4] = ctx->state[0] + B + Cp; - ctx->state[0] = C; + local.C = ctx->state[1] + local.C + local.Dp; + ctx->state[1] = ctx->state[2] + local.D + local.Ep; + ctx->state[2] = ctx->state[3] + local.E + local.Ap; + ctx->state[3] = ctx->state[4] + local.A + local.Bp; + ctx->state[4] = ctx->state[0] + local.B + local.Cp; + ctx->state[0] = local.C; + + /* Zeroise variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } @@ -478,8 +484,7 @@ static const unsigned char ripemd160_test_str[TESTS][81] = { "abcdefghijklmnopqrstuvwxyz" }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" - "345678901234567890" }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }, }; static const size_t ripemd160_test_strlen[TESTS] = diff --git a/connectivity/mbedtls/source/rsa.c b/connectivity/mbedtls/source/rsa.c index 84d87de0d19..d6abd65d4c2 100644 --- a/connectivity/mbedtls/source/rsa.c +++ b/connectivity/mbedtls/source/rsa.c @@ -811,15 +811,14 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, * which one, we just loop and choose new values for both of them. * (Each iteration succeeds with overwhelming probability.) */ ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N ); - if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - continue; - if( ret != 0 ) + if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) goto cleanup; - /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - } while( 0 ); + } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + + /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); /* Blinding value: Vi = Vf^(-e) mod N * (Vi already contains Vf^-1 at this point) */ diff --git a/connectivity/mbedtls/source/sha1.c b/connectivity/mbedtls/source/sha1.c index 593f79513af..6b0f58e7b61 100644 --- a/connectivity/mbedtls/source/sha1.c +++ b/connectivity/mbedtls/source/sha1.c @@ -125,35 +125,40 @@ void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) { - uint32_t temp, W[16], A, B, C, D, E; + struct + { + uint32_t temp, W[16], A, B, C, D, E; + } local; SHA1_VALIDATE_RET( ctx != NULL ); SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); - GET_UINT32_BE( W[ 0], data, 0 ); - GET_UINT32_BE( W[ 1], data, 4 ); - GET_UINT32_BE( W[ 2], data, 8 ); - GET_UINT32_BE( W[ 3], data, 12 ); - GET_UINT32_BE( W[ 4], data, 16 ); - GET_UINT32_BE( W[ 5], data, 20 ); - GET_UINT32_BE( W[ 6], data, 24 ); - GET_UINT32_BE( W[ 7], data, 28 ); - GET_UINT32_BE( W[ 8], data, 32 ); - GET_UINT32_BE( W[ 9], data, 36 ); - GET_UINT32_BE( W[10], data, 40 ); - GET_UINT32_BE( W[11], data, 44 ); - GET_UINT32_BE( W[12], data, 48 ); - GET_UINT32_BE( W[13], data, 52 ); - GET_UINT32_BE( W[14], data, 56 ); - GET_UINT32_BE( W[15], data, 60 ); + GET_UINT32_BE( local.W[ 0], data, 0 ); + GET_UINT32_BE( local.W[ 1], data, 4 ); + GET_UINT32_BE( local.W[ 2], data, 8 ); + GET_UINT32_BE( local.W[ 3], data, 12 ); + GET_UINT32_BE( local.W[ 4], data, 16 ); + GET_UINT32_BE( local.W[ 5], data, 20 ); + GET_UINT32_BE( local.W[ 6], data, 24 ); + GET_UINT32_BE( local.W[ 7], data, 28 ); + GET_UINT32_BE( local.W[ 8], data, 32 ); + GET_UINT32_BE( local.W[ 9], data, 36 ); + GET_UINT32_BE( local.W[10], data, 40 ); + GET_UINT32_BE( local.W[11], data, 44 ); + GET_UINT32_BE( local.W[12], data, 48 ); + GET_UINT32_BE( local.W[13], data, 52 ); + GET_UINT32_BE( local.W[14], data, 56 ); + GET_UINT32_BE( local.W[15], data, 60 ); #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) #define R(t) \ ( \ - temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \ - W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \ - ( W[(t) & 0x0F] = S(temp,1) ) \ + local.temp = local.W[( (t) - 3 ) & 0x0F] ^ \ + local.W[( (t) - 8 ) & 0x0F] ^ \ + local.W[( (t) - 14 ) & 0x0F] ^ \ + local.W[ (t) & 0x0F], \ + ( local.W[(t) & 0x0F] = S(local.temp,1) ) \ ) #define P(a,b,c,d,e,x) \ @@ -163,35 +168,35 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, (b) = S((b),30); \ } while( 0 ) - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; + local.A = ctx->state[0]; + local.B = ctx->state[1]; + local.C = ctx->state[2]; + local.D = ctx->state[3]; + local.E = ctx->state[4]; #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define K 0x5A827999 - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); + P( local.A, local.B, local.C, local.D, local.E, local.W[0] ); + P( local.E, local.A, local.B, local.C, local.D, local.W[1] ); + P( local.D, local.E, local.A, local.B, local.C, local.W[2] ); + P( local.C, local.D, local.E, local.A, local.B, local.W[3] ); + P( local.B, local.C, local.D, local.E, local.A, local.W[4] ); + P( local.A, local.B, local.C, local.D, local.E, local.W[5] ); + P( local.E, local.A, local.B, local.C, local.D, local.W[6] ); + P( local.D, local.E, local.A, local.B, local.C, local.W[7] ); + P( local.C, local.D, local.E, local.A, local.B, local.W[8] ); + P( local.B, local.C, local.D, local.E, local.A, local.W[9] ); + P( local.A, local.B, local.C, local.D, local.E, local.W[10] ); + P( local.E, local.A, local.B, local.C, local.D, local.W[11] ); + P( local.D, local.E, local.A, local.B, local.C, local.W[12] ); + P( local.C, local.D, local.E, local.A, local.B, local.W[13] ); + P( local.B, local.C, local.D, local.E, local.A, local.W[14] ); + P( local.A, local.B, local.C, local.D, local.E, local.W[15] ); + P( local.E, local.A, local.B, local.C, local.D, R(16) ); + P( local.D, local.E, local.A, local.B, local.C, R(17) ); + P( local.C, local.D, local.E, local.A, local.B, R(18) ); + P( local.B, local.C, local.D, local.E, local.A, R(19) ); #undef K #undef F @@ -199,26 +204,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #define F(x,y,z) ((x) ^ (y) ^ (z)) #define K 0x6ED9EBA1 - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); + P( local.A, local.B, local.C, local.D, local.E, R(20) ); + P( local.E, local.A, local.B, local.C, local.D, R(21) ); + P( local.D, local.E, local.A, local.B, local.C, R(22) ); + P( local.C, local.D, local.E, local.A, local.B, R(23) ); + P( local.B, local.C, local.D, local.E, local.A, R(24) ); + P( local.A, local.B, local.C, local.D, local.E, R(25) ); + P( local.E, local.A, local.B, local.C, local.D, R(26) ); + P( local.D, local.E, local.A, local.B, local.C, R(27) ); + P( local.C, local.D, local.E, local.A, local.B, R(28) ); + P( local.B, local.C, local.D, local.E, local.A, R(29) ); + P( local.A, local.B, local.C, local.D, local.E, R(30) ); + P( local.E, local.A, local.B, local.C, local.D, R(31) ); + P( local.D, local.E, local.A, local.B, local.C, R(32) ); + P( local.C, local.D, local.E, local.A, local.B, R(33) ); + P( local.B, local.C, local.D, local.E, local.A, R(34) ); + P( local.A, local.B, local.C, local.D, local.E, R(35) ); + P( local.E, local.A, local.B, local.C, local.D, R(36) ); + P( local.D, local.E, local.A, local.B, local.C, R(37) ); + P( local.C, local.D, local.E, local.A, local.B, R(38) ); + P( local.B, local.C, local.D, local.E, local.A, R(39) ); #undef K #undef F @@ -226,26 +231,26 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) #define K 0x8F1BBCDC - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); + P( local.A, local.B, local.C, local.D, local.E, R(40) ); + P( local.E, local.A, local.B, local.C, local.D, R(41) ); + P( local.D, local.E, local.A, local.B, local.C, R(42) ); + P( local.C, local.D, local.E, local.A, local.B, R(43) ); + P( local.B, local.C, local.D, local.E, local.A, R(44) ); + P( local.A, local.B, local.C, local.D, local.E, R(45) ); + P( local.E, local.A, local.B, local.C, local.D, R(46) ); + P( local.D, local.E, local.A, local.B, local.C, R(47) ); + P( local.C, local.D, local.E, local.A, local.B, R(48) ); + P( local.B, local.C, local.D, local.E, local.A, R(49) ); + P( local.A, local.B, local.C, local.D, local.E, R(50) ); + P( local.E, local.A, local.B, local.C, local.D, R(51) ); + P( local.D, local.E, local.A, local.B, local.C, R(52) ); + P( local.C, local.D, local.E, local.A, local.B, R(53) ); + P( local.B, local.C, local.D, local.E, local.A, R(54) ); + P( local.A, local.B, local.C, local.D, local.E, R(55) ); + P( local.E, local.A, local.B, local.C, local.D, R(56) ); + P( local.D, local.E, local.A, local.B, local.C, R(57) ); + P( local.C, local.D, local.E, local.A, local.B, R(58) ); + P( local.B, local.C, local.D, local.E, local.A, R(59) ); #undef K #undef F @@ -253,35 +258,38 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #define F(x,y,z) ((x) ^ (y) ^ (z)) #define K 0xCA62C1D6 - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); + P( local.A, local.B, local.C, local.D, local.E, R(60) ); + P( local.E, local.A, local.B, local.C, local.D, R(61) ); + P( local.D, local.E, local.A, local.B, local.C, R(62) ); + P( local.C, local.D, local.E, local.A, local.B, R(63) ); + P( local.B, local.C, local.D, local.E, local.A, R(64) ); + P( local.A, local.B, local.C, local.D, local.E, R(65) ); + P( local.E, local.A, local.B, local.C, local.D, R(66) ); + P( local.D, local.E, local.A, local.B, local.C, R(67) ); + P( local.C, local.D, local.E, local.A, local.B, R(68) ); + P( local.B, local.C, local.D, local.E, local.A, R(69) ); + P( local.A, local.B, local.C, local.D, local.E, R(70) ); + P( local.E, local.A, local.B, local.C, local.D, R(71) ); + P( local.D, local.E, local.A, local.B, local.C, R(72) ); + P( local.C, local.D, local.E, local.A, local.B, R(73) ); + P( local.B, local.C, local.D, local.E, local.A, R(74) ); + P( local.A, local.B, local.C, local.D, local.E, R(75) ); + P( local.E, local.A, local.B, local.C, local.D, R(76) ); + P( local.D, local.E, local.A, local.B, local.C, R(77) ); + P( local.C, local.D, local.E, local.A, local.B, R(78) ); + P( local.B, local.C, local.D, local.E, local.A, R(79) ); #undef K #undef F - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; + ctx->state[0] += local.A; + ctx->state[1] += local.B; + ctx->state[2] += local.C; + ctx->state[3] += local.D; + ctx->state[4] += local.E; + + /* Zeroise buffers and variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } diff --git a/connectivity/mbedtls/source/sha256.c b/connectivity/mbedtls/source/sha256.c index b4c4b3624fe..be373d9cb0b 100644 --- a/connectivity/mbedtls/source/sha256.c +++ b/connectivity/mbedtls/source/sha256.c @@ -179,77 +179,104 @@ static const uint32_t K[] = #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define R(t) \ - ( \ - W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \ - S0(W[(t) - 15]) + W[(t) - 16] \ +#define R(t) \ + ( \ + local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \ + S0(local.W[(t) - 15]) + local.W[(t) - 16] \ ) -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += temp1; (h) = temp1 + temp2; \ +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + local.temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += local.temp1; (h) = local.temp1 + local.temp2; \ } while( 0 ) int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) { - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; + struct + { + uint32_t temp1, temp2, W[64]; + uint32_t A[8]; + } local; + unsigned int i; SHA256_VALIDATE_RET( ctx != NULL ); SHA256_VALIDATE_RET( (const unsigned char *)data != NULL ); for( i = 0; i < 8; i++ ) - A[i] = ctx->state[i]; + local.A[i] = ctx->state[i]; #if defined(MBEDTLS_SHA256_SMALLER) for( i = 0; i < 64; i++ ) { if( i < 16 ) - GET_UINT32_BE( W[i], data, 4 * i ); + GET_UINT32_BE( local.W[i], data, 4 * i ); else R( i ); - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); - temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; - A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + local.temp1 = local.A[7]; local.A[7] = local.A[6]; + local.A[6] = local.A[5]; local.A[5] = local.A[4]; + local.A[4] = local.A[3]; local.A[3] = local.A[2]; + local.A[2] = local.A[1]; local.A[1] = local.A[0]; + local.A[0] = local.temp1; } #else /* MBEDTLS_SHA256_SMALLER */ for( i = 0; i < 16; i++ ) - GET_UINT32_BE( W[i], data, 4 * i ); + GET_UINT32_BE( local.W[i], data, 4 * i ); for( i = 0; i < 16; i += 8 ) { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); + P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0] ); + P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], + local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1] ); + P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], + local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2] ); + P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], + local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3] ); + P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], + local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4] ); + P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], + local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5] ); + P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], + local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6] ); + P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], + local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7] ); } for( i = 16; i < 64; i += 8 ) { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); + P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], R(i+0), K[i+0] ); + P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], + local.A[4], local.A[5], local.A[6], R(i+1), K[i+1] ); + P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], + local.A[3], local.A[4], local.A[5], R(i+2), K[i+2] ); + P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], + local.A[2], local.A[3], local.A[4], R(i+3), K[i+3] ); + P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], + local.A[1], local.A[2], local.A[3], R(i+4), K[i+4] ); + P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], + local.A[0], local.A[1], local.A[2], R(i+5), K[i+5] ); + P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], + local.A[7], local.A[0], local.A[1], R(i+6), K[i+6] ); + P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], + local.A[6], local.A[7], local.A[0], R(i+7), K[i+7] ); } #endif /* MBEDTLS_SHA256_SMALLER */ for( i = 0; i < 8; i++ ) - ctx->state[i] += A[i]; + ctx->state[i] += local.A[i]; + + /* Zeroise buffers and variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } diff --git a/connectivity/mbedtls/source/sha512.c b/connectivity/mbedtls/source/sha512.c index 80219d42816..06a628aedce 100644 --- a/connectivity/mbedtls/source/sha512.c +++ b/connectivity/mbedtls/source/sha512.c @@ -232,8 +232,11 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) { int i; - uint64_t temp1, temp2, W[80]; - uint64_t A[8]; + struct + { + uint64_t temp1, temp2, W[80]; + uint64_t A[8]; + } local; SHA512_VALIDATE_RET( ctx != NULL ); SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); @@ -250,64 +253,79 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define P(a,b,c,d,e,f,g,h,x,K) \ - do \ - { \ - temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ - temp2 = S2(a) + F0((a),(b),(c)); \ - (d) += temp1; (h) = temp1 + temp2; \ +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + local.temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += local.temp1; (h) = local.temp1 + local.temp2; \ } while( 0 ) for( i = 0; i < 8; i++ ) - A[i] = ctx->state[i]; + local.A[i] = ctx->state[i]; #if defined(MBEDTLS_SHA512_SMALLER) for( i = 0; i < 80; i++ ) { if( i < 16 ) { - GET_UINT64_BE( W[i], data, i << 3 ); + GET_UINT64_BE( local.W[i], data, i << 3 ); } else { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; + local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + + S0(local.W[i - 15]) + local.W[i - 16]; } - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); - temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; - A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + local.temp1 = local.A[7]; local.A[7] = local.A[6]; + local.A[6] = local.A[5]; local.A[5] = local.A[4]; + local.A[4] = local.A[3]; local.A[3] = local.A[2]; + local.A[2] = local.A[1]; local.A[1] = local.A[0]; + local.A[0] = local.temp1; } #else /* MBEDTLS_SHA512_SMALLER */ for( i = 0; i < 16; i++ ) { - GET_UINT64_BE( W[i], data, i << 3 ); + GET_UINT64_BE( local.W[i], data, i << 3 ); } for( ; i < 80; i++ ) { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; + local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + + S0(local.W[i - 15]) + local.W[i - 16]; } i = 0; do { - P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++; - P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++; - P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++; - P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++; - P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++; - P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++; - P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++; - P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++; + P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++; + P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], + local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++; + P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], + local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++; + P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], + local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++; + P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], + local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++; + P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], + local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++; + P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], + local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++; + P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], + local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++; } while( i < 80 ); #endif /* MBEDTLS_SHA512_SMALLER */ for( i = 0; i < 8; i++ ) - ctx->state[i] += A[i]; + ctx->state[i] += local.A[i]; + + /* Zeroise buffers and variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize( &local, sizeof( local ) ); return( 0 ); } @@ -516,8 +534,7 @@ void mbedtls_sha512( const unsigned char *input, static const unsigned char sha512_test_buf[3][113] = { { "abc" }, - { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, { "" } }; diff --git a/connectivity/mbedtls/source/ssl_cli.c b/connectivity/mbedtls/source/ssl_cli.c index 083b720be11..a8331d9bb34 100644 --- a/connectivity/mbedtls/source/ssl_cli.c +++ b/connectivity/mbedtls/source/ssl_cli.c @@ -63,7 +63,7 @@ static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf ) return( 1 ); #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) ) return( 1 ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -756,6 +756,126 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + const unsigned char *end, + size_t *olen ) +{ + unsigned char *p = buf; + size_t protection_profiles_index = 0, ext_len = 0; + uint16_t mki_len = 0, profile_value = 0; + + *olen = 0; + + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + { + return( 0 ); + } + + /* RFC 5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + /* Extension length = 2 bytes for profiles length, + * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ), + * 1 byte for srtp_mki vector length and the mki_len value + */ + ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) ); + + /* Check there is room in the buffer for the extension + 4 bytes + * - the extension tag (2 bytes) + * - the extension length (2 bytes) + */ + MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP ) & 0xFF ); + + + *p++ = (unsigned char)( ( ( ext_len & 0xFF00 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ext_len & 0xFF ); + + /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */ + /* micro-optimization: + * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + * which is lower than 127, so the upper byte of the length is always 0 + * For the documentation, the more generic code is left in comments + * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) + * >> 8 ) & 0xFF ); + */ + *p++ = 0; + *p++ = (unsigned char)( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) + & 0xFF ); + + for( protection_profiles_index=0; + protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; + protection_profiles_index++ ) + { + profile_value = mbedtls_ssl_check_srtp_profile_value + ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] ); + if( profile_value != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x", + profile_value ) ); + *p++ = ( ( profile_value >> 8 ) & 0xFF ); + *p++ = ( profile_value & 0xFF ); + } + else + { + /* + * Note: we shall never arrive here as protection profiles + * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function + */ + MBEDTLS_SSL_DEBUG_MSG( 3, + ( "client hello, " + "illegal DTLS-SRTP protection profile %d", + ssl->conf->dtls_srtp_profile_list[protection_profiles_index] + ) ); + return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED ); + } + } + + *p++ = mki_len & 0xFF; + + if( mki_len != 0 ) + { + memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len ); + /* + * Increment p to point to the current position. + */ + p += mki_len; + MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } + + /* + * total extension length: extension type (2 bytes) + * + extension length (2 bytes) + * + protection profile length (2 bytes) + * + 2 * number of protection profiles + * + srtp_mki vector length(1 byte) + * + mki value + */ + *olen = p - buf; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Generate random bytes for ClientHello */ @@ -1277,6 +1397,16 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, + end, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret ); + return( ret ); + } + ext_len += olen; +#endif + #if defined(MBEDTLS_SSL_SESSION_TICKETS) if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, end, &olen ) ) != 0 ) @@ -1710,6 +1840,123 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET; + size_t i, mki_len = 0; + uint16_t server_protection_profile_value = 0; + + /* If use_srtp is not configured, just ignore the extension */ + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + return( 0 ); + + /* RFC 5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + * + */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + + /* + * Length is 5 + optional mki_value : one protection profile length (2 bytes) + * + protection profile (2 bytes) + * + mki_len(1 byte) + * and optional srtp_mki + */ + if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* + * get the server protection profile + */ + + /* + * protection profile length must be 0x0002 as we must have only + * one protection profile in server Hello + */ + if( ( buf[0] != 0 ) || ( buf[1] != 2 ) ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + server_protection_profile_value = ( buf[2] << 8 ) | buf[3]; + server_protection = mbedtls_ssl_check_srtp_profile_value( + server_protection_profile_value ); + if( server_protection != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + server_protection ) ) ); + } + + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; + + /* + * Check we have the server profile in our list + */ + for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++) + { + if( server_protection == ssl->conf->dtls_srtp_profile_list[i] ) + { + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + server_protection ) ) ); + break; + } + } + + /* If no match was found : server problem, it shall never answer with incompatible profile */ + if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + /* If server does not use mki in its reply, make sure the client won't keep + * one as negotiated */ + if( len == 5 ) + { + ssl->dtls_srtp_info.mki_len = 0; + } + + /* + * RFC5764: + * If the client detects a nonzero-length MKI in the server's response + * that is different than the one the client offered, then the client + * MUST abort the handshake and SHOULD send an invalid_parameter alert. + */ + if( len > 5 && ( buf[4] != mki_len || + ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } +#if defined (MBEDTLS_DEBUG_C) + if( len > 5 ) + { + MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } +#endif + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Parse HelloVerifyRequest. Only called after verifying the HS type. */ @@ -2278,6 +2525,16 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) break; #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + case MBEDTLS_TLS_EXT_USE_SRTP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) ); + + if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + + break; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + default: MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); @@ -3545,7 +3802,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) status = psa_destroy_key( handshake->ecdh_psa_privkey ); if( status != PSA_SUCCESS ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - handshake->ecdh_psa_privkey = 0; + handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; } else #endif /* MBEDTLS_USE_PSA_CRYPTO && diff --git a/connectivity/mbedtls/source/ssl_msg.c b/connectivity/mbedtls/source/ssl_msg.c index 2ea35808ad5..72f09bb42a4 100644 --- a/connectivity/mbedtls/source/ssl_msg.c +++ b/connectivity/mbedtls/source/ssl_msg.c @@ -850,20 +850,21 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, * Encrypt and authenticate */ - if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, + if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc, iv, transform->ivlen, - add_data, add_data_len, /* add data */ - data, rec->data_len, /* source */ - data, &rec->data_len, /* destination */ - data + rec->data_len, transform->taglen ) ) != 0 ) + add_data, add_data_len, + data, rec->data_len, /* src */ + data, rec->buf_len - (data - rec->buf), /* dst */ + &rec->data_len, + transform->taglen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); return( ret ); } MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", - data + rec->data_len, transform->taglen ); + data + rec->data_len - transform->taglen, + transform->taglen ); /* Account for authentication tag. */ - rec->data_len += transform->taglen; post_avail -= transform->taglen; /* @@ -1045,45 +1046,128 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) /* - * Constant-flow conditional memcpy: - * - if c1 == c2, equivalent to memcpy(dst, src, len), - * - otherwise, a no-op, - * but with execution flow independent of the values of c1 and c2. + * Turn a bit into a mask: + * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1 + * - if bit == 0, return the all-bits 0 mask, aka 0 * - * Use only bit operations to avoid branches that could be used by some - * compilers on some platforms to translate comparison operators. + * This function can be used to write constant-time code by replacing branches + * with bit operations using masks. + * + * This function is implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. */ -static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst, - const unsigned char *src, - size_t len, - size_t c1, size_t c2 ) +static size_t mbedtls_ssl_cf_mask_from_bit( size_t bit ) { - /* diff = 0 if c1 == c2, non-zero otherwise */ - const size_t diff = c1 ^ c2; - /* MSVC has a warning about unary minus on unsigned integer types, * but this is well-defined and precisely what we want to do here. */ #if defined(_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4146 ) #endif + return -bit; +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif +} - /* diff_msb's most significant bit is equal to c1 != c2 */ - const size_t diff_msb = ( diff | -diff ); +/* + * Constant-flow mask generation for "less than" comparison: + * - if x < y, return all bits 1, that is (size_t) -1 + * - otherwise, return all bits 0, that is 0 + * + * This function can be used to write constant-time code by replacing branches + * with bit operations using masks. + * + * This function is implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. + */ +static size_t mbedtls_ssl_cf_mask_lt( size_t x, size_t y ) +{ + /* This has the most significant bit set if and only if x < y */ + const size_t sub = x - y; - /* diff1 = c1 != c2 */ - const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); + /* sub1 = (x < y) ? 1 : 0 */ + const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 ); + + /* mask = (x < y) ? 0xff... : 0x00... */ + const size_t mask = mbedtls_ssl_cf_mask_from_bit( sub1 ); + + return( mask ); +} + +/* + * Constant-flow mask generation for "greater or equal" comparison: + * - if x >= y, return all bits 1, that is (size_t) -1 + * - otherwise, return all bits 0, that is 0 + * + * This function can be used to write constant-time code by replacing branches + * with bit operations using masks. + * + * This function is implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. + */ +static size_t mbedtls_ssl_cf_mask_ge( size_t x, size_t y ) +{ + return( ~mbedtls_ssl_cf_mask_lt( x, y ) ); +} + +/* + * Constant-flow boolean "equal" comparison: + * return x == y + * + * This function can be used to write constant-time code by replacing branches + * with bit operations - it can be used in conjunction with + * mbedtls_ssl_cf_mask_from_bit(). + * + * This function is implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. + */ +static size_t mbedtls_ssl_cf_bool_eq( size_t x, size_t y ) +{ + /* diff = 0 if x == y, non-zero otherwise */ + const size_t diff = x ^ y; - /* mask = c1 != c2 ? 0xff : 0x00 */ - const unsigned char mask = (unsigned char) -diff1; + /* MSVC has a warning about unary minus on unsigned integer types, + * but this is well-defined and precisely what we want to do here. */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + + /* diff_msb's most significant bit is equal to x != y */ + const size_t diff_msb = ( diff | -diff ); #if defined(_MSC_VER) #pragma warning( pop ) #endif - /* dst[i] = c1 != c2 ? dst[i] : src[i] */ + /* diff1 = (x != y) ? 1 : 0 */ + const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); + + return( 1 ^ diff1 ); +} + +/* + * Constant-flow conditional memcpy: + * - if c1 == c2, equivalent to memcpy(dst, src, len), + * - otherwise, a no-op, + * but with execution flow independent of the values of c1 and c2. + * + * This function is implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. + */ +static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst, + const unsigned char *src, + size_t len, + size_t c1, size_t c2 ) +{ + /* mask = c1 == c2 ? 0xff : 0x00 */ + const size_t equal = mbedtls_ssl_cf_bool_eq( c1, c2 ); + const unsigned char mask = (unsigned char) mbedtls_ssl_cf_mask_from_bit( equal ); + + /* dst[i] = c1 == c2 ? src[i] : dst[i] */ for( size_t i = 0; i < len; i++ ) - dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask ); + dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask ); } /* @@ -1301,7 +1385,9 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, /* Check that there's space for the authentication tag. */ if( rec->data_len < transform->taglen ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < taglen (%d) " ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < taglen (%d) ", + rec->data_len, + transform->taglen ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); } rec->data_len -= transform->taglen; @@ -1337,12 +1423,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, /* * Decrypt and authenticate */ - if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec, + if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec, iv, transform->ivlen, add_data, add_data_len, - data, rec->data_len, - data, &olen, - data + rec->data_len, + data, rec->data_len + transform->taglen, /* src */ + data, rec->buf_len - (data - rec->buf), &olen, /* dst */ transform->taglen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); @@ -1528,8 +1613,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, if( auth_done == 1 ) { - correct *= ( rec->data_len >= padlen + 1 ); - padlen *= ( rec->data_len >= padlen + 1 ); + const size_t mask = mbedtls_ssl_cf_mask_ge( + rec->data_len, + padlen + 1 ); + correct &= mask; + padlen &= mask; } else { @@ -1543,8 +1631,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, } #endif - correct *= ( rec->data_len >= transform->maclen + padlen + 1 ); - padlen *= ( rec->data_len >= transform->maclen + padlen + 1 ); + const size_t mask = mbedtls_ssl_cf_mask_ge( + rec->data_len, + transform->maclen + padlen + 1 ); + correct &= mask; + padlen &= mask; } padlen++; @@ -1555,6 +1646,10 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, #if defined(MBEDTLS_SSL_PROTO_SSL3) if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { + /* This is the SSL 3.0 path, we don't have to worry about Lucky + * 13, because there's a strictly worse padding attack built in + * the protocol (known as part of POODLE), so we don't care if the + * code is not constant-time, in particular branches are OK. */ if( padlen > transform->ivlen ) { #if defined(MBEDTLS_SSL_DEBUG_ALL) @@ -1578,7 +1673,6 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, * `min(256,plaintext_len)` reads (but take into account * only the last `padlen` bytes for the padding check). */ size_t pad_count = 0; - size_t real_count = 0; volatile unsigned char* const check = data; /* Index of first padding byte; it has been ensured above @@ -1590,16 +1684,21 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, for( idx = start_idx; idx < rec->data_len; idx++ ) { - real_count |= ( idx >= padding_idx ); - pad_count += real_count * ( check[idx] == padlen - 1 ); + /* pad_count += (idx >= padding_idx) && + * (check[idx] == padlen - 1); + */ + const size_t mask = mbedtls_ssl_cf_mask_ge( idx, padding_idx ); + const size_t equal = mbedtls_ssl_cf_bool_eq( check[idx], + padlen - 1 ); + pad_count += mask & equal; } - correct &= ( pad_count == padlen ); + correct &= mbedtls_ssl_cf_bool_eq( pad_count, padlen ); #if defined(MBEDTLS_SSL_DEBUG_ALL) if( padlen > 0 && correct == 0 ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); #endif - padlen &= correct * 0x1FF; + padlen &= mbedtls_ssl_cf_mask_from_bit( correct ); } else #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ @@ -1921,14 +2020,6 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { uint32_t timeout; - /* Just to be sure */ - if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " - "mbedtls_ssl_set_timer_cb() for DTLS" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - /* * The point is, we need to always read a full datagram at once, so we * sometimes read more then requested, and handle the additional data. diff --git a/connectivity/mbedtls/source/ssl_srv.c b/connectivity/mbedtls/source/ssl_srv.c index 2e63fced35b..e33b828add3 100644 --- a/connectivity/mbedtls/source/ssl_srv.c +++ b/connectivity/mbedtls/source/ssl_srv.c @@ -157,7 +157,7 @@ static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf ) return( 1 ); #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) ) return( 1 ); #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -172,13 +172,13 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) /* If we've used a callback to select the PSK, * the static configuration is irrelevant. */ - if( ssl->handshake->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) ) return( 1 ); return( 0 ); } - if( ssl->conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) ) return( 1 ); return( 0 ); @@ -776,6 +776,126 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET; + size_t i,j; + size_t profile_length; + uint16_t mki_length; + /*! 2 bytes for profile length and 1 byte for mki len */ + const size_t size_of_lengths = 3; + + /* If use_srtp is not configured, just ignore the extension */ + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + { + return( 0 ); + } + + /* RFC5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + */ + + /* + * Min length is 5: at least one protection profile(2 bytes) + * and length(2 bytes) + srtp_mki length(1 byte) + * Check here that we have at least 2 bytes of protection profiles length + * and one of srtp_mki length + */ + if( len < size_of_lengths ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; + + /* first 2 bytes are protection profile length(in bytes) */ + profile_length = ( buf[0] << 8 ) | buf[1]; + buf += 2; + + /* The profile length cannot be bigger than input buffer size - lengths fields */ + if( profile_length > len - size_of_lengths || + profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */ + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + /* + * parse the extension list values are defined in + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + */ + for( j = 0; j < profile_length; j += 2 ) + { + uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1]; + client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value ); + + if( client_protection != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + } + else + { + continue; + } + /* check if suggested profile is in our list */ + for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) + { + if( client_protection == ssl->conf->dtls_srtp_profile_list[i] ) + { + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + break; + } + } + if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET ) + break; + } + buf += profile_length; /* buf points to the mki length */ + mki_length = *buf; + buf++; + + if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH || + mki_length + profile_length + size_of_lengths != len ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Parse the mki only if present and mki is supported locally */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED && + mki_length > 0 ) + { + ssl->dtls_srtp_info.mki_len = mki_length; + + memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "using mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Auxiliary functions for ServerHello parsing and related actions */ @@ -1942,6 +2062,16 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + case MBEDTLS_TLS_EXT_USE_SRTP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) ); + + ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + default: MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", ext_id ) ); @@ -2500,6 +2630,78 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS) +static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + size_t mki_len = 0, ext_len = 0; + uint16_t profile_value = 0; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + *olen = 0; + + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) ); + + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + + /* The extension total size is 9 bytes : + * - 2 bytes for the extension tag + * - 2 bytes for the total size + * - 2 bytes for the protection profile length + * - 2 bytes for the protection profile + * - 1 byte for the mki length + * + the actual mki length + * Check we have enough room in the output buffer */ + if( (size_t)( end - buf ) < mki_len + 9 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* extension */ + buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_USE_SRTP ) & 0xFF ); + /* + * total length 5 and mki value: only one profile(2 bytes) + * and length(2 bytes) and srtp_mki ) + */ + ext_len = 5 + mki_len; + buf[2] = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ext_len & 0xFF ); + + /* protection profile length: 2 */ + buf[4] = 0x00; + buf[5] = 0x02; + profile_value = mbedtls_ssl_check_srtp_profile_value( + ssl->dtls_srtp_info.chosen_dtls_srtp_profile ); + if( profile_value != MBEDTLS_TLS_SRTP_UNSET ) + { + buf[6] = (unsigned char)( ( profile_value >> 8 ) & 0xFF ); + buf[7] = (unsigned char)( profile_value & 0xFF ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) ); + return; + } + + buf[8] = mki_len & 0xFF; + memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len ); + + *olen = 9 + mki_len; +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) { @@ -2788,6 +2990,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); if( ext_len > 0 ) @@ -3722,11 +3929,12 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, /* In case of a failure in decryption, the decryption may write less than * 2 bytes of output, but we always read the first two bytes. It doesn't * matter in the end because diff will be nonzero in that case due to - * peer_pmslen being less than 48, and we only care whether diff is 0. - * But do initialize peer_pms for robustness anyway. This also makes - * memory analyzers happy (don't access uninitialized memory, even - * if it's an unsigned char). */ + * ret being nonzero, and we only care whether diff is 0. + * But do initialize peer_pms and peer_pmslen for robustness anyway. This + * also makes memory analyzers happy (don't access uninitialized memory, + * even if it's an unsigned char). */ peer_pms[0] = peer_pms[1] = ~0; + peer_pmslen = 0; ret = ssl_decrypt_encrypted_pms( ssl, p, end, peer_pms, diff --git a/connectivity/mbedtls/source/ssl_ticket.c b/connectivity/mbedtls/source/ssl_ticket.c index e3e802315a8..626d137cc64 100644 --- a/connectivity/mbedtls/source/ssl_ticket.c +++ b/connectivity/mbedtls/source/ssl_ticket.c @@ -209,7 +209,6 @@ int mbedtls_ssl_ticket_write( void *p_ticket, unsigned char *iv = start + TICKET_KEY_NAME_BYTES; unsigned char *state_len_bytes = iv + TICKET_IV_BYTES; unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES; - unsigned char *tag; size_t clear_len, ciph_len; *tlen = 0; @@ -250,23 +249,23 @@ int mbedtls_ssl_ticket_write( void *p_ticket, state_len_bytes[1] = ( clear_len ) & 0xff; /* Encrypt and authenticate */ - tag = state + clear_len; - if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, + if( ( ret = mbedtls_cipher_auth_encrypt_ext( &key->ctx, iv, TICKET_IV_BYTES, /* Additional data: key name, IV and length */ key_name, TICKET_ADD_DATA_LEN, - state, clear_len, state, &ciph_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) + state, clear_len, + state, end - state, &ciph_len, + TICKET_AUTH_TAG_BYTES ) ) != 0 ) { goto cleanup; } - if( ciph_len != clear_len ) + if( ciph_len != clear_len + TICKET_AUTH_TAG_BYTES ) { ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; goto cleanup; } - *tlen = TICKET_MIN_LEN + ciph_len; + *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES; cleanup: #if defined(MBEDTLS_THREADING_C) @@ -308,7 +307,6 @@ int mbedtls_ssl_ticket_parse( void *p_ticket, unsigned char *iv = buf + TICKET_KEY_NAME_BYTES; unsigned char *enc_len_p = iv + TICKET_IV_BYTES; unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES; - unsigned char *tag; size_t enc_len, clear_len; if( ctx == NULL || ctx->f_rng == NULL ) @@ -326,7 +324,6 @@ int mbedtls_ssl_ticket_parse( void *p_ticket, goto cleanup; enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; - tag = ticket + enc_len; if( len != TICKET_MIN_LEN + enc_len ) { @@ -344,13 +341,13 @@ int mbedtls_ssl_ticket_parse( void *p_ticket, } /* Decrypt and authenticate */ - if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, + if( ( ret = mbedtls_cipher_auth_decrypt_ext( &key->ctx, iv, TICKET_IV_BYTES, /* Additional data: key name, IV and length */ key_name, TICKET_ADD_DATA_LEN, - ticket, enc_len, - ticket, &clear_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) + ticket, enc_len + TICKET_AUTH_TAG_BYTES, + ticket, enc_len, &clear_len, + TICKET_AUTH_TAG_BYTES ) ) != 0 ) { if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) ret = MBEDTLS_ERR_SSL_INVALID_MAC; diff --git a/connectivity/mbedtls/source/ssl_tls.c b/connectivity/mbedtls/source/ssl_tls.c index 7062d53b788..a1a5859f056 100644 --- a/connectivity/mbedtls/source/ssl_tls.c +++ b/connectivity/mbedtls/source/ssl_tls.c @@ -446,7 +446,7 @@ static int tls1_prf( const unsigned char *secret, size_t slen, #if defined(MBEDTLS_USE_PSA_CRYPTO) static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation, - psa_key_handle_t slot, + psa_key_id_t key, psa_algorithm_t alg, const unsigned char* seed, size_t seed_length, const unsigned char* label, size_t label_length, @@ -466,7 +466,7 @@ static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* de if( status != PSA_SUCCESS ) return( status ); - if( slot == 0 ) + if( mbedtls_svc_key_id_is_null( key ) ) { status = psa_key_derivation_input_bytes( derivation, PSA_KEY_DERIVATION_INPUT_SECRET, @@ -475,8 +475,7 @@ static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* de else { status = psa_key_derivation_input_key( - derivation, PSA_KEY_DERIVATION_INPUT_SECRET, - slot ); + derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key ); } if( status != PSA_SUCCESS ) return( status ); @@ -507,7 +506,7 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, { psa_status_t status; psa_algorithm_t alg; - psa_key_handle_t master_slot = 0; + psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_derivation_operation_t derivation = PSA_KEY_DERIVATION_OPERATION_INIT; @@ -521,7 +520,7 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, * this PRF is also used to derive an IV, in particular in EAP-TLS, * and for this use case it makes sense to have a 0-length "secret". * Since the key API doesn't allow importing a key of length 0, - * keep master_slot=0, which setup_psa_key_derivation() understands + * keep master_key=0, which setup_psa_key_derivation() understands * to mean a 0-length "secret" input. */ if( slen != 0 ) { @@ -530,13 +529,13 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, psa_set_key_algorithm( &key_attributes, alg ); psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE ); - status = psa_import_key( &key_attributes, secret, slen, &master_slot ); + status = psa_import_key( &key_attributes, secret, slen, &master_key ); if( status != PSA_SUCCESS ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } status = setup_psa_key_derivation( &derivation, - master_slot, alg, + master_key, alg, random, rlen, (unsigned char const *) label, (size_t) strlen( label ), @@ -544,7 +543,7 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, if( status != PSA_SUCCESS ) { psa_key_derivation_abort( &derivation ); - psa_destroy_key( master_slot ); + psa_destroy_key( master_key ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } @@ -552,19 +551,19 @@ static int tls_prf_generic( mbedtls_md_type_t md_type, if( status != PSA_SUCCESS ) { psa_key_derivation_abort( &derivation ); - psa_destroy_key( master_slot ); + psa_destroy_key( master_key ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } status = psa_key_derivation_abort( &derivation ); if( status != PSA_SUCCESS ) { - psa_destroy_key( master_slot ); + psa_destroy_key( master_key ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } - if( master_slot != 0 ) - status = psa_destroy_key( master_slot ); + if( ! mbedtls_svc_key_id_is_null( master_key ) ) + status = psa_destroy_key( master_key ); if( status != PSA_SUCCESS ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); @@ -681,20 +680,20 @@ static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ) #endif #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char *, size_t * ); +static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char*, size_t * ); static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char *, size_t * ); +static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char*, size_t * ); static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); #endif #if defined(MBEDTLS_SHA512_C) static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char *, size_t * ); +static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char*, size_t * ); static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ @@ -707,13 +706,13 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) { /* If we've used a callback to select the PSK, * the static configuration is irrelevant. */ - if( ssl->handshake->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) ) return( 1 ); return( 0 ); } - if( ssl->conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) ) return( 1 ); return( 0 ); @@ -1514,7 +1513,7 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, /* Perform PSK-to-MS expansion in a single step. */ psa_status_t status; psa_algorithm_t alg; - psa_key_handle_t psk; + psa_key_id_t psk; psa_key_derivation_operation_t derivation = PSA_KEY_DERIVATION_OPERATION_INIT; mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac; @@ -1668,7 +1667,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_SSL3) void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, - unsigned char hash[36], + unsigned char *hash, size_t *hlen ) { mbedtls_md5_context md5; @@ -1721,7 +1720,7 @@ void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, - unsigned char hash[36], + unsigned char *hash, size_t *hlen ) { mbedtls_md5_context md5; @@ -1753,7 +1752,7 @@ void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SHA256_C) void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, - unsigned char hash[32], + unsigned char *hash, size_t *hlen ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) @@ -1802,7 +1801,7 @@ void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SHA512_C) void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, - unsigned char hash[48], + unsigned char *hash, size_t *hlen ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) @@ -3198,6 +3197,9 @@ static void ssl_calc_finished_tls_sha256( #endif /* MBEDTLS_SHA256_C */ #if defined(MBEDTLS_SHA512_C) + +typedef int (*finish_sha384_t)(mbedtls_sha512_context*, unsigned char*); + static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *buf, int from ) { @@ -3256,8 +3258,14 @@ static void ssl_calc_finished_tls_sha384( MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) sha512.state, sizeof( sha512.state ) ); #endif + /* + * For SHA-384, we can save 16 bytes by keeping padbuf 48 bytes long. + * However, to avoid stringop-overflow warning in gcc, we have to cast + * mbedtls_sha512_finish_ret(). + */ + finish_sha384_t finish = (finish_sha384_t)mbedtls_sha512_finish_ret; + finish( &sha512, padbuf ); - mbedtls_sha512_finish_ret( &sha512, padbuf ); mbedtls_sha512_free( &sha512 ); #endif @@ -3859,6 +3867,10 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, mbedtls_ssl_reset_in_out_pointers( ssl ); +#if defined(MBEDTLS_SSL_DTLS_SRTP) + memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) ); +#endif + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) goto error; @@ -4340,11 +4352,11 @@ static void ssl_conf_remove_psk( mbedtls_ssl_config *conf ) { /* Remove reference to existing PSK, if any. */ #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) ) { /* The maintenance of the PSK key slot is the * user's responsibility. */ - conf->psk_opaque = 0; + conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; } /* This and the following branch should never * be taken simultaenously as we maintain the @@ -4428,9 +4440,9 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, static void ssl_remove_psk( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ssl->handshake->psk_opaque != 0 ) + if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) ) { - ssl->handshake->psk_opaque = 0; + ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT; } else #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -4465,7 +4477,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_USE_PSA_CRYPTO) int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, - psa_key_handle_t psk_slot, + psa_key_id_t psk, const unsigned char *psk_identity, size_t psk_identity_len ) { @@ -4474,9 +4486,9 @@ int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, ssl_conf_remove_psk( conf ); /* Check and set opaque PSK */ - if( psk_slot == 0 ) + if( mbedtls_svc_key_id_is_null( psk ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - conf->psk_opaque = psk_slot; + conf->psk_opaque = psk; /* Check and set PSK Identity */ ret = ssl_conf_set_psk_identity( conf, psk_identity, @@ -4488,13 +4500,14 @@ int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, } int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl, - psa_key_handle_t psk_slot ) + psa_key_id_t psk ) { - if( psk_slot == 0 || ssl->handshake == NULL ) + if( ( mbedtls_svc_key_id_is_null( psk ) ) || + ( ssl->handshake == NULL ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); ssl_remove_psk( ssl ); - ssl->handshake->psk_opaque = psk_slot; + ssl->handshake->psk_opaque = psk; return( 0 ); } #endif /* MBEDTLS_USE_PSA_CRYPTO */ @@ -4685,6 +4698,86 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, + int support_mki_value ) +{ + conf->dtls_srtp_mki_support = support_mki_value; +} + +int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, + unsigned char *mki_value, + uint16_t mki_len ) +{ + if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED ) + { + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len ); + ssl->dtls_srtp_info.mki_len = mki_len; + return( 0 ); +} + +int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf, + const mbedtls_ssl_srtp_profile *profiles ) +{ + const mbedtls_ssl_srtp_profile *p; + size_t list_size = 0; + + /* check the profiles list: all entry must be valid, + * its size cannot be more than the total number of supported profiles, currently 4 */ + for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET && + list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH; + p++ ) + { + if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET ) + { + list_size++; + } + else + { + /* unsupported value, stop parsing and set the size to an error value */ + list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1; + } + } + + if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH ) + { + conf->dtls_srtp_profile_list = NULL; + conf->dtls_srtp_profile_list_len = 0; + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + conf->dtls_srtp_profile_list = profiles; + conf->dtls_srtp_profile_list_len = list_size; + + return( 0 ); +} + +void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, + mbedtls_dtls_srtp_info *dtls_srtp_info ) +{ + dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile; + /* do not copy the mki value if there is no chosen profile */ + if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) + { + dtls_srtp_info->mki_len = 0; + } + else + { + dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len; + memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) { conf->max_major_ver = major; @@ -5682,11 +5775,24 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) { int ret = 0; + /* Sanity checks */ + if( ssl == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " + "mbedtls_ssl_set_timer_cb() for DTLS" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); + /* Main handshake loop */ while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake_step( ssl ); diff --git a/connectivity/mbedtls/source/ssl_tls13_keys.c b/connectivity/mbedtls/source/ssl_tls13_keys.c new file mode 100644 index 00000000000..c39e0322ba0 --- /dev/null +++ b/connectivity/mbedtls/source/ssl_tls13_keys.c @@ -0,0 +1,349 @@ +/* + * TLS 1.3 key schedule + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 ( the "License" ); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + +#include "mbedtls/hkdf.h" +#include "mbedtls/ssl_internal.h" +#include "ssl_tls13_keys.h" + +#include +#include + +#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \ + .name = string, + +struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels = +{ + /* This seems to work in C, despite the string literal being one + * character too long due to the 0-termination. */ + MBEDTLS_SSL_TLS1_3_LABEL_LIST +}; + +#undef MBEDTLS_SSL_TLS1_3_LABEL + +/* + * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule. + * + * The HkdfLabel is specified in RFC 8446 as follows: + * + * struct HkdfLabel { + * uint16 length; // Length of expanded key material + * opaque label<7..255>; // Always prefixed by "tls13 " + * opaque context<0..255>; // Usually a communication transcript hash + * }; + * + * Parameters: + * - desired_length: Length of expanded key material + * Even though the standard allows expansion to up to + * 2**16 Bytes, TLS 1.3 never uses expansion to more than + * 255 Bytes, so we require `desired_length` to be at most + * 255. This allows us to save a few Bytes of code by + * hardcoding the writing of the high bytes. + * - (label, llen): label + label length, without "tls13 " prefix + * The label length MUST be less than or equal to + * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN + * It is the caller's responsibility to ensure this. + * All (label, label length) pairs used in TLS 1.3 + * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). + * - (ctx, clen): context + context length + * The context length MUST be less than or equal to + * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN + * It is the caller's responsibility to ensure this. + * - dst: Target buffer for HkdfLabel structure, + * This MUST be a writable buffer of size + * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes. + * - dlen: Pointer at which to store the actual length of + * the HkdfLabel structure on success. + */ + +static const char tls1_3_label_prefix[6] = "tls13 "; + +#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \ + ( 2 /* expansion length */ \ + + 1 /* label length */ \ + + label_len \ + + 1 /* context length */ \ + + context_len ) + +#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ + SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ + sizeof(tls1_3_label_prefix) + \ + MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \ + MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) + +static void ssl_tls1_3_hkdf_encode_label( + size_t desired_length, + const unsigned char *label, size_t llen, + const unsigned char *ctx, size_t clen, + unsigned char *dst, size_t *dlen ) +{ + size_t total_label_len = + sizeof(tls1_3_label_prefix) + llen; + size_t total_hkdf_lbl_len = + SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen ); + + unsigned char *p = dst; + + /* Add the size of the expanded key material. + * We're hardcoding the high byte to 0 here assuming that we never use + * TLS 1.3 HKDF key expansion to more than 255 Bytes. */ +#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255 +#error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \ + value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN" +#endif + + *p++ = 0; + *p++ = (unsigned char)( ( desired_length >> 0 ) & 0xFF ); + + /* Add label incl. prefix */ + *p++ = (unsigned char)( total_label_len & 0xFF ); + memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) ); + p += sizeof(tls1_3_label_prefix); + memcpy( p, label, llen ); + p += llen; + + /* Add context value */ + *p++ = (unsigned char)( clen & 0xFF ); + if( clen != 0 ) + memcpy( p, ctx, clen ); + + /* Return total length to the caller. */ + *dlen = total_hkdf_lbl_len; +} + +int mbedtls_ssl_tls1_3_hkdf_expand_label( + mbedtls_md_type_t hash_alg, + const unsigned char *secret, size_t slen, + const unsigned char *label, size_t llen, + const unsigned char *ctx, size_t clen, + unsigned char *buf, size_t blen ) +{ + const mbedtls_md_info_t *md; + unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ]; + size_t hkdf_label_len; + + if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN ) + { + /* Should never happen since this is an internal + * function, and we know statically which labels + * are allowed. */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) + { + /* Should not happen, as above. */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN ) + { + /* Should not happen, as above. */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + md = mbedtls_md_info_from_type( hash_alg ); + if( md == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + ssl_tls1_3_hkdf_encode_label( blen, + label, llen, + ctx, clen, + hkdf_label, + &hkdf_label_len ); + + return( mbedtls_hkdf_expand( md, + secret, slen, + hkdf_label, hkdf_label_len, + buf, blen ) ); +} + +/* + * The traffic keying material is generated from the following inputs: + * + * - One secret value per sender. + * - A purpose value indicating the specific value being generated + * - The desired lengths of key and IV. + * + * The expansion itself is based on HKDF: + * + * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length ) + * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length ) + * + * [sender] denotes the sending side and the Secret value is provided + * by the function caller. Note that we generate server and client side + * keys in a single function call. + */ +int mbedtls_ssl_tls1_3_make_traffic_keys( + mbedtls_md_type_t hash_alg, + const unsigned char *client_secret, + const unsigned char *server_secret, + size_t slen, size_t key_len, size_t iv_len, + mbedtls_ssl_key_set *keys ) +{ + int ret = 0; + + ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, + client_secret, slen, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), + NULL, 0, + keys->client_write_key, key_len ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, + server_secret, slen, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), + NULL, 0, + keys->server_write_key, key_len ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, + client_secret, slen, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), + NULL, 0, + keys->client_write_iv, iv_len ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, + server_secret, slen, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), + NULL, 0, + keys->server_write_iv, iv_len ); + if( ret != 0 ) + return( ret ); + + keys->key_len = key_len; + keys->iv_len = iv_len; + + return( 0 ); +} + +int mbedtls_ssl_tls1_3_derive_secret( + mbedtls_md_type_t hash_alg, + const unsigned char *secret, size_t slen, + const unsigned char *label, size_t llen, + const unsigned char *ctx, size_t clen, + int ctx_hashed, + unsigned char *dstbuf, size_t buflen ) +{ + int ret; + unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ]; + + const mbedtls_md_info_t *md; + md = mbedtls_md_info_from_type( hash_alg ); + if( md == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED ) + { + ret = mbedtls_md( md, ctx, clen, hashed_context ); + if( ret != 0 ) + return( ret ); + clen = mbedtls_md_get_size( md ); + } + else + { + if( clen > sizeof(hashed_context) ) + { + /* This should never happen since this function is internal + * and the code sets `ctx_hashed` correctly. + * Let's double-check nonetheless to not run at the risk + * of getting a stack overflow. */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( hashed_context, ctx, clen ); + } + + return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, + secret, slen, + label, llen, + hashed_context, clen, + dstbuf, buflen ) ); +} + +int mbedtls_ssl_tls1_3_evolve_secret( + mbedtls_md_type_t hash_alg, + const unsigned char *secret_old, + const unsigned char *input, size_t input_len, + unsigned char *secret_new ) +{ + int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + size_t hlen, ilen; + unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 }; + unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 }; + + const mbedtls_md_info_t *md; + md = mbedtls_md_info_from_type( hash_alg ); + if( md == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + hlen = mbedtls_md_get_size( md ); + + /* For non-initial runs, call Derive-Secret( ., "derived", "") + * on the old secret. */ + if( secret_old != NULL ) + { + ret = mbedtls_ssl_tls1_3_derive_secret( + hash_alg, + secret_old, hlen, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ), + NULL, 0, /* context */ + MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, + tmp_secret, hlen ); + if( ret != 0 ) + goto cleanup; + } + + if( input != NULL ) + { + memcpy( tmp_input, input, input_len ); + ilen = input_len; + } + else + { + ilen = hlen; + } + + /* HKDF-Extract takes a salt and input key material. + * The salt is the old secret, and the input key material + * is the input secret (PSK / ECDHE). */ + ret = mbedtls_hkdf_extract( md, + tmp_secret, hlen, + tmp_input, ilen, + secret_new ); + if( ret != 0 ) + goto cleanup; + + ret = 0; + + cleanup: + + mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) ); + mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) ); + return( ret ); +} + +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ diff --git a/connectivity/mbedtls/source/ssl_tls13_keys.h b/connectivity/mbedtls/source/ssl_tls13_keys.h new file mode 100644 index 00000000000..7089049ce2c --- /dev/null +++ b/connectivity/mbedtls/source/ssl_tls13_keys.h @@ -0,0 +1,274 @@ +/* + * TLS 1.3 key schedule + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 ( the "License" ); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#if !defined(MBEDTLS_SSL_TLS1_3_KEYS_H) +#define MBEDTLS_SSL_TLS1_3_KEYS_H + +/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at + * the point of use. See e.g. the definition of mbedtls_ssl_tls1_3_labels_union + * below. */ +#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \ + MBEDTLS_SSL_TLS1_3_LABEL( finished , "finished" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( resumption , "resumption" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( exporter , "exporter" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( key , "key" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( iv , "iv" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( res_master , "res master" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( exp_master , "exp master" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( ext_binder , "ext binder" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( res_binder , "res binder" ) \ + MBEDTLS_SSL_TLS1_3_LABEL( derived , "derived" ) + +#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \ + const unsigned char name [ sizeof(string) - 1 ]; + +union mbedtls_ssl_tls1_3_labels_union +{ + MBEDTLS_SSL_TLS1_3_LABEL_LIST +}; +struct mbedtls_ssl_tls1_3_labels_struct +{ + MBEDTLS_SSL_TLS1_3_LABEL_LIST +}; +#undef MBEDTLS_SSL_TLS1_3_LABEL + +extern const struct mbedtls_ssl_tls1_3_labels_struct mbedtls_ssl_tls1_3_labels; + +#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( LABEL ) \ + mbedtls_ssl_tls1_3_labels.LABEL, \ + sizeof(mbedtls_ssl_tls1_3_labels.LABEL) + +#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \ + sizeof( union mbedtls_ssl_tls1_3_labels_union ) + +/* The maximum length of HKDF contexts used in the TLS 1.3 standard. + * Since contexts are always hashes of message transcripts, this can + * be approximated from above by the maximum hash size. */ +#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \ + MBEDTLS_MD_MAX_SIZE + +/* Maximum desired length for expanded key material generated + * by HKDF-Expand-Label. + * + * Warning: If this ever needs to be increased, the implementation + * ssl_tls1_3_hkdf_encode_label() in ssl_tls13_keys.c needs to be + * adjusted since it currently assumes that HKDF key expansion + * is never used with more than 255 Bytes of output. */ +#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255 + +/** + * \brief The \c HKDF-Expand-Label function from + * the TLS 1.3 standard RFC 8446. + * + * + * HKDF-Expand-Label( Secret, Label, Context, Length ) = + * HKDF-Expand( Secret, HkdfLabel, Length ) + * + * + * \param hash_alg The identifier for the hash algorithm to use. + * \param secret The \c Secret argument to \c HKDF-Expand-Label. + * This must be a readable buffer of length \p slen Bytes. + * \param slen The length of \p secret in Bytes. + * \param label The \c Label argument to \c HKDF-Expand-Label. + * This must be a readable buffer of length \p llen Bytes. + * \param llen The length of \p label in Bytes. + * \param ctx The \c Context argument to \c HKDF-Expand-Label. + * This must be a readable buffer of length \p clen Bytes. + * \param clen The length of \p context in Bytes. + * \param buf The destination buffer to hold the expanded secret. + * This must be a writable buffer of length \p blen Bytes. + * \param blen The desired size of the expanded secret in Bytes. + * + * \returns \c 0 on success. + * \return A negative error code on failure. + */ + +int mbedtls_ssl_tls1_3_hkdf_expand_label( + mbedtls_md_type_t hash_alg, + const unsigned char *secret, size_t slen, + const unsigned char *label, size_t llen, + const unsigned char *ctx, size_t clen, + unsigned char *buf, size_t blen ); + +/** + * \brief This function is part of the TLS 1.3 key schedule. + * It extracts key and IV for the actual client/server traffic + * from the client/server traffic secrets. + * + * From RFC 8446: + * + * + * [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length) + * [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)* + * + * + * \param hash_alg The identifier for the hash algorithm to be used + * for the HKDF-based expansion of the secret. + * \param client_secret The client traffic secret. + * This must be a readable buffer of size \p slen Bytes + * \param server_secret The server traffic secret. + * This must be a readable buffer of size \p slen Bytes + * \param slen Length of the secrets \p client_secret and + * \p server_secret in Bytes. + * \param key_len The desired length of the key to be extracted in Bytes. + * \param iv_len The desired length of the IV to be extracted in Bytes. + * \param keys The address of the structure holding the generated + * keys and IVs. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ + +int mbedtls_ssl_tls1_3_make_traffic_keys( + mbedtls_md_type_t hash_alg, + const unsigned char *client_secret, + const unsigned char *server_secret, + size_t slen, size_t key_len, size_t iv_len, + mbedtls_ssl_key_set *keys ); + + +#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0 +#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1 + +/** + * \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446. + * + * + * Derive-Secret( Secret, Label, Messages ) = + * HKDF-Expand-Label( Secret, Label, + * Hash( Messages ), + * Hash.Length ) ) + * + * + * \param hash_alg The identifier for the hash function used for the + * applications of HKDF. + * \param secret The \c Secret argument to the \c Derive-Secret function. + * This must be a readable buffer of length \p slen Bytes. + * \param slen The length of \p secret in Bytes. + * \param label The \c Label argument to the \c Derive-Secret function. + * This must be a readable buffer of length \p llen Bytes. + * \param llen The length of \p label in Bytes. + * \param ctx The hash of the \c Messages argument to the + * \c Derive-Secret function, or the \c Messages argument + * itself, depending on \p context_already_hashed. + * \param clen The length of \p hash. + * \param ctx_hashed This indicates whether the \p ctx contains the hash of + * the \c Messages argument in the application of the + * \c Derive-Secret function + * (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether + * it is the content of \c Messages itself, in which case + * the function takes care of the hashing + * (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED). + * \param dstbuf The target buffer to write the output of + * \c Derive-Secret to. This must be a writable buffer of + * size \p buflen Bytes. + * \param buflen The length of \p dstbuf in Bytes. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls1_3_derive_secret( + mbedtls_md_type_t hash_alg, + const unsigned char *secret, size_t slen, + const unsigned char *label, size_t llen, + const unsigned char *ctx, size_t clen, + int ctx_hashed, + unsigned char *dstbuf, size_t buflen ); + +/** + * \brief Compute the next secret in the TLS 1.3 key schedule + * + * The TLS 1.3 key schedule proceeds as follows to compute + * the three main secrets during the handshake: The early + * secret for early data, the handshake secret for all + * other encrypted handshake messages, and the master + * secret for all application traffic. + * + * + * 0 + * | + * v + * PSK -> HKDF-Extract = Early Secret + * | + * v + * Derive-Secret( ., "derived", "" ) + * | + * v + * (EC)DHE -> HKDF-Extract = Handshake Secret + * | + * v + * Derive-Secret( ., "derived", "" ) + * | + * v + * 0 -> HKDF-Extract = Master Secret + * + * + * Each of the three secrets in turn is the basis for further + * key derivations, such as the derivation of traffic keys and IVs; + * see e.g. mbedtls_ssl_tls1_3_make_traffic_keys(). + * + * This function implements one step in this evolution of secrets: + * + * + * old_secret + * | + * v + * Derive-Secret( ., "derived", "" ) + * | + * v + * input -> HKDF-Extract = new_secret + * + * + * \param hash_alg The identifier for the hash function used for the + * applications of HKDF. + * \param secret_old The address of the buffer holding the old secret + * on function entry. If not \c NULL, this must be a + * readable buffer whose size matches the output size + * of the hash function represented by \p hash_alg. + * If \c NULL, an all \c 0 array will be used instead. + * \param input The address of the buffer holding the additional + * input for the key derivation (e.g., the PSK or the + * ephemeral (EC)DH secret). If not \c NULL, this must be + * a readable buffer whose size \p input_len Bytes. + * If \c NULL, an all \c 0 array will be used instead. + * \param input_len The length of \p input in Bytes. + * \param secret_new The address of the buffer holding the new secret + * on function exit. This must be a writable buffer + * whose size matches the output size of the hash + * function represented by \p hash_alg. + * This may be the same as \p secret_old. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ + +int mbedtls_ssl_tls1_3_evolve_secret( + mbedtls_md_type_t hash_alg, + const unsigned char *secret_old, + const unsigned char *input, size_t input_len, + unsigned char *secret_new ); + +#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ diff --git a/connectivity/mbedtls/source/threading.c b/connectivity/mbedtls/source/threading.c index 9268da1888f..2bb932d2d02 100644 --- a/connectivity/mbedtls/source/threading.c +++ b/connectivity/mbedtls/source/threading.c @@ -42,7 +42,7 @@ #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) /* * This is a convenience shorthand macro to avoid checking the long * preprocessor conditions above. Ideally, we could expose this macro in @@ -57,7 +57,7 @@ #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ - _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ #endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ diff --git a/connectivity/mbedtls/source/version_features.c b/connectivity/mbedtls/source/version_features.c index d2840fa3cd9..42ccaf95407 100644 --- a/connectivity/mbedtls/source/version_features.c +++ b/connectivity/mbedtls/source/version_features.c @@ -417,9 +417,9 @@ static const char * const features[] = { #if defined(MBEDTLS_ENTROPY_NV_SEED) "MBEDTLS_ENTROPY_NV_SEED", #endif /* MBEDTLS_ENTROPY_NV_SEED */ -#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) - "MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER", -#endif /* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */ +#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER", +#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ #if defined(MBEDTLS_MEMORY_DEBUG) "MBEDTLS_MEMORY_DEBUG", #endif /* MBEDTLS_MEMORY_DEBUG */ @@ -435,6 +435,9 @@ static const char * const features[] = { #if defined(MBEDTLS_PKCS1_V21) "MBEDTLS_PKCS1_V21", #endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) + "MBEDTLS_PSA_CRYPTO_DRIVERS", +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */ #if defined(MBEDTLS_PSA_CRYPTO_SPM) "MBEDTLS_PSA_CRYPTO_SPM", #endif /* MBEDTLS_PSA_CRYPTO_SPM */ @@ -531,6 +534,9 @@ static const char * const features[] = { #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) "MBEDTLS_SSL_DTLS_HELLO_VERIFY", #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + "MBEDTLS_SSL_DTLS_SRTP", +#endif /* MBEDTLS_SSL_DTLS_SRTP */ #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ @@ -573,6 +579,9 @@ static const char * const features[] = { #if defined(MBEDTLS_USE_PSA_CRYPTO) "MBEDTLS_USE_PSA_CRYPTO", #endif /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) + "MBEDTLS_PSA_CRYPTO_CONFIG", +#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */ #if defined(MBEDTLS_VERSION_FEATURES) "MBEDTLS_VERSION_FEATURES", #endif /* MBEDTLS_VERSION_FEATURES */ diff --git a/connectivity/mbedtls/source/x509.c b/connectivity/mbedtls/source/x509.c index 1579c1abca6..2a7be329b2c 100644 --- a/connectivity/mbedtls/source/x509.c +++ b/connectivity/mbedtls/source/x509.c @@ -154,7 +154,7 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md return( MBEDTLS_ERR_X509_INVALID_ALG + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - p = (unsigned char *) alg->p; + p = alg->p; end = p + alg->len; if( p >= end ) diff --git a/connectivity/mbedtls/source/x509_crt.c b/connectivity/mbedtls/source/x509_crt.c index 71e9cec3728..a623c57a6c1 100644 --- a/connectivity/mbedtls/source/x509_crt.c +++ b/connectivity/mbedtls/source/x509_crt.c @@ -1304,6 +1304,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, if( crt->sig_oid.len != sig_oid2.len || memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || + sig_params1.tag != sig_params2.tag || sig_params1.len != sig_params2.len || ( sig_params1.len != 0 && memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) diff --git a/connectivity/mbedtls/tools/importer/Makefile b/connectivity/mbedtls/tools/importer/Makefile index bda34cb589d..b1ca284762d 100644 --- a/connectivity/mbedtls/tools/importer/Makefile +++ b/connectivity/mbedtls/tools/importer/Makefile @@ -27,7 +27,7 @@ # # Set the mbed TLS release to import (this can/should be edited before import) -MBED_TLS_RELEASE ?= mbedtls-2.24.0 +MBED_TLS_RELEASE ?= v2.25.0 MBED_TLS_REPO_URL ?= git@github.com:ARMmbed/mbedtls.git # Translate between mbed TLS namespace and mbed namespace diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt index c0db16ec90b..5fc1be9775b 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt @@ -23,6 +23,7 @@ target_sources(mbed-psa INTERFACE mbedtls/psa_crypto.c mbedtls/psa_crypto_se.c + mbedtls/psa_crypto_driver_wrappers.c mbedtls/psa_crypto_slot_management.c mbedtls/psa_crypto_storage.c mbedtls/psa_its_file.c diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto.h index a3161666d79..b41a20bfc45 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto.h @@ -36,16 +36,6 @@ * @{ */ -/** \brief Key handle. - * - * This type represents open handles to keys. It must be an unsigned integral - * type. The choice of type is implementation-dependent. - * - * 0 is not a valid key handle. How other handle values are assigned is - * implementation-dependent. - */ -typedef _unsigned_integral_type_ psa_key_handle_t; - /**@}*/ #endif /* __DOXYGEN_ONLY__ */ @@ -146,11 +136,30 @@ static psa_key_attributes_t psa_key_attributes_init(void); * linkage). This function may be provided as a function-like macro, * but in this case it must evaluate each of its arguments exactly once. * - * \param[out] attributes The attribute structure to write to. - * \param id The persistent identifier for the key. + * \param[out] attributes The attribute structure to write to. + * \param key The persistent identifier for the key. */ -static void psa_set_key_id(psa_key_attributes_t *attributes, - psa_key_id_t id); +static void psa_set_key_id( psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t key ); + +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +/** Set the owner identifier of a key. + * + * When key identifiers encode key owner identifiers, psa_set_key_id() does + * not allow to define in key attributes the owner of volatile keys as + * psa_set_key_id() enforces the key to be persistent. + * + * This function allows to set in key attributes the owner identifier of a + * key. It is intended to be used for volatile keys. For persistent keys, + * it is recommended to use the PSA Cryptography API psa_set_key_id() to define + * the owner of a key. + * + * \param[out] attributes The attribute structure to write to. + * \param owner_id The key owner identifier. + */ +static void mbedtls_set_key_owner_id( psa_key_attributes_t *attributes, + mbedtls_key_owner_id_t owner_id ); +#endif /** Set the location of a persistent key. * @@ -192,7 +201,8 @@ static void psa_set_key_lifetime(psa_key_attributes_t *attributes, * This value is unspecified if the attribute structure declares * the key as volatile. */ -static psa_key_id_t psa_get_key_id(const psa_key_attributes_t *attributes); +static mbedtls_svc_key_id_t psa_get_key_id( + const psa_key_attributes_t *attributes); /** Retrieve the lifetime from key attributes. * @@ -347,7 +357,7 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); * Once you have called this function on an attribute structure, * you must call psa_reset_key_attributes() to free these resources. * - * \param[in] handle Handle to the key to query. + * \param[in] key Identifier of the key to query. * \param[in,out] attributes On success, the attributes of the key. * On failure, equivalent to a * freshly-initialized structure. @@ -363,7 +373,7 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_get_key_attributes(psa_key_handle_t handle, +psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, psa_key_attributes_t *attributes); /** Reset a key attribute structure to a freshly initialized state. @@ -386,93 +396,28 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes); * @{ */ -/** Open a handle to an existing persistent key. - * - * Open a handle to a persistent key. A key is persistent if it was created - * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key - * always has a nonzero key identifier, set with psa_set_key_id() when - * creating the key. Implementations may provide additional pre-provisioned - * keys that can be opened with psa_open_key(). Such keys have a key identifier - * in the vendor range, as documented in the description of #psa_key_id_t. - * - * The application must eventually close the handle with psa_close_key() or - * psa_destroy_key() to release associated resources. If the application dies - * without calling one of these functions, the implementation should perform - * the equivalent of a call to psa_close_key(). +/** Remove non-essential copies of key material from memory. * - * Some implementations permit an application to open the same key multiple - * times. If this is successful, each call to psa_open_key() will return a - * different key handle. + * If the key identifier designates a volatile key, this functions does not do + * anything and returns successfully. * - * \note Applications that rely on opening a key multiple times will not be - * portable to implementations that only permit a single key handle to be - * opened. See also :ref:\`key-handles\`. + * If the key identifier designates a persistent key, then this function will + * free all resources associated with the key in volatile memory. The key + * data in persistent storage is not affected and the key can still be used. * - * \param id The persistent identifier of the key. - * \param[out] handle On success, a handle to the key. + * \param key Identifier of the key to purge. * * \retval #PSA_SUCCESS - * Success. The application can now use the value of `*handle` - * to access the key. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * The implementation does not have sufficient resources to open the - * key. This can be due to reaching an implementation limit on the - * number of open keys, the number of open key handles, or available - * memory. - * \retval #PSA_ERROR_DOES_NOT_EXIST - * There is no persistent key with key identifier \p id. + * The key material will have been removed from memory if it is not + * currently required. * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p id is not a valid persistent key identifier. - * \retval #PSA_ERROR_NOT_PERMITTED - * The specified key exists, but the application does not have the - * permission to access it. Note that this specification does not - * define any way to create such a key, but it may be possible - * through implementation-specific means. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \p key is not a valid key identifier. * \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_open_key(psa_key_id_t id, - psa_key_handle_t *handle); - - -/** Close a key handle. - * - * If the handle designates a volatile key, this will destroy the key material - * and free all associated resources, just like psa_destroy_key(). - * - * If this is the last open handle to a persistent key, then closing the handle - * will free all resources associated with the key in volatile memory. The key - * data in persistent storage is not affected and can be opened again later - * with a call to psa_open_key(). - * - * Closing the key handle makes the handle invalid, and the key handle - * must not be used again by the application. - * - * \note If the key handle was used to set up an active - * :ref:\`multipart operation \`, then closing the - * key handle can cause the multipart operation to fail. Applications should - * maintain the key handle until after the multipart operation has finished. - * - * \param handle The key handle to close. - * If this is \c 0, do nothing and return \c PSA_SUCCESS. - * - * \retval #PSA_SUCCESS - * \p handle was a valid handle or \c 0. It is now closed. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p handle is not a valid handle nor \c 0. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_close_key(psa_key_handle_t handle); +psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); /** Make a copy of a key. * @@ -511,7 +456,10 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * The effect of this function on implementation-defined attributes is * implementation-defined. * - * \param source_handle The key to copy. It must be a valid key handle. + * \param source_key The key to copy. It must allow the usage + * #PSA_KEY_USAGE_COPY. If a private or secret key is + * being copied outside of a secure element it must + * also allow #PSA_KEY_USAGE_EXPORT. * \param[in] attributes The attributes for the new key. * They are used as follows: * - The key type and size may be 0. If either is @@ -525,12 +473,14 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * the source key and \p attributes so that * both sets of restrictions apply, as * described in the documentation of this function. - * \param[out] target_handle On success, a handle to the newly created key. + * \param[out] target_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 * \retval #PSA_ERROR_INVALID_HANDLE - * \p source_handle is invalid. + * \p source_key is invalid. * \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. @@ -558,9 +508,9 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_copy_key(psa_key_handle_t source_handle, +psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, const psa_key_attributes_t *attributes, - psa_key_handle_t *target_handle); + mbedtls_svc_key_id_t *target_key); /** @@ -571,28 +521,22 @@ psa_status_t psa_copy_key(psa_key_handle_t source_handle, * make a best effort to ensure that that the key material cannot be recovered. * * This function also erases any metadata such as policies and frees - * resources associated with the key. To free all resources associated with - * the key, all handles to the key must be closed or destroyed. - * - * Destroying the key makes the handle invalid, and the key handle - * must not be used again by the application. Using other open handles to the - * destroyed key in a cryptographic operation will result in an error. + * resources associated with the key. * * If a key is currently in use in a multipart operation, then destroying the * key will cause the multipart operation to fail. * - * \param handle Handle to the key to erase. - * If this is \c 0, do nothing and return \c PSA_SUCCESS. + * \param key Identifier of the key to erase. If this is \c 0, do nothing and + * return #PSA_SUCCESS. * * \retval #PSA_SUCCESS - * \p handle was a valid handle and the key material that it - * referred to has been erased. - * Alternatively, \p handle is \c 0. + * \p key was a valid identifier and the key material that it + * referred to has been erased. Alternatively, \p key is \c 0. * \retval #PSA_ERROR_NOT_PERMITTED * The key cannot be erased because it is * read-only, either due to a policy or due to physical restrictions. * \retval #PSA_ERROR_INVALID_HANDLE - * \p handle is not a valid handle nor \c 0. + * \p key is not a valid identifier nor \c 0. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * There was an failure in communication with the cryptoprocessor. * The key material may still be present in the cryptoprocessor. @@ -610,7 +554,7 @@ psa_status_t psa_copy_key(psa_key_handle_t source_handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_destroy_key(psa_key_handle_t handle); +psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); /**@}*/ @@ -645,7 +589,9 @@ psa_status_t psa_destroy_key(psa_key_handle_t handle); * \p data buffer. * If the key size in \p attributes is nonzero, * it must be equal to the size from \p data. - * \param[out] handle On success, a handle to the newly created key. + * \param[out] key On success, an identifier to the newly created key. + * For persistent keys, this is the key identifier + * defined in \p attributes. * \c 0 on failure. * \param[in] data Buffer containing the key data. The content of this * buffer is interpreted according to the type declared @@ -690,7 +636,7 @@ psa_status_t psa_destroy_key(psa_key_handle_t handle); psa_status_t psa_import_key(const psa_key_attributes_t *attributes, const uint8_t *data, size_t data_length, - psa_key_handle_t *handle); + mbedtls_svc_key_id_t *key); @@ -751,7 +697,9 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set. * - * \param handle Handle to the key to export. + * \param key Identifier of the key to export. It must allow the + * usage #PSA_KEY_USAGE_EXPORT, unless it is a public + * key. * \param[out] data Buffer where the key data is to be written. * \param data_size Size of the \p data buffer in bytes. * \param[out] data_length On success, the number of bytes @@ -778,7 +726,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_export_key(psa_key_handle_t handle, +psa_status_t psa_export_key(mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size, size_t *data_length); @@ -821,7 +769,7 @@ psa_status_t psa_export_key(psa_key_handle_t handle, * Exporting a public key object or the public part of a key pair is * always permitted, regardless of the key's usage flags. * - * \param handle Handle to the key to export. + * \param key Identifier of the key to export. * \param[out] data Buffer where the key data is to be written. * \param data_size Size of the \p data buffer in bytes. * \param[out] data_length On success, the number of bytes @@ -848,7 +796,7 @@ psa_status_t psa_export_key(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_export_public_key(psa_key_handle_t handle, +psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size, size_t *data_length); @@ -1225,7 +1173,8 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, * about the MAC value which could allow an attacker to guess * a valid MAC and thereby bypass security controls. * - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(\p alg) is true). * \param[in] input Buffer containing the input message. @@ -1240,7 +1189,7 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. * \retval #PSA_ERROR_BUFFER_TOO_SMALL @@ -1256,7 +1205,7 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_mac_compute(psa_key_handle_t handle, +psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -1266,7 +1215,8 @@ psa_status_t psa_mac_compute(psa_key_handle_t handle, /** Calculate the MAC of a message and compare it with a reference value. * - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(\p alg) is true). * \param[in] input Buffer containing the input message. @@ -1282,7 +1232,7 @@ psa_status_t psa_mac_compute(psa_key_handle_t handle, * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1296,7 +1246,7 @@ psa_status_t psa_mac_compute(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_mac_verify(psa_key_handle_t handle, +psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -1381,9 +1331,9 @@ static psa_mac_operation_t psa_mac_operation_init(void); * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_mac_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. - * It must remain valid until the operation - * terminates. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(\p alg) is true). * @@ -1392,7 +1342,7 @@ static psa_mac_operation_t psa_mac_operation_init(void); * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1409,7 +1359,7 @@ static psa_mac_operation_t psa_mac_operation_init(void); * results in this error code. */ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Set up a multipart MAC verification operation. @@ -1443,9 +1393,10 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_mac_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. - * It must remain valid until the operation - * terminates. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage + * PSA_KEY_USAGE_VERIFY_MESSAGE. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(\p alg) is true). * @@ -1471,7 +1422,7 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * results in this error code. */ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Add a message fragment to a multipart MAC operation. @@ -1638,9 +1589,8 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); * vector). Use the multipart operation interface with a * #psa_cipher_operation_t object to provide other forms of IV. * - * \param handle Handle to the key to use for the operation. - * It must remain valid until the operation - * terminates. + * \param key Identifier of the key to use for the operation. + * It must allow the usage #PSA_KEY_USAGE_ENCRYPT. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). @@ -1658,7 +1608,7 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. * \retval #PSA_ERROR_BUFFER_TOO_SMALL @@ -1672,7 +1622,7 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_cipher_encrypt(psa_key_handle_t handle, +psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -1684,9 +1634,10 @@ psa_status_t psa_cipher_encrypt(psa_key_handle_t handle, * * This function decrypts a message encrypted with a symmetric cipher. * - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. * It must remain valid until the operation - * terminates. + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). @@ -1704,7 +1655,7 @@ psa_status_t psa_cipher_encrypt(psa_key_handle_t handle, * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. * \retval #PSA_ERROR_BUFFER_TOO_SMALL @@ -1718,7 +1669,7 @@ psa_status_t psa_cipher_encrypt(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_cipher_decrypt(psa_key_handle_t handle, +psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -1804,9 +1755,10 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_cipher_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. * It must remain valid until the operation - * terminates. + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). @@ -1816,7 +1768,7 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1832,7 +1784,7 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * results in this error code. */ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Set the key for a multipart symmetric decryption operation. @@ -1867,9 +1819,10 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_cipher_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. * It must remain valid until the operation - * terminates. + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). @@ -1879,7 +1832,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1895,7 +1848,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * results in this error code. */ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Generate an IV for a symmetric encryption operation. @@ -2109,7 +2062,9 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); /** Process an authenticated encryption operation. * - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2140,7 +2095,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2155,7 +2110,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_aead_encrypt(psa_key_handle_t handle, +psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -2169,7 +2124,9 @@ psa_status_t psa_aead_encrypt(psa_key_handle_t handle, /** Process an authenticated decryption operation. * - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2200,7 +2157,7 @@ psa_status_t psa_aead_encrypt(psa_key_handle_t handle, * The ciphertext is not authentic. * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2215,7 +2172,7 @@ psa_status_t psa_aead_encrypt(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_aead_decrypt(psa_key_handle_t handle, +psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -2311,9 +2268,10 @@ static psa_aead_operation_t psa_aead_operation_init(void); * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_aead_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. * It must remain valid until the operation - * terminates. + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2322,10 +2280,10 @@ static psa_aead_operation_t psa_aead_operation_init(void); * Success. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2339,7 +2297,7 @@ static psa_aead_operation_t psa_aead_operation_init(void); * results in this error code. */ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Set the key for a multipart authenticated decryption operation. @@ -2377,9 +2335,10 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for * #psa_aead_operation_t and not yet in use. - * \param handle Handle to the key to use for the operation. + * \param key Identifier of the key to use for the operation. * It must remain valid until the operation - * terminates. + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2388,10 +2347,10 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * Success. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p handle is not compatible with \p alg. + * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2405,7 +2364,7 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * results in this error code. */ psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg); /** Generate a random nonce for an authenticated encryption operation. @@ -2431,7 +2390,7 @@ psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, * Success. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active aead encrypt - operation, with no nonce set). + * operation, with no nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p nonce buffer is too small. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2863,10 +2822,11 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * - * \param handle Handle to the key to use for the operation. - * It must be an asymmetric key pair. + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_HASH. * \param alg A signature algorithm that is compatible with - * the type of \p handle. + * the type of \p key. * \param[in] hash The hash or message to sign. * \param hash_length Size of the \p hash buffer in bytes. * \param[out] signature Buffer where the signature is to be written. @@ -2882,7 +2842,7 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p handle. + * respectively of \p key. * \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2896,7 +2856,7 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_sign_hash(psa_key_handle_t handle, +psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -2913,10 +2873,12 @@ psa_status_t psa_sign_hash(psa_key_handle_t handle, * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * - * \param handle Handle to the key to use for the operation. - * It must be a public key or an asymmetric key pair. + * \param key Identifier of the key to use for the operation. It + * must be a public key or an asymmetric key pair. The + * key must allow the usage + * #PSA_KEY_USAGE_VERIFY_HASH. * \param alg A signature algorithm that is compatible with - * the type of \p handle. + * the type of \p key. * \param[in] hash The hash or message whose signature is to be * verified. * \param hash_length Size of the \p hash buffer in bytes. @@ -2942,7 +2904,7 @@ psa_status_t psa_sign_hash(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_verify_hash(psa_key_handle_t handle, +psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -2952,11 +2914,12 @@ psa_status_t psa_verify_hash(psa_key_handle_t handle, /** * \brief Encrypt a short message with a public key. * - * \param handle Handle to the key to use for the operation. - * It must be a public key or an asymmetric - * key pair. + * \param key Identifer of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p handle. + * compatible with the type of \p key. * \param[in] input The message to encrypt. * \param input_length Size of the \p input buffer in bytes. * \param[in] salt A salt or label, if supported by the @@ -2985,7 +2948,7 @@ psa_status_t psa_verify_hash(psa_key_handle_t handle, * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p handle. + * respectively of \p key. * \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2999,7 +2962,7 @@ psa_status_t psa_verify_hash(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle, +psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3012,10 +2975,11 @@ psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle, /** * \brief Decrypt a short message with a private key. * - * \param handle Handle to the key to use for the operation. - * It must be an asymmetric key pair. + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. It must + * allow the usage #PSA_KEY_USAGE_DECRYPT. * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p handle. + * compatible with the type of \p key. * \param[in] input The message to decrypt. * \param input_length Size of the \p input buffer in bytes. * \param[in] salt A salt or label, if supported by the @@ -3044,7 +3008,7 @@ psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle, * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p handle. + * respectively of \p key. * \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -3059,7 +3023,7 @@ psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle, +psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3317,9 +3281,9 @@ psa_status_t psa_key_derivation_input_bytes( * psa_key_derivation_setup() and must not * have produced any output yet. * \param step Which step the input data is for. - * \param handle Handle to the key. It must have an - * appropriate type for \p step and must - * allow the usage #PSA_KEY_USAGE_DERIVE. + * \param key Identifier of the key. It must have an + * appropriate type for step and must allow the + * usage #PSA_KEY_USAGE_DERIVE. * * \retval #PSA_SUCCESS * Success. @@ -3345,7 +3309,7 @@ psa_status_t psa_key_derivation_input_bytes( psa_status_t psa_key_derivation_input_key( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, - psa_key_handle_t handle); + mbedtls_svc_key_id_t key); /** Perform a key agreement and use the shared secret as input to a key * derivation. @@ -3370,7 +3334,8 @@ psa_status_t psa_key_derivation_input_key( * The operation must be ready for an * input of the type given by \p step. * \param step Which step the input data is for. - * \param private_key Handle to the private key to use. + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. * \param[in] peer_key Public key of the peer. The peer key must be in the * same format that psa_import_key() accepts for the * public key type corresponding to the type of @@ -3414,7 +3379,7 @@ psa_status_t psa_key_derivation_input_key( psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, - psa_key_handle_t private_key, + mbedtls_svc_key_id_t private_key, const uint8_t *peer_key, size_t peer_key_length); @@ -3558,7 +3523,9 @@ psa_status_t psa_key_derivation_output_bytes( * * \param[in] attributes The attributes for the new key. * \param[in,out] operation The key derivation operation object to read from. - * \param[out] handle On success, a handle to the newly created key. + * \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 @@ -3598,7 +3565,7 @@ psa_status_t psa_key_derivation_output_bytes( psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, - psa_key_handle_t *handle); + mbedtls_svc_key_id_t *key); /** Abort a key derivation operation. * @@ -3639,7 +3606,8 @@ psa_status_t psa_key_derivation_abort( * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg) * is true). - * \param private_key Handle to the private key to use. + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. * \param[in] peer_key Public key of the peer. It must be * in the same format that psa_import_key() * accepts. The standard formats for public @@ -3677,7 +3645,7 @@ psa_status_t psa_key_derivation_abort( * results in this error code. */ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, - psa_key_handle_t private_key, + mbedtls_svc_key_id_t private_key, const uint8_t *peer_key, size_t peer_key_length, uint8_t *output, @@ -3733,7 +3701,9 @@ psa_status_t psa_generate_random(uint8_t *output, * attributes. * * \param[in] attributes The attributes for the new key. - * \param[out] handle On success, a handle to the newly created key. + * \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 @@ -3758,7 +3728,7 @@ psa_status_t psa_generate_random(uint8_t *output, * results in this error code. */ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, - psa_key_handle_t *handle); + mbedtls_svc_key_id_t *key); /**@}*/ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_accel_driver.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_accel_driver.h index 1a193c5b9e3..4488ea8ad8f 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_accel_driver.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_accel_driver.h @@ -75,7 +75,7 @@ typedef struct psa_drv_hash_context_s psa_drv_hash_context_t; * \param[in,out] p_context A structure that will contain the * hardware-specific hash context * - * \retval PSA_SUCCESS Success. + * \retval #PSA_SUCCESS Success. */ typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context); @@ -120,7 +120,7 @@ typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context, * \param[out] p_output_length The number of bytes placed in `p_output` after * success * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context, @@ -188,7 +188,7 @@ typedef struct psa_drv_accel_mac_context_s psa_drv_accel_mac_context_t; * to be used in the operation * \param[in] key_length The size in bytes of the key material * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_accel_mac_setup_t)(psa_drv_accel_mac_context_t *p_context, @@ -235,7 +235,7 @@ typedef psa_status_t (*psa_drv_accel_mac_update_t)(psa_drv_accel_mac_context_t * * \param[in] mac_length The size in bytes of the buffer that has been * allocated for the `p_mac` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_accel_mac_finish_t)(psa_drv_accel_mac_context_t *p_context, @@ -261,7 +261,7 @@ typedef psa_status_t (*psa_drv_accel_mac_finish_t)(psa_drv_accel_mac_context_t * * \param[in] mac_length The size in bytes of the data in the `p_mac` * buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The operation completed successfully and the comparison matched */ typedef psa_status_t (*psa_drv_accel_mac_finish_verify_t)(psa_drv_accel_mac_context_t *p_context, @@ -335,7 +335,7 @@ typedef psa_status_t (*psa_drv_accel_mac_t)(const uint8_t *p_input, * \param[in] p_mac The MAC data to be compared * \param[in] mac_length The length in bytes of the `p_mac` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The operation completed successfully and the comparison matched */ typedef psa_status_t (*psa_drv_accel_mac_verify_t)(const uint8_t *p_input, @@ -396,7 +396,7 @@ typedef struct psa_drv_accel_cipher_context_s psa_drv_accel_cipher_context_t; * to be used in the operation * \param[in] key_data_size The size in bytes of the key material * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_cipher_setup_t)(psa_drv_accel_cipher_context_t *p_context, psa_encrypt_or_decrypt_t direction, @@ -419,7 +419,7 @@ typedef psa_status_t (*psa_drv_accel_cipher_setup_t)(psa_drv_accel_cipher_contex * \param[in] p_iv A buffer containing the initialization vecotr * \param[in] iv_length The size in bytes of the contents of `p_iv` * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_cipher_set_iv_t)(psa_drv_accel_cipher_context_t *p_context, const uint8_t *p_iv, @@ -448,7 +448,7 @@ typedef psa_status_t (*psa_drv_accel_cipher_set_iv_t)(psa_drv_accel_cipher_conte * \param[out] p_output_length After completion, will contain the number * of bytes placed in the `p_output` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_cipher_update_t)(psa_drv_accel_cipher_context_t *p_context, const uint8_t *p_input, @@ -477,7 +477,7 @@ typedef psa_status_t (*psa_drv_accel_cipher_update_t)(psa_drv_accel_cipher_conte * \param[out] p_output_length After completion, will contain the number of * bytes placed in the `p_output` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_cipher_finish_t)(psa_drv_accel_cipher_context_t *p_context, uint8_t *p_output, @@ -499,7 +499,7 @@ typedef psa_status_t (*psa_drv_accel_cipher_finish_t)(psa_drv_accel_cipher_conte * \param[in,out] p_context A hardware-specific structure for the * previously started cipher operation * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_cipher_abort_t)(psa_drv_accel_cipher_context_t *p_context); @@ -659,7 +659,7 @@ typedef psa_status_t (*psa_drv_accel_aead_decrypt_t)(const uint8_t *p_key, * \param[out] p_signature_length On success, the number of bytes * that make up the returned signature value * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_asymmetric_sign_t)(const uint8_t *p_key, size_t key_size, @@ -697,7 +697,7 @@ typedef psa_status_t (*psa_drv_accel_asymmetric_sign_t)(const uint8_t *p_key, * \param[in] p_signature Buffer containing the signature to verify * \param[in] signature_length Size of the `p_signature` buffer in bytes * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The signature is valid. */ typedef psa_status_t (*psa_drv_accel_asymmetric_verify_t)(const uint8_t *p_key, @@ -748,7 +748,7 @@ typedef psa_status_t (*psa_drv_accel_asymmetric_verify_t)(const uint8_t *p_key, * \param[out] p_output_length On success, the number of bytes * that make up the returned output * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_asymmetric_encrypt_t)(const uint8_t *p_key, size_t key_size, @@ -800,7 +800,7 @@ typedef psa_status_t (*psa_drv_accel_asymmetric_encrypt_t)(const uint8_t *p_key, * \param[out] p_output_length On success, the number of bytes * that make up the returned output * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_accel_asymmetric_decrypt_t)(const uint8_t *p_key, size_t key_size, diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_compat.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_compat.h index 4b607b6ff65..5bb56693866 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_compat.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_compat.h @@ -34,6 +34,27 @@ extern "C" { #endif +/* + * To support both openless APIs and psa_open_key() temporarily, define + * psa_key_handle_t to be equal to mbedtls_svc_key_id_t. Do not mark the + * type and its utility macros and functions deprecated yet. This will be done + * in a subsequent phase. + */ +typedef mbedtls_svc_key_id_t psa_key_handle_t; + +#define PSA_KEY_HANDLE_INIT MBEDTLS_SVC_KEY_ID_INIT + +/** Check wether an handle is null. + * + * \param handle Handle + * + * \return Non-zero if the handle is null, zero otherwise. + */ +static inline int psa_key_handle_is_null( psa_key_handle_t handle ) +{ + return( mbedtls_svc_key_id_is_null( handle ) ); +} + #if !defined(MBEDTLS_DEPRECATED_REMOVED) /* @@ -52,6 +73,7 @@ typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t mbedtls_deprecated_psa_ecc_famil typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t mbedtls_deprecated_psa_dh_family_t; typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t psa_ecc_curve_t; typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t psa_dh_group_t; +typedef MBEDTLS_PSA_DEPRECATED psa_algorithm_t mbedtls_deprecated_psa_algorithm_t; #define PSA_KEY_TYPE_GET_CURVE PSA_KEY_TYPE_ECC_GET_FAMILY #define PSA_KEY_TYPE_GET_GROUP PSA_KEY_TYPE_DH_GET_FAMILY @@ -113,10 +135,6 @@ MBEDTLS_PSA_DEPRECATED static inline psa_status_t psa_asymmetric_verify( psa_key return psa_verify_hash( key, alg, hash, hash_length, signature, signature_length ); } - - -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - /* * Size-specific elliptic curve families. */ @@ -223,6 +241,117 @@ MBEDTLS_PSA_DEPRECATED static inline psa_status_t psa_asymmetric_verify( psa_key #define PSA_DH_GROUP_CUSTOM \ MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_CUSTOM ) +/* + * Deprecated PSA Crypto stream cipher algorithms (PSA Crypto API <= 1.0 beta3) + */ +#define PSA_ALG_ARC4 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_STREAM_CIPHER ) +#define PSA_ALG_CHACHA20 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_STREAM_CIPHER ) + +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** Open a handle to an existing persistent key. + * + * Open a handle to a persistent key. A key is persistent if it was created + * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key + * always has a nonzero key identifier, set with psa_set_key_id() when + * creating the key. Implementations may provide additional pre-provisioned + * keys that can be opened with psa_open_key(). Such keys have an application + * key identifier in the vendor range, as documented in the description of + * #psa_key_id_t. + * + * The application must eventually close the handle with psa_close_key() or + * psa_destroy_key() to release associated resources. If the application dies + * without calling one of these functions, the implementation should perform + * the equivalent of a call to psa_close_key(). + * + * Some implementations permit an application to open the same key multiple + * times. If this is successful, each call to psa_open_key() will return a + * different key handle. + * + * \note This API is not part of the PSA Cryptography API Release 1.0.0 + * specification. It was defined in the 1.0 Beta 3 version of the + * specification but was removed in the 1.0.0 released version. This API is + * kept for the time being to not break applications relying on it. It is not + * deprecated yet but will be in the near future. + * + * \note Applications that rely on opening a key multiple times will not be + * portable to implementations that only permit a single key handle to be + * opened. See also :ref:\`key-handles\`. + * + * + * \param key The persistent identifier of the key. + * \param[out] handle On success, a handle to the key. + * + * \retval #PSA_SUCCESS + * Success. The application can now use the value of `*handle` + * to access the key. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * The implementation does not have sufficient resources to open the + * key. This can be due to reaching an implementation limit on the + * number of open keys, the number of open key handles, or available + * memory. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * There is no persistent key with key identifier \p id. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p id is not a valid persistent key identifier. + * \retval #PSA_ERROR_NOT_PERMITTED + * The specified key exists, but the application does not have the + * permission to access it. Note that this specification does not + * define any way to create such a key, but it may be possible + * through implementation-specific means. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \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_open_key( mbedtls_svc_key_id_t key, + psa_key_handle_t *handle ); + +/** Close a key handle. + * + * If the handle designates a volatile key, this will destroy the key material + * and free all associated resources, just like psa_destroy_key(). + * + * If this is the last open handle to a persistent key, then closing the handle + * will free all resources associated with the key in volatile memory. The key + * data in persistent storage is not affected and can be opened again later + * with a call to psa_open_key(). + * + * Closing the key handle makes the handle invalid, and the key handle + * must not be used again by the application. + * + * \note This API is not part of the PSA Cryptography API Release 1.0.0 + * specification. It was defined in the 1.0 Beta 3 version of the + * specification but was removed in the 1.0.0 released version. This API is + * kept for the time being to not break applications relying on it. It is not + * deprecated yet but will be in the near future. + * + * \note If the key handle was used to set up an active + * :ref:\`multipart operation \`, then closing the + * key handle can cause the multipart operation to fail. Applications should + * maintain the key handle until after the multipart operation has finished. + * + * \param handle The key handle to close. + * If this is \c 0, do nothing and return \c PSA_SUCCESS. + * + * \retval #PSA_SUCCESS + * \p handle was a valid handle or \c 0. It is now closed. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p handle is not a valid handle nor \c 0. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_close_key(psa_key_handle_t handle); + #ifdef __cplusplus } #endif diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_config.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_config.h new file mode 100644 index 00000000000..cf7f63a05da --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_config.h @@ -0,0 +1,78 @@ +/** + * \file psa/crypto_config.h + * \brief PSA crypto configuration options (set of defines) + * + */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +/** + * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in config.h, + * this file determines which cryptographic mechanisms are enabled + * through the PSA Cryptography API (\c psa_xxx() functions). + * + * To enable a cryptographic mechanism, uncomment the definition of + * the corresponding \c PSA_WANT_xxx preprocessor symbol. + * To disable a cryptographic mechanism, comment out the definition of + * the corresponding \c PSA_WANT_xxx preprocessor symbol. + * The names of cryptographic mechanisms correspond to values + * defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead + * of \c PSA_. + * + * Note that many cryptographic mechanisms involve two symbols: one for + * the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm + * (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve + * additional symbols. + */ +#else +/** + * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in config.h, + * this file is not used, and cryptographic mechanisms are supported + * through the PSA API if and only if they are supported through the + * mbedtls_xxx API. + */ +#endif +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_CONFIG_H +#define PSA_CRYPTO_CONFIG_H + +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 +#define PSA_WANT_ALG_ECDH 1 +#define PSA_WANT_ALG_ECDSA 1 +#define PSA_WANT_ALG_HKDF 1 +#define PSA_WANT_ALG_HMAC 1 +#define PSA_WANT_ALG_MD2 1 +#define PSA_WANT_ALG_MD4 1 +#define PSA_WANT_ALG_MD5 1 +#define PSA_WANT_ALG_RIPEMD160 1 +#define PSA_WANT_ALG_RSA_OAEP 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 +#define PSA_WANT_ALG_RSA_PSS 1 +#define PSA_WANT_ALG_SHA_1 1 +#define PSA_WANT_ALG_SHA_224 1 +#define PSA_WANT_ALG_SHA_256 1 +#define PSA_WANT_ALG_SHA_384 1 +#define PSA_WANT_ALG_SHA_512 1 +#define PSA_WANT_ALG_TLS12_PRF 1 +#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 + +#endif /* PSA_CRYPTO_CONFIG_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_entropy_driver.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_entropy_driver.h index 61750448bb3..9b6546ee947 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_entropy_driver.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_entropy_driver.h @@ -47,7 +47,7 @@ extern "C" { * containing any context information for * the implementation * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_entropy_init_t)(void *p_context); @@ -75,7 +75,7 @@ typedef psa_status_t (*psa_drv_entropy_init_t)(void *p_context); * \param[out] p_received_entropy_bits The amount of entropy (in bits) * actually provided in `p_buffer` * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_entropy_get_bits_t)(void *p_context, uint8_t *p_buffer, diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_extra.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_extra.h index 1e6a4bba267..f793a6cacb6 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_extra.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_extra.h @@ -32,8 +32,6 @@ #include "crypto_compat.h" -#include "platform/mbed_toolchain.h" - #ifdef __cplusplus extern "C" { #endif @@ -56,17 +54,15 @@ extern "C" { * for, in addition to the algorithm set with * psa_set_key_algorithm(). * - * \deprecated This is for backward compatibility only. - * Setting an enrollment algorithm is not recommended, because - * using the same key with different algorithms can allow some - * attacks based on arithmetic relations between different - * computations made with the same key, or can escalate harmless - * side channels into exploitable ones. Use this function only - * if it is necessary to support a protocol for which it has been - * verified that the usage of the key with multiple algorithms - * is safe. + * \warning Setting an enrollment algorithm is not recommended, because + * using the same key with different algorithms can allow some + * attacks based on arithmetic relations between different + * computations made with the same key, or can escalate harmless + * side channels into exploitable ones. Use this function only + * if it is necessary to support a protocol for which it has been + * verified that the usage of the key with multiple algorithms + * is safe. */ -MBED_DEPRECATED("Setting enrollment algorithm is for backward compatibility and not recommended.") static inline void psa_set_key_enrollment_algorithm( psa_key_attributes_t *attributes, psa_algorithm_t alg2) @@ -79,10 +75,7 @@ static inline void psa_set_key_enrollment_algorithm( * \param[in] attributes The key attribute structure to query. * * \return The enrollment algorithm stored in the attribute structure. - * \deprecated This is for backward compatibility only. - * Deprecated along with psa_set_key_enrollment_algorithm(). */ -MBED_DEPRECATED("Getting enrollment algorithm is for backward compatibility and not recommended.") static inline psa_algorithm_t psa_get_key_enrollment_algorithm( const psa_key_attributes_t *attributes) { @@ -238,10 +231,12 @@ typedef struct mbedtls_psa_stats_s size_t cache_slots; /** Number of slots that are not used for anything. */ size_t empty_slots; + /** Number of slots that are locked. */ + size_t locked_slots; /** Largest key id value among open keys in internal persistent storage. */ - psa_app_key_id_t max_open_internal_key_id; + psa_key_id_t max_open_internal_key_id; /** Largest key id value among open keys in secure elements. */ - psa_app_key_id_t max_open_external_key_id; + psa_key_id_t max_open_external_key_id; } mbedtls_psa_stats_t; /** \brief Get statistics about @@ -358,7 +353,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, #define PSA_KEY_TYPE_IS_DSA(type) \ (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY) -#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000) +#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x06000400) /** DSA signature with hashing. * * This is the signature scheme defined by FIPS 186-4, @@ -375,7 +370,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, */ #define PSA_ALG_DSA(hash_alg) \ (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000) +#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x06000500) #define PSA_ALG_DSA_DETERMINISTIC_FLAG PSA_ALG_ECDSA_DETERMINISTIC_FLAG /** Deterministic DSA signature with hashing. * diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_platform.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_platform.h index 77c0e5b2f0a..567398dbfdc 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_platform.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_platform.h @@ -41,60 +41,44 @@ #include MBEDTLS_CONFIG_FILE #endif +/* Translate between classic MBEDTLS_xxx feature symbols and PSA_xxx + * feature symbols. */ +#include "mbedtls/config_psa.h" + /* PSA requires several types which C99 provides in stdint.h. */ #include -/* Integral type representing a key handle. */ -typedef uint16_t psa_key_handle_t; +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) -/* This implementation distinguishes *application key identifiers*, which - * are the key identifiers specified by the application, from - * *key file identifiers*, which are the key identifiers that the library - * sees internally. The two types can be different if there is a remote - * call layer between the application and the library which supports - * multiple client applications that do not have access to each others' - * keys. The point of having different types is that the key file - * identifier may encode not only the key identifier specified by the - * application, but also the the identity of the application. +/* Building for the PSA Crypto service on a PSA platform, a key owner is a PSA + * partition identifier. * - * Note that this is an internal concept of the library and the remote - * call layer. The application itself never sees anything other than - * #psa_app_key_id_t with its standard definition. + * The function psa_its_identifier_of_slot() in psa_crypto_storage.c that + * translates a key identifier to a key storage file name assumes that + * mbedtls_key_owner_id_t is an 32 bits integer. This function thus needs + * reworking if mbedtls_key_owner_id_t is not defined as a 32 bits integer + * here anymore. */ +typedef int32_t mbedtls_key_owner_id_t; -/* The application key identifier is always what the application sees as - * #psa_key_id_t. */ -typedef uint32_t psa_app_key_id_t; - -#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) - -#if defined(PSA_CRYPTO_SECURE) -/* Building for the PSA Crypto service on a PSA platform. */ -/* A key owner is a PSA partition identifier. */ -typedef int32_t psa_key_owner_id_t; -#endif - -typedef struct +/** Compare two key owner identifiers. + * + * \param id1 First key owner identifier. + * \param id2 Second key owner identifier. + * + * \return Non-zero if the two key owner identifiers are equal, zero otherwise. + */ +static inline int mbedtls_key_owner_id_equal( mbedtls_key_owner_id_t id1, + mbedtls_key_owner_id_t id2 ) { - uint32_t key_id; - psa_key_owner_id_t owner; -} psa_key_file_id_t; -#define PSA_KEY_FILE_GET_KEY_ID( file_id ) ( ( file_id ).key_id ) - -/* Since crypto.h is used as part of the PSA Cryptography API specification, - * it must use standard types for things like the argument of psa_open_key(). - * If it wasn't for that constraint, psa_open_key() would take a - * `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an - * alias for `psa_key_file_id_t` when building for a multi-client service. */ -typedef psa_key_file_id_t psa_key_id_t; -#define PSA_KEY_ID_INIT {0, 0} - -#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */ - -/* By default, a key file identifier is just the application key identifier. */ -typedef psa_app_key_id_t psa_key_file_id_t; -#define PSA_KEY_FILE_GET_KEY_ID( id ) ( id ) + return( id1 == id2 ); +} -#endif /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */ +#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ #endif /* PSA_CRYPTO_PLATFORM_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_se_driver.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_se_driver.h index 46b2d645cbe..1fae575161b 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_se_driver.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_se_driver.h @@ -178,7 +178,7 @@ typedef uint64_t psa_key_slot_number_t; * \param[in] algorithm The algorithm to be used to underly the MAC * operation * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context, @@ -213,7 +213,7 @@ typedef psa_status_t (*psa_drv_se_mac_update_t)(void *op_context, * \param[out] p_mac_length After completion, will contain the number of * bytes placed in the `p_mac` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context, @@ -230,10 +230,10 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context, * will be compared against * \param[in] mac_length The size in bytes of the value stored in `p_mac` * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The operation completed successfully and the MACs matched each * other - * \retval PSA_ERROR_INVALID_SIGNATURE + * \retval #PSA_ERROR_INVALID_SIGNATURE * The operation completed successfully, but the calculated MAC did * not match the provided MAC */ @@ -264,7 +264,7 @@ typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context); * \param[out] p_mac_length After completion, will contain the number of * bytes placed in the `output` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. */ typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context, @@ -289,10 +289,10 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_cont * be compared against * \param[in] mac_length The size in bytes of `mac` * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The operation completed successfully and the MACs matched each * other - * \retval PSA_ERROR_INVALID_SIGNATURE + * \retval #PSA_ERROR_INVALID_SIGNATURE * The operation completed successfully, but the calculated MAC did * not match the provided MAC */ @@ -384,8 +384,8 @@ typedef struct { * \param[in] direction Indicates whether the operation is an encrypt * or decrypt * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED */ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context, void *op_context, @@ -406,7 +406,7 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_cont * \param[in] p_iv A buffer containing the initialization vector * \param[in] iv_length The size (in bytes) of the `p_iv` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, const uint8_t *p_iv, @@ -428,7 +428,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, * \param[out] p_output_length After completion, will contain the number * of bytes placed in the `p_output` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, const uint8_t *p_input, @@ -449,7 +449,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, * \param[out] p_output_length After completion, will contain the number of * bytes placed in the `p_output` buffer * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context, uint8_t *p_output, @@ -484,8 +484,8 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context); * \param[in] output_size The allocated size in bytes of the `p_output` * buffer * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED */ typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -553,7 +553,7 @@ typedef struct { * \param[out] p_signature_length On success, the number of bytes * that make up the returned signature value * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -578,7 +578,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_c * \param[in] p_signature Buffer containing the signature to verify * \param[in] signature_length Size of the `p_signature` buffer in bytes * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The signature is valid. */ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context, @@ -617,7 +617,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv * \param[out] p_output_length On success, the number of bytes that make up * the returned output * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -657,7 +657,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *dr * \param[out] p_output_length On success, the number of bytes * that make up the returned output * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -1195,7 +1195,7 @@ typedef struct { * \param[in] source_key The key to be used as the source material for * the key derivation * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context, void *op_context, @@ -1215,7 +1215,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t * * \param[in] p_collateral A buffer containing the collateral data * \param[in] collateral_size The size in bytes of the collateral * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, uint32_t collateral_id, @@ -1230,7 +1230,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, * \param[in] dest_key The slot where the generated key material * should be placed * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, psa_key_slot_number_t dest_key); @@ -1244,7 +1244,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, * \param[out] p_output_length Upon success, contains the number of bytes of * key material placed in `p_output` * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS */ typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context, uint8_t *p_output, @@ -1353,7 +1353,7 @@ typedef struct { * \param location The location value through which this driver will * be exposed to applications. * This driver will be used for all keys such that - * `location == PSA_KEY_LIFETIME_LOCATION( lifetime )`. + * `location == #PSA_KEY_LIFETIME_GET_LOCATION( lifetime )`. * The value #PSA_KEY_LOCATION_LOCAL_STORAGE is reserved * and may not be used for drivers. Implementations * may reserve other values. @@ -1362,22 +1362,22 @@ typedef struct { * module keeps running. It is typically a global * constant. * - * \return PSA_SUCCESS + * \return #PSA_SUCCESS * The driver was successfully registered. Applications can now * use \p lifetime to access keys through the methods passed to * this function. - * \return PSA_ERROR_BAD_STATE + * \return #PSA_ERROR_BAD_STATE * This function was called after the initialization of the * cryptography module, and this implementation does not support * driver registration at this stage. - * \return PSA_ERROR_ALREADY_EXISTS + * \return #PSA_ERROR_ALREADY_EXISTS * There is already a registered driver for this value of \p lifetime. - * \return PSA_ERROR_INVALID_ARGUMENT + * \return #PSA_ERROR_INVALID_ARGUMENT * \p lifetime is a reserved value. - * \return PSA_ERROR_NOT_SUPPORTED + * \return #PSA_ERROR_NOT_SUPPORTED * `methods->hal_version` is not supported by this implementation. - * \return PSA_ERROR_INSUFFICIENT_MEMORY - * \return PSA_ERROR_NOT_PERMITTED + * \return #PSA_ERROR_INSUFFICIENT_MEMORY + * \return #PSA_ERROR_NOT_PERMITTED */ psa_status_t psa_register_se_driver( psa_key_location_t location, diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_sizes.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_sizes.h index f6373b8c21e..3df01b2ce82 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_sizes.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_sizes.h @@ -657,4 +657,91 @@ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ 0) +/** The default nonce size for an AEAD algorithm, in bytes. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the nonce output from #psa_aead_generate_nonce(). + * + * See also #PSA_AEAD_NONCE_MAX_SIZE. + * + * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(), + * #psa_aead_encrypt() or #psa_aead_decrypt(), just the default size that is generated by + * #psa_aead_generate_nonce(). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with algorithm \p alg. + * + * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The default nonce size for the specified key type and algorithm. + * If the key type or AEAD algorithm is not recognized, + * or the parameters are incompatible, return 0. + * An implementation can return either 0 or a correct size for a key type + * and AEAD algorithm that it recognizes, but does not support. + */ +#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \ + (PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \ + PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \ + (key_type) == PSA_KEY_TYPE_CHACHA20 && \ + PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \ + 0) + +/** The maximum default nonce size among all supported pairs of key types and AEAD algorithms, in bytes. + * + * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() may return. + * + * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(), + * #psa_aead_encrypt() or #psa_aead_decrypt(), just the largest size that may be generated by + * #psa_aead_generate_nonce(). + */ +#define PSA_AEAD_NONCE_MAX_SIZE 12 + +/** The default IV size for a cipher algorithm, in bytes. + * + * The IV that is generated as part of a call to #psa_cipher_encrypt() is always + * the default IV length for the algorithm. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the IV output from #psa_cipher_generate_iv() when using + * a multi-part cipher operation. + * + * See also #PSA_CIPHER_IV_MAX_SIZE. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with algorithm \p alg. + * + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \return The default IV size for the specified key type and algorithm. + * If the algorithm does not use an IV, return 0. + * If the key type or cipher algorithm is not recognized, + * or the parameters are incompatible, return 0. + * An implementation can return either 0 or a correct size for a key type + * and cipher algorithm that it recognizes, but does not support. + */ +#define PSA_CIPHER_IV_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \ + ((alg) == PSA_ALG_CTR || \ + (alg) == PSA_ALG_CFB || \ + (alg) == PSA_ALG_OFB || \ + (alg) == PSA_ALG_XTS || \ + (alg) == PSA_ALG_CBC_NO_PADDING || \ + (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \ + (key_type) == PSA_KEY_TYPE_CHACHA20 && \ + (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \ + 0) + +/** The maximum IV size for all supported cipher algorithms, in bytes. + * + * See also #PSA_CIPHER_IV_LENGTH(). + */ +#define PSA_CIPHER_IV_MAX_SIZE 16 + #endif /* PSA_CRYPTO_SIZES_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_types.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_types.h index 17718eb6dce..0a2ae54285f 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_types.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_types.h @@ -33,6 +33,8 @@ #ifndef PSA_CRYPTO_TYPES_H #define PSA_CRYPTO_TYPES_H +#include "crypto_platform.h" + #include /** \defgroup error Error codes @@ -123,7 +125,7 @@ typedef uint32_t psa_algorithm_t; * implementation-specific device management event occurs (for example, * a factory reset). * - * Persistent keys have a key identifier of type #psa_key_id_t. + * Persistent keys have a key identifier of type #mbedtls_svc_key_id_t. * This identifier remains valid throughout the lifetime of the key, * even if the application instance that created the key terminates. * The application can call psa_open_key() to open a persistent key that @@ -226,15 +228,24 @@ typedef uint32_t psa_key_location_t; * - 0 is reserved as an invalid key identifier. * - Key identifiers outside these ranges are reserved for future use. */ -/* Implementation-specific quirk: The Mbed Crypto library can be built as - * part of a multi-client service that exposes the PSA Crypto API in each - * client and encodes the client identity in the key id argument of functions - * such as psa_open_key(). In this build configuration, we define - * psa_key_id_t in crypto_platform.h instead of here. */ -#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER) typedef uint32_t psa_key_id_t; -#define PSA_KEY_ID_INIT 0 -#endif + +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +typedef psa_key_id_t mbedtls_svc_key_id_t; + +#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ +/* Implementation-specific: The Mbed Cryptography library can be built as + * part of a multi-client service that exposes the PSA Cryptograpy API in each + * client and encodes the client identity in the key identifier argument of + * functions such as psa_open_key(). + */ +typedef struct +{ + psa_key_id_t key_id; + mbedtls_key_owner_id_t owner; +} mbedtls_svc_key_id_t; + +#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ /**@}*/ @@ -341,7 +352,7 @@ typedef uint32_t psa_key_usage_t; * -# Call a key creation function: psa_import_key(), psa_generate_key(), * psa_key_derivation_output_key() or psa_copy_key(). This function reads * the attribute structure, creates a key with these attributes, and - * outputs a handle to the newly created key. + * outputs a key identifier to the newly created key. * -# The attribute structure is now no longer necessary. * You may call psa_reset_key_attributes(), although this is optional * with the workflow presented here because the attributes currently diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_values.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_values.h index a9407118034..f1b5c53ab2c 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_values.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/inc/psa/crypto_values.h @@ -108,7 +108,7 @@ * as applicable. * * Implementations shall not return this error code to indicate that a - * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE * instead. */ #define PSA_ERROR_BAD_STATE ((psa_status_t)-137) @@ -118,7 +118,7 @@ * combination of parameters are recognized as invalid. * * Implementations shall not return this error code to indicate that a - * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE * instead. */ #define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) @@ -266,7 +266,7 @@ * to read from a resource. */ #define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) -/** The key handle is not valid. See also :ref:\`key-handles\`. +/** The key identifier is not valid. See also :ref:\`key-handles\`. */ #define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) @@ -609,14 +609,14 @@ #define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000) #define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000) -#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000) -#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000) +#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x02000000) +#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x03000000) #define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000) -#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000) -#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000) -#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000) -#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000) -#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x30000000) +#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x05000000) +#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x06000000) +#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x07000000) +#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x08000000) +#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x09000000) /** Whether an algorithm is vendor-defined. * @@ -718,35 +718,35 @@ #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) /** MD2 */ -#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) +#define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) /** MD4 */ -#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) +#define PSA_ALG_MD4 ((psa_algorithm_t)0x02000002) /** MD5 */ -#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003) +#define PSA_ALG_MD5 ((psa_algorithm_t)0x02000003) /** PSA_ALG_RIPEMD160 */ -#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004) +#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x02000004) /** SHA1 */ -#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005) +#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x02000005) /** SHA2-224 */ -#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008) +#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x02000008) /** SHA2-256 */ -#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x01000009) +#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x02000009) /** SHA2-384 */ -#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0100000a) +#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0200000a) /** SHA2-512 */ -#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0100000b) +#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0200000b) /** SHA2-512/224 */ -#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0100000c) +#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0200000c) /** SHA2-512/256 */ -#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0100000d) +#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0200000d) /** SHA3-224 */ -#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x01000010) +#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x02000010) /** SHA3-256 */ -#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x01000011) +#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x02000011) /** SHA3-384 */ -#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x01000012) +#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x02000012) /** SHA3-512 */ -#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x01000013) +#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x02000013) /** In a hash-and-sign algorithm policy, allow any hash algorithm. * @@ -769,9 +769,9 @@ * an algorithm built from `PSA_xxx_SIGNATURE` and a specific hash. Each * call to sign or verify a message may use a different hash. * ``` - * psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...); - * psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...); - * psa_sign_hash(handle, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...); + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...); + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...); + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...); * ``` * * This value may not be used to build other algorithms that are @@ -781,10 +781,10 @@ * This value may not be used to build an algorithm specification to * perform an operation. It is only valid to build policies. */ -#define PSA_ALG_ANY_HASH ((psa_algorithm_t)0x010000ff) +#define PSA_ALG_ANY_HASH ((psa_algorithm_t)0x020000ff) #define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000) -#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x02800000) +#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x03800000) /** Macro to build an HMAC algorithm. * * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256. @@ -823,8 +823,8 @@ * reach up to 63; the largest MAC is 64 bytes so its trivial truncation * to full length is correctly encoded as 0 and any non-trivial truncation * is correctly encoded as a value between 1 and 63. */ -#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x00003f00) -#define PSA_MAC_TRUNCATION_OFFSET 8 +#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x003f0000) +#define PSA_MAC_TRUNCATION_OFFSET 16 /** Macro to build a truncated MAC algorithm. * @@ -892,15 +892,15 @@ #define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \ (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) -#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000) +#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x03c00000) /** The CBC-MAC construction over a block cipher * * \warning CBC-MAC is insecure in many cases. * A more secure mode, such as #PSA_ALG_CMAC, is recommended. */ -#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001) +#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x03c00100) /** The CMAC construction over a block cipher */ -#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002) +#define PSA_ALG_CMAC ((psa_algorithm_t)0x03c00200) /** Whether the specified algorithm is a MAC algorithm based on a block cipher. * @@ -933,21 +933,13 @@ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \ (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG)) -/** The ARC4 stream cipher algorithm. - */ -#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001) - -/** The ChaCha20 stream cipher. - * - * ChaCha20 is defined in RFC 7539. - * - * The nonce size for psa_cipher_set_iv() or psa_cipher_generate_iv() - * must be 12. - * - * The initial block counter is always 0. +/** The stream cipher mode of a stream cipher algorithm. * + * The underlying stream cipher is determined by the key type. + * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20. + * - To use ARC4, use a key type of #PSA_KEY_TYPE_ARC4. */ -#define PSA_ALG_CHACHA20 ((psa_algorithm_t)0x04800005) +#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t)0x04800100) /** The CTR stream cipher mode. * @@ -956,19 +948,19 @@ * For example, to use AES-128-CTR, use this algorithm with * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes). */ -#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001) +#define PSA_ALG_CTR ((psa_algorithm_t)0x04c01000) /** The CFB stream cipher mode. * * The underlying block cipher is determined by the key type. */ -#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002) +#define PSA_ALG_CFB ((psa_algorithm_t)0x04c01100) /** The OFB stream cipher mode. * * The underlying block cipher is determined by the key type. */ -#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003) +#define PSA_ALG_OFB ((psa_algorithm_t)0x04c01200) /** The XTS cipher mode. * @@ -976,7 +968,27 @@ * least one full block of input, but beyond this minimum the input * does not need to be a whole number of blocks. */ -#define PSA_ALG_XTS ((psa_algorithm_t)0x044000ff) +#define PSA_ALG_XTS ((psa_algorithm_t)0x0440ff00) + +/** The Electronic Code Book (ECB) mode of a block cipher, with no padding. + * + * \warning ECB mode does not protect the confidentiality of the encrypted data + * except in extremely narrow circumstances. It is recommended that applications + * only use ECB if they need to construct an operating mode that the + * implementation does not provide. Implementations are encouraged to provide + * the modes that applications need in preference to supporting direct access + * to ECB. + * + * The underlying block cipher is determined by the key type. + * + * This symmetric cipher mode can only be used with messages whose lengths are a + * multiple of the block size of the chosen block cipher. + * + * ECB mode does not accept an initialization vector (IV). When using a + * multi-part cipher operation with this algorithm, psa_cipher_generate_iv() + * and psa_cipher_set_iv() must not be called. + */ +#define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t)0x04404400) /** The CBC block cipher chaining mode, with no padding. * @@ -985,7 +997,7 @@ * This symmetric cipher mode can only be used with messages whose lengths * are whole number of blocks for the chosen block cipher. */ -#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t)0x04600100) +#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t)0x04404000) /** The CBC block cipher chaining mode with PKCS#7 padding. * @@ -993,7 +1005,7 @@ * * This is the padding method defined by PKCS#7 (RFC 2315) §10.3. */ -#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101) +#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04404100) #define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000) @@ -1014,13 +1026,13 @@ * * The underlying block cipher is determined by the key type. */ -#define PSA_ALG_CCM ((psa_algorithm_t)0x06401001) +#define PSA_ALG_CCM ((psa_algorithm_t)0x05500100) /** The GCM authenticated encryption algorithm. * * The underlying block cipher is determined by the key type. */ -#define PSA_ALG_GCM ((psa_algorithm_t)0x06401002) +#define PSA_ALG_GCM ((psa_algorithm_t)0x05500200) /** The Chacha20-Poly1305 AEAD algorithm. * @@ -1031,14 +1043,14 @@ * * Implementations must support 16-byte tags and should reject other sizes. */ -#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x06001005) +#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x05100500) /* In the encoding of a AEAD algorithm, the bits corresponding to * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag. * The constants for default lengths follow this encoding. */ -#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x00003f00) -#define PSA_AEAD_TAG_LENGTH_OFFSET 8 +#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x003f0000) +#define PSA_AEAD_TAG_LENGTH_OFFSET 16 /** Macro to build a shortened AEAD algorithm. * @@ -1082,7 +1094,7 @@ PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \ ref : -#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000) +#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x06000200) /** RSA PKCS#1 v1.5 signature with hashing. * * This is the signature scheme defined by RFC 8017 @@ -1110,7 +1122,7 @@ #define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE) -#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x10030000) +#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x06000300) /** RSA PSS signature with hashing. * * This is the signature scheme defined by RFC 8017 @@ -1134,7 +1146,7 @@ #define PSA_ALG_IS_RSA_PSS(alg) \ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) -#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000) +#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x06000600) /** ECDSA signature with hashing. * * This is the ECDSA signature scheme defined by ANSI X9.62, @@ -1167,7 +1179,7 @@ * the curve size. */ #define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE -#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t)0x10070000) +#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t)0x06000700) /** Deterministic ECDSA signature with hashing. * * This is the deterministic ECDSA signature scheme defined by RFC 6979. @@ -1192,7 +1204,7 @@ */ #define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \ (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000) +#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00000100) #define PSA_ALG_IS_ECDSA(alg) \ (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_ECDSA_DETERMINISTIC_FLAG) == \ PSA_ALG_ECDSA_BASE) @@ -1246,9 +1258,9 @@ /** RSA PKCS#1 v1.5 encryption. */ -#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t)0x12020000) +#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t)0x07000200) -#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x12030000) +#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x07000300) /** RSA OAEP encryption. * * This is the encryption scheme defined by RFC 8017 @@ -1272,7 +1284,7 @@ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ 0) -#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x20000100) +#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x08000100) /** Macro to build an HKDF algorithm. * * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256. @@ -1311,7 +1323,7 @@ #define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x20000200) +#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x08000200) /** Macro to build a TLS-1.2 PRF algorithm. * * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, @@ -1354,7 +1366,7 @@ #define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x20000300) +#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x08000300) /** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. * * In a pure-PSK handshake in TLS 1.2, the master secret is derived @@ -1400,8 +1412,8 @@ #define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x0803ffff) -#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0x10fc0000) +#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0xfe00ffff) +#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0xffff0000) /** Macro to build a combined algorithm that chains a key agreement with * a key derivation. @@ -1432,7 +1444,7 @@ * a key derivation function. * Usually, raw key agreement algorithms are constructed directly with * a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are - * constructed with PSA_ALG_KEY_AGREEMENT(). + * constructed with #PSA_ALG_KEY_AGREEMENT(). * * \param alg An algorithm identifier (value of type #psa_algorithm_t). * @@ -1454,7 +1466,7 @@ * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p` * in bits. */ -#define PSA_ALG_FFDH ((psa_algorithm_t)0x30100000) +#define PSA_ALG_FFDH ((psa_algorithm_t)0x09010000) /** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. * @@ -1496,7 +1508,7 @@ * in big-endian byte order. * The bit size is `m` for the field `F_{2^m}`. */ -#define PSA_ALG_ECDH ((psa_algorithm_t)0x30200000) +#define PSA_ALG_ECDH ((psa_algorithm_t)0x09020000) /** Whether the specified algorithm is an elliptic curve Diffie-Hellman * algorithm. @@ -1541,7 +1553,7 @@ /** The default lifetime for volatile keys. * - * A volatile key only exists as long as the handle to it is not closed. + * A volatile key only exists as long as the identifier to it is not destroyed. * The key material is guaranteed to be erased on a power reset. * * A key with this lifetime is typically stored in the RAM area of the @@ -1636,16 +1648,105 @@ /** The minimum value for a key identifier chosen by the application. */ -#define PSA_KEY_ID_USER_MIN ((psa_app_key_id_t)0x00000001) +#define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001) /** The maximum value for a key identifier chosen by the application. */ -#define PSA_KEY_ID_USER_MAX ((psa_app_key_id_t)0x3fffffff) +#define PSA_KEY_ID_USER_MAX ((psa_key_id_t)0x3fffffff) /** The minimum value for a key identifier chosen by the implementation. */ -#define PSA_KEY_ID_VENDOR_MIN ((psa_app_key_id_t)0x40000000) +#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t)0x40000000) /** The maximum value for a key identifier chosen by the implementation. */ -#define PSA_KEY_ID_VENDOR_MAX ((psa_app_key_id_t)0x7fffffff) +#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t)0x7fffffff) + + +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + +#define MBEDTLS_SVC_KEY_ID_INIT ( (psa_key_id_t)0 ) +#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( id ) +#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( 0 ) + +/** Utility to initialize a key identifier at runtime. + * + * \param unused Unused parameter. + * \param key_id Identifier of the key. + */ +static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( + unsigned int unused, psa_key_id_t key_id ) +{ + (void)unused; + + return( key_id ); +} + +/** Compare two key identifiers. + * + * \param id1 First key identifier. + * \param id2 Second key identifier. + * + * \return Non-zero if the two key identifier are equal, zero otherwise. + */ +static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1, + mbedtls_svc_key_id_t id2 ) +{ + return( id1 == id2 ); +} + +/** Check whether a key identifier is null. + * + * \param key Key identifier. + * + * \return Non-zero if the key identifier is null, zero otherwise. + */ +static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key ) +{ + return( key == 0 ); +} + +#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ + +#define MBEDTLS_SVC_KEY_ID_INIT ( (mbedtls_svc_key_id_t){ 0, 0 } ) +#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( ( id ).key_id ) +#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( ( id ).owner ) + +/** Utility to initialize a key identifier at runtime. + * + * \param owner_id Identifier of the key owner. + * \param key_id Identifier of the key. + */ +static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( + mbedtls_key_owner_id_t owner_id, psa_key_id_t key_id ) +{ + return( (mbedtls_svc_key_id_t){ .key_id = key_id, + .owner = owner_id } ); +} + +/** Compare two key identifiers. + * + * \param id1 First key identifier. + * \param id2 Second key identifier. + * + * \return Non-zero if the two key identifier are equal, zero otherwise. + */ +static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1, + mbedtls_svc_key_id_t id2 ) +{ + return( ( id1.key_id == id2.key_id ) && + mbedtls_key_owner_id_equal( id1.owner, id2.owner ) ); +} + +/** Check whether a key identifier is null. + * + * \param key Key identifier. + * + * \return Non-zero if the key identifier is null, zero otherwise. + */ +static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key ) +{ + return( ( key.key_id == 0 ) && ( key.owner == 0 ) ); +} + +#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ /**@}*/ @@ -1712,7 +1813,7 @@ * * For a key pair, this concerns the private key. */ -#define PSA_KEY_USAGE_SIGN_HASH ((psa_key_usage_t)0x00000400) +#define PSA_KEY_USAGE_SIGN_HASH ((psa_key_usage_t)0x00001000) /** Whether the key may be used to verify a message signature. * @@ -1722,11 +1823,11 @@ * * For a key pair, this concerns the public key. */ -#define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t)0x00000800) +#define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t)0x00002000) /** Whether the key may be used to derive other keys. */ -#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00001000) +#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00004000) /**@}*/ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/crypto_struct.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/crypto_struct.h index 67c53db9286..6a018e1f901 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/crypto_struct.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/crypto_struct.h @@ -77,6 +77,16 @@ extern "C" { #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +typedef struct { + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_driver_wrappers.h */ + unsigned int id; + /** Context structure for the assigned driver, when id is not zero. */ + void* ctx; +} psa_operation_driver_context_t; + struct psa_hash_operation_s { psa_algorithm_t alg; @@ -158,16 +168,18 @@ struct psa_cipher_operation_s unsigned int key_set : 1; unsigned int iv_required : 1; unsigned int iv_set : 1; + unsigned int mbedtls_in_use : 1; /* Indicates mbed TLS is handling the operation. */ uint8_t iv_size; uint8_t block_size; union { unsigned dummy; /* Enable easier initializing of the union. */ mbedtls_cipher_context_t cipher; + psa_operation_driver_context_t driver; } ctx; }; -#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, {0}} +#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}} static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) { const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; @@ -330,12 +342,12 @@ typedef struct psa_key_type_t type; psa_key_bits_t bits; psa_key_lifetime_t lifetime; - psa_key_id_t id; + mbedtls_svc_key_id_t id; psa_key_policy_t policy; psa_key_attributes_flag_t flags; } psa_core_key_attributes_t; -#define PSA_CORE_KEY_ATTRIBUTES_INIT {PSA_KEY_TYPE_NONE, 0, PSA_KEY_LIFETIME_VOLATILE, PSA_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0} +#define PSA_CORE_KEY_ATTRIBUTES_INIT {PSA_KEY_TYPE_NONE, 0, PSA_KEY_LIFETIME_VOLATILE, MBEDTLS_SVC_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0} struct psa_key_attributes_s { @@ -359,29 +371,44 @@ static inline struct psa_key_attributes_s psa_key_attributes_init( void ) return( v ); } -static inline void psa_set_key_id(psa_key_attributes_t *attributes, - psa_key_id_t id) +static inline void psa_set_key_id( psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t key ) { - attributes->core.id = id; - if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE ) - attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT; + psa_key_lifetime_t lifetime = attributes->core.lifetime; + + attributes->core.id = key; + + if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) + { + attributes->core.lifetime = + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_LIFETIME_PERSISTENT, + PSA_KEY_LIFETIME_GET_LOCATION( lifetime ) ); + } } -static inline psa_key_id_t psa_get_key_id( +static inline mbedtls_svc_key_id_t psa_get_key_id( const psa_key_attributes_t *attributes) { return( attributes->core.id ); } +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +static inline void mbedtls_set_key_owner_id( psa_key_attributes_t *attributes, + mbedtls_key_owner_id_t owner ) +{ + attributes->core.id.owner = owner; +} +#endif + static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime) { attributes->core.lifetime = lifetime; - if( lifetime == PSA_KEY_LIFETIME_VOLATILE ) + if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) { -#ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER attributes->core.id.key_id = 0; - attributes->core.id.owner = 0; #else attributes->core.id = 0; #endif diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto.c index bffddc995be..82b95dc6dd1 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto.c @@ -22,11 +22,16 @@ #if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +#include "check_crypto_config.h" +#endif + #include "psa_crypto_service_integration.h" #include "psa/crypto.h" #include "psa_crypto_core.h" #include "psa_crypto_invasive.h" +#include "psa_crypto_driver_wrappers.h" #if defined(MBEDTLS_PSA_CRYPTO_SE_C) #include "psa_crypto_se.h" #endif @@ -124,7 +129,7 @@ static psa_global_data_t global_data; if( global_data.initialized == 0 ) \ return( PSA_ERROR_BAD_STATE ); -static psa_status_t mbedtls_to_psa_error( int ret ) +psa_status_t mbedtls_to_psa_error( int ret ) { /* If there's both a high-level code and low-level code, dispatch on * the high-level code. */ @@ -198,7 +203,7 @@ static psa_status_t mbedtls_to_psa_error( int ret ) case MBEDTLS_ERR_CIPHER_INVALID_PADDING: return( PSA_ERROR_INVALID_PADDING ); case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED: - return( PSA_ERROR_BAD_STATE ); + return( PSA_ERROR_INVALID_ARGUMENT ); case MBEDTLS_ERR_CIPHER_AUTH_FAILED: return( PSA_ERROR_INVALID_SIGNATURE ); case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT: @@ -369,7 +374,15 @@ static inline int psa_key_slot_is_external( const psa_key_slot_t *slot ) } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -#if defined(MBEDTLS_ECP_C) +/* For now the MBEDTLS_PSA_ACCEL_ guards are also used here since the + * current test driver in key_management.c is using this function + * when accelerators are used for ECC key pair and public key. + * Once that dependency is resolved these guards can be removed. + */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve, size_t byte_length ) { @@ -437,7 +450,10 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve, return( MBEDTLS_ECP_DP_NONE ); } } -#endif /* defined(MBEDTLS_ECP_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || + * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */ static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type, size_t bits ) @@ -446,9 +462,7 @@ static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type, switch( type ) { case PSA_KEY_TYPE_RAW_DATA: -#if defined(MBEDTLS_MD_C) case PSA_KEY_TYPE_HMAC: -#endif case PSA_KEY_TYPE_DERIVE: break; #if defined(MBEDTLS_AES_C) @@ -490,9 +504,13 @@ static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type, return( PSA_SUCCESS ); } -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) -#if defined(MBEDTLS_PK_PARSE_C) /* 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 @@ -514,7 +532,6 @@ static psa_status_t psa_check_rsa_key_byte_aligned( mbedtls_mpi_free( &n ); return( status ); } -#endif /* MBEDTLS_PK_PARSE_C */ /** Load the contents of a key buffer into an internal RSA representation * @@ -531,7 +548,6 @@ static psa_status_t psa_load_rsa_representation( psa_key_type_t type, size_t data_length, mbedtls_rsa_context **p_rsa ) { -#if defined(MBEDTLS_PK_PARSE_C) psa_status_t status; mbedtls_pk_context ctx; size_t bits; @@ -576,15 +592,18 @@ static psa_status_t psa_load_rsa_representation( psa_key_type_t type, exit: mbedtls_pk_free( &ctx ); return( status ); -#else - (void) data; - (void) data_length; - (void) type; - (void) rsa; - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* MBEDTLS_PK_PARSE_C */ } +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ + +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) + /** Export an RSA key to export representation * * \param[in] type The type of key (public/private) to export @@ -708,9 +727,15 @@ static psa_status_t psa_import_rsa_key( psa_key_slot_t *slot, return( PSA_SUCCESS ); } -#endif /* defined(MBEDTLS_RSA_C) */ -#if defined(MBEDTLS_ECP_C) +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ + +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) /** Load the contents of a key buffer into an internal ECP representation * * \param[in] type The type of key contained in \p data. @@ -738,7 +763,7 @@ static psa_status_t psa_load_ecp_representation( psa_key_type_t type, * - 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 n is the key size in bits. + * 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 ); @@ -810,7 +835,14 @@ static psa_status_t psa_load_ecp_representation( psa_key_type_t type, return( status ); } +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) /** Export an ECP key to export representation * * \param[in] type The type of key (public/private) to export @@ -929,7 +961,8 @@ static psa_status_t psa_import_ecp_key( psa_key_slot_t *slot, return( PSA_SUCCESS ); } -#endif /* defined(MBEDTLS_ECP_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ /** Return the size of the key in the given slot, in bits. * @@ -968,14 +1001,45 @@ static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot, return( PSA_SUCCESS ); } -/** Import key data into a slot. `slot->attr.type` must have been set - * previously. This function assumes that the slot does not contain - * any key material yet. On failure, the slot content is unchanged. */ -psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, - const uint8_t *data, - size_t data_length ) +psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot, + const uint8_t* data, + size_t data_length ) +{ + psa_status_t status = psa_allocate_buffer_to_slot( slot, + data_length ); + if( status != PSA_SUCCESS ) + return( status ); + + memcpy( slot->data.key.data, data, data_length ); + return( PSA_SUCCESS ); +} + +/** Import key data into a slot. + * + * `slot->type` must have been set previously. + * This function assumes that the slot does not contain any key material yet. + * On failure, the slot content is unchanged. + * + * Persistent storage is not affected. + * + * \param[in,out] slot The key slot to import data into. + * Its `type` field must have previously been set to + * the desired key type. + * It must not contain any key material yet. + * \param[in] data Buffer containing the key material to parse and import. + * \param data_length Size of \p data in bytes. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +static psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, + const uint8_t *data, + size_t data_length ) { psa_status_t status = PSA_SUCCESS; + size_t bit_size; /* zero-length keys are never supported. */ if( data_length == 0 ) @@ -983,7 +1047,7 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, if( key_type_is_raw_bytes( slot->attr.type ) ) { - size_t bit_size = PSA_BYTES_TO_BITS( data_length ); + bit_size = PSA_BYTES_TO_BITS( data_length ); /* Ensure that the bytes-to-bits conversion hasn't overflown. */ if( data_length > SIZE_MAX / 8 ) @@ -999,47 +1063,69 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, return( status ); /* Allocate memory for the key */ - status = psa_allocate_buffer_to_slot( slot, data_length ); + status = psa_copy_key_material_into_slot( slot, data, data_length ); if( status != PSA_SUCCESS ) return( status ); - /* copy key into allocated buffer */ - memcpy( slot->data.key.data, data, data_length ); - /* Write the actual key size to the slot. * psa_start_key_creation() wrote the size declared by the * caller, which may be 0 (meaning unspecified) or wrong. */ slot->attr.bits = (psa_key_bits_t) bit_size; + + return( PSA_SUCCESS ); } - else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) - { -#if defined(MBEDTLS_ECP_C) - status = psa_import_ecp_key( slot, - data, data_length ); -#else - /* No drivers have been implemented yet, so without mbed TLS backing - * there's no way to do ECP with the current library. */ + else if( PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) ) + { + /* Try validation through accelerators first. */ + bit_size = slot->attr.bits; + psa_key_attributes_t attributes = { + .core = slot->attr + }; + status = psa_driver_wrapper_validate_key( &attributes, + data, + data_length, + &bit_size ); + if( status == PSA_SUCCESS ) + { + /* Key has been validated successfully by an accelerator. + * Copy key material into slot. */ + status = psa_copy_key_material_into_slot( slot, data, data_length ); + if( status != PSA_SUCCESS ) + return( status ); + + slot->attr.bits = (psa_key_bits_t) bit_size; + return( PSA_SUCCESS ); + } + else if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); + + /* Key format is not supported by any accelerator, try software fallback + * if present. */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) + { + return( psa_import_ecp_key( slot, data, data_length ) ); + } +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) + { + return( psa_import_rsa_key( slot, data, data_length ) ); + } +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ + + /* Fell through the fallback as well, so have nothing else to try. */ return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* defined(MBEDTLS_ECP_C) */ - } - else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) - { -#if defined(MBEDTLS_RSA_C) - status = psa_import_rsa_key( slot, - data, data_length ); -#else - /* No drivers have been implemented yet, so without mbed TLS backing - * there's no way to do RSA with the current library. */ - status = PSA_ERROR_NOT_SUPPORTED; -#endif /* defined(MBEDTLS_RSA_C) */ } else { /* Unknown key type */ return( PSA_ERROR_NOT_SUPPORTED ); } - - return( status ); } /** Calculate the intersection of two algorithm usage policies. @@ -1083,6 +1169,15 @@ static int psa_key_algorithm_permits( psa_algorithm_t policy_alg, return( ( policy_alg & ~PSA_ALG_HASH_MASK ) == ( requested_alg & ~PSA_ALG_HASH_MASK ) ); } + /* If policy_alg is a generic key agreement operation, then using it for + * a key derivation with that key agreement should also be allowed. This + * behaviour is expected to be defined in a future specification version. */ + if( PSA_ALG_IS_RAW_KEY_AGREEMENT( policy_alg ) && + PSA_ALG_IS_KEY_AGREEMENT( requested_alg ) ) + { + return( PSA_ALG_KEY_AGREEMENT_GET_BASE( requested_alg ) == + policy_alg ); + } /* If it isn't permitted, it's forbidden. */ return( 0 ); } @@ -1128,22 +1223,31 @@ static psa_status_t psa_restrict_key_policy( return( PSA_SUCCESS ); } -/** Retrieve a slot which must contain a key. The key must have allow all the - * usage flags set in \p usage. If \p alg is nonzero, the key must allow - * operations with this algorithm. */ -static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg ) +/** Get the description of a key given its identifier and policy constraints + * and lock it. + * + * The key must have allow all the usage flags set in \p usage. If \p alg is + * nonzero, the key must allow operations with this algorithm. + * + * In case of a persistent key, the function loads the description of the key + * into a key slot if not already done. + * + * On success, the returned key slot is locked. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. + */ +static psa_status_t psa_get_and_lock_key_slot_with_policy( + mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot, + psa_key_usage_t usage, + psa_algorithm_t alg ) { - psa_status_t status; - psa_key_slot_t *slot = NULL; - - *p_slot = NULL; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; - status = psa_get_key_slot( handle, &slot ); + status = psa_get_and_lock_key_slot( key, p_slot ); if( status != PSA_SUCCESS ) return( status ); + slot = *p_slot; /* Enforce that usage policy for the key slot contains all the flags * required by the usage parameter. There is one exception: public @@ -1151,45 +1255,61 @@ static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle, * if they had the export flag. */ if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ) usage &= ~PSA_KEY_USAGE_EXPORT; + + status = PSA_ERROR_NOT_PERMITTED; if( ( slot->attr.policy.usage & usage ) != usage ) - return( PSA_ERROR_NOT_PERMITTED ); + goto error; /* Enforce that the usage policy permits the requested algortihm. */ if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) ) - return( PSA_ERROR_NOT_PERMITTED ); + goto error; - *p_slot = slot; return( PSA_SUCCESS ); + +error: + *p_slot = NULL; + psa_unlock_key_slot( slot ); + + return( status ); } -/** Retrieve a slot which must contain a transparent key. +/** Get a key slot containing a transparent key and lock it. * * A transparent key is a key for which the key material is directly * available, as opposed to a key in a secure element. * - * This is a temporary function to use instead of psa_get_key_from_slot() - * until secure element support is fully implemented. + * This is a temporary function to use instead of + * psa_get_and_lock_key_slot_with_policy() until secure element support is + * fully implemented. + * + * On success, the returned key slot is locked. It is the responsibility of the + * caller to unlock the key slot when it does not access it anymore. */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) -static psa_status_t psa_get_transparent_key( psa_key_handle_t handle, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg ) +static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( + mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot, + psa_key_usage_t usage, + psa_algorithm_t alg ) { - psa_status_t status = psa_get_key_from_slot( handle, p_slot, usage, alg ); + psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot, + usage, alg ); if( status != PSA_SUCCESS ) return( status ); + if( psa_key_slot_is_external( *p_slot ) ) { + psa_unlock_key_slot( *p_slot ); *p_slot = NULL; return( PSA_ERROR_NOT_SUPPORTED ); } + return( PSA_SUCCESS ); } #else /* MBEDTLS_PSA_CRYPTO_SE_C */ /* With no secure element support, all keys are transparent. */ -#define psa_get_transparent_key( handle, p_slot, usage, alg ) \ - psa_get_key_from_slot( handle, p_slot, usage, alg ) +#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \ + psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg ) #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ /** Wipe key data from a slot. Preserve metadata such as the policy. */ @@ -1220,6 +1340,22 @@ static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ) { psa_status_t status = psa_remove_key_data_from_memory( slot ); + + /* + * As the return error code may not be handled in case of multiple errors, + * do our best to report an unexpected lock counter: if available + * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as + * part of the execution of a test suite this will stop the test suite + * execution). + */ + if( slot->lock_count != 1 ) + { +#ifdef MBEDTLS_CHECK_PARAMS + MBEDTLS_PARAM_FAILED( slot->lock_count == 1 ); +#endif + status = PSA_ERROR_CORRUPTION_DETECTED; + } + /* Multipart operations may still be using the key. This is safe * because all multipart operation objects are independent from * the key slot: if they need to access the key after the setup @@ -1232,7 +1368,7 @@ psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ) return( status ); } -psa_status_t psa_destroy_key( psa_key_handle_t handle ) +psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) { psa_key_slot_t *slot; psa_status_t status; /* status of the last operation */ @@ -1241,13 +1377,33 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) psa_se_drv_table_entry_t *driver; #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - if( handle == 0 ) + if( mbedtls_svc_key_id_is_null( key ) ) return( PSA_SUCCESS ); - status = psa_get_key_slot( handle, &slot ); + /* + * Get the description of the key in a key slot. In case of a persistent + * key, this will load the key description from persistent memory if not + * done yet. We cannot avoid this loading as without it we don't know if + * the key is operated by an SE or not and this information is needed by + * the current implementation. + */ + status = psa_get_and_lock_key_slot( key, &slot ); if( status != PSA_SUCCESS ) return( status ); + /* + * If the key slot containing the key description is under access by the + * library (apart from the present access), the key cannot be destroyed + * yet. For the time being, just return in error. Eventually (to be + * implemented), the key should be destroyed when all accesses have + * stopped. + */ + if( slot->lock_count > 1 ) + { + psa_unlock_key_slot( slot ); + return( PSA_ERROR_GENERIC_ERROR ); + } + #if defined(MBEDTLS_PSA_CRYPTO_SE_C) driver = psa_get_se_driver_entry( slot->attr.lifetime ); if( driver != NULL ) @@ -1283,7 +1439,7 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( slot->attr.lifetime != PSA_KEY_LIFETIME_VOLATILE ) + if( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) { status = psa_destroy_persistent_key( slot->attr.id ); if( overall_status == PSA_SUCCESS ) @@ -1367,7 +1523,8 @@ psa_status_t psa_get_key_domain_parameters( return( PSA_SUCCESS ); } -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) static psa_status_t psa_get_rsa_public_exponent( const mbedtls_rsa_context *rsa, psa_key_attributes_t *attributes ) @@ -1407,19 +1564,21 @@ static psa_status_t psa_get_rsa_public_exponent( mbedtls_free( buffer ); return( mbedtls_to_psa_error( ret ) ); } -#endif /* MBEDTLS_RSA_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ /** Retrieve all the publicly-accessible attributes of a key. */ -psa_status_t psa_get_key_attributes( psa_key_handle_t handle, +psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key, psa_key_attributes_t *attributes ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; psa_reset_key_attributes( attributes ); - status = psa_get_key_from_slot( handle, &slot, 0, 0 ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 ); if( status != PSA_SUCCESS ) return( status ); @@ -1434,7 +1593,8 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, switch( slot->attr.type ) { -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) case PSA_KEY_TYPE_RSA_KEY_PAIR: case PSA_KEY_TYPE_RSA_PUBLIC_KEY: #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -1461,7 +1621,8 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, mbedtls_free( rsa ); } break; -#endif /* MBEDTLS_RSA_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ default: /* Nothing else to do. */ break; @@ -1469,7 +1630,10 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, if( status != PSA_SUCCESS ) psa_reset_key_attributes( attributes ); - return( status ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -1557,13 +1721,24 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, /* Exporting private -> private */ return( psa_internal_export_key_buffer( slot, data, data_size, data_length ) ); } + /* Need to export the public part of a private key, - * so conversion is needed */ + * so conversion is needed. Try the accelerators first. */ + psa_status_t status = psa_driver_wrapper_export_public_key( slot, + data, + data_size, + data_length ); + + if( status != PSA_ERROR_NOT_SUPPORTED || + psa_key_lifetime_is_external( slot->attr.lifetime ) ) + return( status ); + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) mbedtls_rsa_context *rsa = NULL; - psa_status_t status = psa_load_rsa_representation( + status = psa_load_rsa_representation( slot->attr.type, slot->data.key.data, slot->data.key.bytes, @@ -1584,13 +1759,15 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, #else /* We don't know how to convert a private RSA key to public. */ return( PSA_ERROR_NOT_SUPPORTED ); -#endif +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ } else { -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) mbedtls_ecp_keypair *ecp = NULL; - psa_status_t status = psa_load_ecp_representation( + status = psa_load_ecp_representation( slot->attr.type, slot->data.key.data, slot->data.key.bytes, @@ -1612,7 +1789,8 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, #else /* We don't know how to convert a private ECC key to public */ return( PSA_ERROR_NOT_SUPPORTED ); -#endif +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ } } else @@ -1624,13 +1802,14 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, } } -psa_status_t psa_export_key( psa_key_handle_t handle, +psa_status_t psa_export_key( mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size, size_t *data_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; /* Set the key to empty now, so that even when there are errors, we always * set data_length to a value between 0 and data_size. On error, setting @@ -1639,22 +1818,28 @@ psa_status_t psa_export_key( psa_key_handle_t handle, *data_length = 0; /* Export requires the EXPORT flag. There is an exception for public keys, - * which don't require any flag, but psa_get_key_from_slot takes - * care of this. */ - status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 ); + * which don't require any flag, but + * psa_get_and_lock_key_slot_with_policy() takes care of this. + */ + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_EXPORT, 0 ); if( status != PSA_SUCCESS ) return( status ); - return( psa_internal_export_key( slot, data, data_size, - data_length, 0 ) ); + + status = psa_internal_export_key( slot, data, data_size, data_length, 0 ); + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } -psa_status_t psa_export_public_key( psa_key_handle_t handle, +psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size, size_t *data_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; /* Set the key to empty now, so that even when there are errors, we always * set data_length to a value between 0 and data_size. On error, setting @@ -1663,11 +1848,14 @@ psa_status_t psa_export_public_key( psa_key_handle_t handle, *data_length = 0; /* Exporting a public key doesn't require a usage flag. */ - status = psa_get_key_from_slot( handle, &slot, 0, 0 ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 ); if( status != PSA_SUCCESS ) return( status ); - return( psa_internal_export_key( slot, data, data_size, - data_length, 1 ) ); + + status = psa_internal_export_key( slot, data, data_size, data_length, 1 ); + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } #if defined(static_assert) @@ -1717,17 +1905,29 @@ static psa_status_t psa_validate_key_attributes( psa_se_drv_table_entry_t **p_drv ) { psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_lifetime_t lifetime = psa_get_key_lifetime( attributes ); + mbedtls_svc_key_id_t key = psa_get_key_id( attributes ); - status = psa_validate_key_location( psa_get_key_lifetime( attributes ), - p_drv ); + status = psa_validate_key_location( lifetime, p_drv ); if( status != PSA_SUCCESS ) return( status ); - status = psa_validate_key_persistence( psa_get_key_lifetime( attributes ), - psa_get_key_id( attributes ) ); + status = psa_validate_key_persistence( lifetime ); if( status != PSA_SUCCESS ) return( status ); + if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) + { + if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ) != 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + } + else + { + status = psa_validate_key_id( psa_get_key_id( attributes ), 0 ); + if( status != PSA_SUCCESS ) + return( status ); + } + status = psa_validate_key_policy( &attributes->core.policy ); if( status != PSA_SUCCESS ) return( status ); @@ -1755,15 +1955,18 @@ static psa_status_t psa_validate_key_attributes( * * This function is intended to be used as follows: * -# Call psa_start_key_creation() to allocate a key slot, prepare - * it with the specified attributes, and assign it a handle. + * it with the specified attributes, and in case of a volatile key assign it + * a volatile key identifier. * -# Populate the slot with the key material. * -# Call psa_finish_key_creation() to finalize the creation of the slot. * In case of failure at any step, stop the sequence and call * psa_fail_key_creation(). * + * On success, the key slot is locked. It is the responsibility of the caller + * to unlock the key slot when it does not access it anymore. + * * \param method An identification of the calling function. * \param[in] attributes Key attributes for the new key. - * \param[out] handle On success, a handle for the allocated slot. * \param[out] p_slot On success, a pointer to the prepared slot. * \param[out] p_drv On any return, the driver for the key, if any. * NULL for a transparent key. @@ -1776,11 +1979,11 @@ static psa_status_t psa_validate_key_attributes( static psa_status_t psa_start_key_creation( psa_key_creation_method_t method, const psa_key_attributes_t *attributes, - psa_key_handle_t *handle, psa_key_slot_t **p_slot, psa_se_drv_table_entry_t **p_drv ) { psa_status_t status; + psa_key_id_t volatile_key_id; psa_key_slot_t *slot; (void) method; @@ -1790,7 +1993,7 @@ static psa_status_t psa_start_key_creation( if( status != PSA_SUCCESS ) return( status ); - status = psa_get_empty_key_slot( handle, p_slot ); + status = psa_get_empty_key_slot( &volatile_key_id, p_slot ); if( status != PSA_SUCCESS ) return( status ); slot = *p_slot; @@ -1799,9 +2002,19 @@ static psa_status_t psa_start_key_creation( * creation mechanism to verify that this information is correct. * It's automatically correct for mechanisms that use the bit-size as * an input (generate, device) but not for those where the bit-size - * is optional (import, copy). */ + * is optional (import, copy). In case of a volatile key, assign it the + * volatile key identifier associated to the slot returned to contain its + * definition. */ slot->attr = attributes->core; + if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) + { +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + slot->attr.id = volatile_key_id; +#else + slot->attr.id.key_id = volatile_key_id; +#endif + } /* Erase external-only flags from the internal copy. To access * external-only flags, query `attributes`. Thanks to the check @@ -1857,7 +2070,7 @@ static psa_status_t psa_start_key_creation( } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - return( status ); + return( PSA_SUCCESS ); } /** Finalize the creation of a key once its key material has been set. @@ -1868,18 +2081,25 @@ static psa_status_t psa_start_key_creation( * See the documentation of psa_start_key_creation() for the intended use * of this function. * + * If the finalization succeeds, the function unlocks the key slot (it was + * locked by psa_start_key_creation()) and the key slot cannot be accessed + * anymore as part of the key creation process. + * * \param[in,out] slot Pointer to the slot with key material. * \param[in] driver The secure element driver for the key, * or NULL for a transparent key. + * \param[out] key On success, identifier of the key. Note that the + * key identifier is also stored in the key slot. * * \retval #PSA_SUCCESS - * The key was successfully created. The handle is now valid. + * The key was successfully created. * \return If this function fails, the key slot is an invalid state. * You must call psa_fail_key_creation() to wipe and free the slot. */ static psa_status_t psa_finish_key_creation( psa_key_slot_t *slot, - psa_se_drv_table_entry_t *driver ) + psa_se_drv_table_entry_t *driver, + mbedtls_svc_key_id_t *key) { psa_status_t status = PSA_SUCCESS; (void) slot; @@ -1896,13 +2116,9 @@ static psa_status_t psa_finish_key_creation( static_assert( sizeof( slot->data.se.slot_number ) == sizeof( data.slot_number ), "Slot number size does not match psa_se_key_data_storage_t" ); - static_assert( sizeof( slot->attr.bits ) == sizeof( data.bits ), - "Bit-size size does not match psa_se_key_data_storage_t" ); #endif memcpy( &data.slot_number, &slot->data.se.slot_number, sizeof( slot->data.se.slot_number ) ); - memcpy( &data.bits, &slot->attr.bits, - sizeof( slot->attr.bits ) ); status = psa_save_persistent_key( &slot->attr, (uint8_t*) &data, sizeof( data ) ); @@ -1910,22 +2126,11 @@ static psa_status_t psa_finish_key_creation( else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ { - size_t buffer_size = - PSA_KEY_EXPORT_MAX_SIZE( slot->attr.type, - slot->attr.bits ); - uint8_t *buffer = mbedtls_calloc( 1, buffer_size ); - size_t length = 0; - if( buffer == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - status = psa_internal_export_key( slot, - buffer, buffer_size, &length, - 0 ); - if( status == PSA_SUCCESS ) - status = psa_save_persistent_key( &slot->attr, - buffer, length ); - - mbedtls_platform_zeroize( buffer, buffer_size ); - mbedtls_free( buffer ); + /* Key material is saved in export representation in the slot, so + * just pass the slot buffer for storage. */ + status = psa_save_persistent_key( &slot->attr, + slot->data.key.data, + slot->data.key.bytes ); } } #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ @@ -1946,11 +2151,17 @@ static psa_status_t psa_finish_key_creation( return( status ); } status = psa_crypto_stop_transaction( ); - if( status != PSA_SUCCESS ) - return( status ); } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + if( status == PSA_SUCCESS ) + { + *key = slot->attr.id; + status = psa_unlock_key_slot( slot ); + if( status != PSA_SUCCESS ) + *key = MBEDTLS_SVC_KEY_ID_INIT; + } + return( status ); } @@ -2015,7 +2226,8 @@ static psa_status_t psa_validate_optional_attributes( if( attributes->domain_parameters_size != 0 ) { -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_rsa_context *rsa = NULL; @@ -2052,7 +2264,8 @@ static psa_status_t psa_validate_optional_attributes( return( mbedtls_to_psa_error( ret ) ); } else -#endif +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || + * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ { return( PSA_ERROR_INVALID_ARGUMENT ); } @@ -2070,12 +2283,14 @@ static psa_status_t psa_validate_optional_attributes( psa_status_t psa_import_key( const psa_key_attributes_t *attributes, const uint8_t *data, size_t data_length, - psa_key_handle_t *handle ) + mbedtls_svc_key_id_t *key ) { psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + *key = MBEDTLS_SVC_KEY_ID_INIT; + /* Reject zero-length symmetric keys (including raw data key objects). * This also rejects any key which might be encoded as an empty string, * which is never valid. */ @@ -2083,7 +2298,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, return( PSA_ERROR_INVALID_ARGUMENT ); status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes, - handle, &slot, &driver ); + &slot, &driver ); if( status != PSA_SUCCESS ) goto exit; @@ -2124,13 +2339,11 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, if( status != PSA_SUCCESS ) goto exit; - status = psa_finish_key_creation( slot, driver ); + status = psa_finish_key_creation( slot, driver, key ); exit: if( status != PSA_SUCCESS ) - { psa_fail_key_creation( slot, driver ); - *handle = 0; - } + return( status ); } @@ -2141,7 +2354,7 @@ psa_status_t mbedtls_psa_register_se_key( psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; - psa_key_handle_t handle = 0; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; /* Leaving attributes unspecified is not currently supported. * It could make sense to query the key type and size from the @@ -2153,19 +2366,18 @@ psa_status_t mbedtls_psa_register_se_key( return( PSA_ERROR_NOT_SUPPORTED ); status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes, - &handle, &slot, &driver ); + &slot, &driver ); if( status != PSA_SUCCESS ) goto exit; - status = psa_finish_key_creation( slot, driver ); + status = psa_finish_key_creation( slot, driver, &key ); exit: if( status != PSA_SUCCESS ) - { psa_fail_key_creation( slot, driver ); - } + /* Registration doesn't keep the key in RAM. */ - psa_close_key( handle ); + psa_close_key( key ); return( status ); } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ @@ -2173,40 +2385,33 @@ psa_status_t mbedtls_psa_register_se_key( static psa_status_t psa_copy_key_material( const psa_key_slot_t *source, psa_key_slot_t *target ) { - psa_status_t status; - uint8_t *buffer = NULL; - size_t buffer_size = 0; - size_t length; - - buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type, - psa_get_key_slot_bits( source ) ); - buffer = mbedtls_calloc( 1, buffer_size ); - if( buffer == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 ); + psa_status_t status = psa_copy_key_material_into_slot( target, + source->data.key.data, + source->data.key.bytes ); if( status != PSA_SUCCESS ) - goto exit; + return( status ); + target->attr.type = source->attr.type; - status = psa_import_key_into_slot( target, buffer, length ); + target->attr.bits = source->attr.bits; -exit: - mbedtls_platform_zeroize( buffer, buffer_size ); - mbedtls_free( buffer ); - return( status ); + return( PSA_SUCCESS ); } -psa_status_t psa_copy_key( psa_key_handle_t source_handle, +psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key, const psa_key_attributes_t *specified_attributes, - psa_key_handle_t *target_handle ) + mbedtls_svc_key_id_t *target_key ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *source_slot = NULL; psa_key_slot_t *target_slot = NULL; psa_key_attributes_t actual_attributes = *specified_attributes; psa_se_drv_table_entry_t *driver = NULL; - status = psa_get_transparent_key( source_handle, &source_slot, - PSA_KEY_USAGE_COPY, 0 ); + *target_key = MBEDTLS_SVC_KEY_ID_INIT; + + status = psa_get_and_lock_transparent_key_slot_with_policy( + source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 ); if( status != PSA_SUCCESS ) goto exit; @@ -2220,9 +2425,8 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle, if( status != PSA_SUCCESS ) goto exit; - status = psa_start_key_creation( PSA_KEY_CREATION_COPY, - &actual_attributes, - target_handle, &target_slot, &driver ); + status = psa_start_key_creation( PSA_KEY_CREATION_COPY, &actual_attributes, + &target_slot, &driver ); if( status != PSA_SUCCESS ) goto exit; @@ -2239,14 +2443,14 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle, if( status != PSA_SUCCESS ) goto exit; - status = psa_finish_key_creation( target_slot, driver ); + status = psa_finish_key_creation( target_slot, driver, target_key ); exit: if( status != PSA_SUCCESS ) - { psa_fail_key_creation( target_slot, driver ); - *target_handle = 0; - } - return( status ); + + unlock_status = psa_unlock_key_slot( source_slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -2255,42 +2459,47 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle, /* Message digests */ /****************************************************************/ -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg ) { switch( alg ) { -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: return( &mbedtls_md2_info ); #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: return( &mbedtls_md4_info ); #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) case PSA_ALG_MD5: return( &mbedtls_md5_info ); #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) case PSA_ALG_RIPEMD160: return( &mbedtls_ripemd160_info ); #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) case PSA_ALG_SHA_1: return( &mbedtls_sha1_info ); #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) case PSA_ALG_SHA_224: return( &mbedtls_sha224_info ); +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) case PSA_ALG_SHA_256: return( &mbedtls_sha256_info ); #endif -#if defined(MBEDTLS_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) case PSA_ALG_SHA_384: return( &mbedtls_sha384_info ); #endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) case PSA_ALG_SHA_512: return( &mbedtls_sha512_info ); #endif @@ -2298,7 +2507,10 @@ static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg ) return( NULL ); } } -#endif +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) { @@ -2309,41 +2521,47 @@ psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) * in use. It's ok to call abort on such an object, and there's * nothing to do. */ break; -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: mbedtls_md2_free( &operation->ctx.md2 ); break; #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: mbedtls_md4_free( &operation->ctx.md4 ); break; #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) case PSA_ALG_MD5: mbedtls_md5_free( &operation->ctx.md5 ); break; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) case PSA_ALG_RIPEMD160: mbedtls_ripemd160_free( &operation->ctx.ripemd160 ); break; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) case PSA_ALG_SHA_1: mbedtls_sha1_free( &operation->ctx.sha1 ); break; #endif -#if defined(MBEDTLS_SHA256_C) +#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_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#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; @@ -2368,53 +2586,55 @@ psa_status_t psa_hash_setup( psa_hash_operation_t *operation, switch( alg ) { -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: mbedtls_md2_init( &operation->ctx.md2 ); ret = mbedtls_md2_starts_ret( &operation->ctx.md2 ); break; #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: mbedtls_md4_init( &operation->ctx.md4 ); ret = mbedtls_md4_starts_ret( &operation->ctx.md4 ); break; #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) case PSA_ALG_MD5: mbedtls_md5_init( &operation->ctx.md5 ); ret = mbedtls_md5_starts_ret( &operation->ctx.md5 ); break; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) case PSA_ALG_RIPEMD160: mbedtls_ripemd160_init( &operation->ctx.ripemd160 ); ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 ); break; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) case PSA_ALG_SHA_1: mbedtls_sha1_init( &operation->ctx.sha1 ); ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 ); break; #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) case PSA_ALG_SHA_224: mbedtls_sha256_init( &operation->ctx.sha256 ); ret = mbedtls_sha256_starts_ret( &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_ret( &operation->ctx.sha256, 0 ); break; #endif -#if defined(MBEDTLS_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) case PSA_ALG_SHA_384: mbedtls_sha512_init( &operation->ctx.sha512 ); ret = mbedtls_sha512_starts_ret( &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_ret( &operation->ctx.sha512, 0 ); @@ -2445,53 +2665,62 @@ psa_status_t psa_hash_update( psa_hash_operation_t *operation, switch( operation->alg ) { -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: ret = mbedtls_md2_update_ret( &operation->ctx.md2, input, input_length ); break; #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: ret = mbedtls_md4_update_ret( &operation->ctx.md4, input, input_length ); break; #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) case PSA_ALG_MD5: ret = mbedtls_md5_update_ret( &operation->ctx.md5, input, input_length ); break; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) case PSA_ALG_RIPEMD160: ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160, input, input_length ); break; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) case PSA_ALG_SHA_1: ret = mbedtls_sha1_update_ret( &operation->ctx.sha1, input, input_length ); break; #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) case PSA_ALG_SHA_224: + ret = mbedtls_sha256_update_ret( &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_ret( &operation->ctx.sha256, input, input_length ); break; #endif -#if defined(MBEDTLS_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) case PSA_ALG_SHA_384: + ret = mbedtls_sha512_update_ret( &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_ret( &operation->ctx.sha512, input, input_length ); break; #endif default: + (void)input; return( PSA_ERROR_BAD_STATE ); } @@ -2526,41 +2755,47 @@ psa_status_t psa_hash_finish( psa_hash_operation_t *operation, switch( operation->alg ) { -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash ); break; #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash ); break; #endif -#if defined(MBEDTLS_MD5_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) case PSA_ALG_MD5: ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash ); break; #endif -#if defined(MBEDTLS_RIPEMD160_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) case PSA_ALG_RIPEMD160: ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash ); break; #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) case PSA_ALG_SHA_1: ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash ); break; #endif -#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) case PSA_ALG_SHA_224: + ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash ); + break; +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) case PSA_ALG_SHA_256: ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash ); break; #endif -#if defined(MBEDTLS_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) case PSA_ALG_SHA_384: + ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash ); + break; #endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) case PSA_ALG_SHA_512: ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash ); break; @@ -2663,47 +2898,55 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, { case 0: return( PSA_ERROR_BAD_STATE ); -#if defined(MBEDTLS_MD2_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) case PSA_ALG_MD2: mbedtls_md2_clone( &target_operation->ctx.md2, &source_operation->ctx.md2 ); break; #endif -#if defined(MBEDTLS_MD4_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) case PSA_ALG_MD4: mbedtls_md4_clone( &target_operation->ctx.md4, &source_operation->ctx.md4 ); break; #endif -#if defined(MBEDTLS_MD5_C) +#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_RIPEMD160_C) +#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_SHA1_C) +#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_SHA256_C) +#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_SHA512_C) -#if !defined(MBEDTLS_SHA512_NO_SHA384) +#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 ); @@ -2738,8 +2981,7 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( { switch( alg ) { - case PSA_ALG_ARC4: - case PSA_ALG_CHACHA20: + case PSA_ALG_STREAM_CIPHER: mode = MBEDTLS_MODE_STREAM; break; case PSA_ALG_CTR: @@ -2751,6 +2993,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( case PSA_ALG_OFB: mode = MBEDTLS_MODE_OFB; break; + case PSA_ALG_ECB_NO_PADDING: + mode = MBEDTLS_MODE_ECB; + break; case PSA_ALG_CBC_NO_PADDING: mode = MBEDTLS_MODE_CBC; break; @@ -2812,7 +3057,7 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( (int) key_bits, mode ) ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) static size_t psa_get_hash_block_size( psa_algorithm_t alg ) { switch( alg ) @@ -2839,7 +3084,7 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg ) return( 0 ); } } -#endif /* MBEDTLS_MD_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */ /* Initialize the MAC operation structure. Once this function has been * called, psa_mac_abort can run and will do the right thing. */ @@ -2864,7 +3109,7 @@ static psa_status_t psa_mac_init( psa_mac_operation_t *operation, } else #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#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. */ @@ -2872,7 +3117,7 @@ static psa_status_t psa_mac_init( psa_mac_operation_t *operation, status = PSA_SUCCESS; } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ { if( ! PSA_ALG_IS_MAC( alg ) ) status = PSA_ERROR_INVALID_ARGUMENT; @@ -2883,13 +3128,13 @@ static psa_status_t psa_mac_init( psa_mac_operation_t *operation, return( status ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) { mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); return( psa_hash_abort( &hmac->hash_ctx ) ); } -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) { @@ -2908,13 +3153,13 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) } else #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( operation->alg ) ) { psa_hmac_abort_internal( &operation->ctx.hmac ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ { /* Sanity check (shouldn't happen: operation->alg should * always have been initialized to a valid value). */ @@ -2960,7 +3205,7 @@ static int psa_cmac_setup( psa_mac_operation_t *operation, } #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, const uint8_t *key, size_t key_length, @@ -3022,14 +3267,15 @@ static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, return( status ); } -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, int is_sign ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; size_t key_bits; psa_key_usage_t usage = @@ -3049,7 +3295,8 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, if( is_sign ) operation->is_sign = 1; - status = psa_get_transparent_key( handle, &slot, usage, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; key_bits = psa_get_key_slot_bits( slot ); @@ -3072,7 +3319,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, } else #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( full_length_alg ) ) { psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg ); @@ -3103,7 +3350,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, hash_alg ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ { (void) key_bits; status = PSA_ERROR_NOT_SUPPORTED; @@ -3138,21 +3385,24 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, { operation->key_set = 1; } - return( status ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg ) { - return( psa_mac_setup( operation, handle, alg, 1 ) ); + return( psa_mac_setup( operation, key, alg, 1 ) ); } psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg ) { - return( psa_mac_setup( operation, handle, alg, 0 ) ); + return( psa_mac_setup( operation, key, alg, 0 ) ); } psa_status_t psa_mac_update( psa_mac_operation_t *operation, @@ -3175,14 +3425,14 @@ psa_status_t psa_mac_update( psa_mac_operation_t *operation, } else #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( operation->alg ) ) { status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input, input_length ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ { /* This shouldn't happen if `operation` was initialized by * a setup function. */ @@ -3194,7 +3444,7 @@ psa_status_t psa_mac_update( psa_mac_operation_t *operation, return( status ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, uint8_t *mac, size_t mac_size ) @@ -3232,7 +3482,7 @@ static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, mbedtls_platform_zeroize( tmp, hash_size ); return( status ); } -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation, uint8_t *mac, @@ -3258,14 +3508,14 @@ static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation, } else #endif /* MBEDTLS_CMAC_C */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( operation->alg ) ) { return( psa_hmac_finish_internal( &operation->ctx.hmac, mac, operation->mac_size ) ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ { /* This shouldn't happen if `operation` was initialized by * a setup function. */ @@ -3361,7 +3611,8 @@ psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, /* Asymmetric cryptography */ /****************************************************************/ -#if defined(MBEDTLS_RSA_C) +#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, @@ -3380,7 +3631,7 @@ static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg, return( PSA_ERROR_INVALID_ARGUMENT ); #endif -#if defined(MBEDTLS_PKCS1_V15) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) /* For PKCS#1 v1.5 signature, if using a hash, the hash length * must be correct. */ if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) && @@ -3391,16 +3642,16 @@ static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg, if( mbedtls_md_get_size( md_info ) != hash_length ) return( PSA_ERROR_INVALID_ARGUMENT ); } -#endif /* MBEDTLS_PKCS1_V15 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ -#if defined(MBEDTLS_PKCS1_V21) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) /* PSS requires a hash internally. */ if( PSA_ALG_IS_RSA_PSS( alg ) ) { if( md_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); } -#endif /* MBEDTLS_PKCS1_V21 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ return( PSA_SUCCESS ); } @@ -3424,7 +3675,7 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, if( signature_size < mbedtls_rsa_get_len( rsa ) ) return( PSA_ERROR_BUFFER_TOO_SMALL ); -#if defined(MBEDTLS_PKCS1_V15) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ) { mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15, @@ -3439,8 +3690,8 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, signature ); } else -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) if( PSA_ALG_IS_RSA_PSS( alg ) ) { mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ); @@ -3454,7 +3705,7 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, signature ); } else -#endif /* MBEDTLS_PKCS1_V21 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ { return( PSA_ERROR_INVALID_ARGUMENT ); } @@ -3482,7 +3733,7 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, if( signature_length != mbedtls_rsa_get_len( rsa ) ) return( PSA_ERROR_INVALID_SIGNATURE ); -#if defined(MBEDTLS_PKCS1_V15) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ) { mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15, @@ -3497,8 +3748,8 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, signature ); } else -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) if( PSA_ALG_IS_RSA_PSS( alg ) ) { mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ); @@ -3512,7 +3763,7 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, signature ); } else -#endif /* MBEDTLS_PKCS1_V21 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS */ { return( PSA_ERROR_INVALID_ARGUMENT ); } @@ -3524,9 +3775,11 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, return( PSA_ERROR_INVALID_SIGNATURE ); return( mbedtls_to_psa_error( ret ) ); } -#endif /* MBEDTLS_RSA_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ -#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) /* `ecp` cannot be const because `ecp->grp` needs to be non-const * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det() * (even though these functions don't modify it). */ @@ -3550,7 +3803,7 @@ static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp, goto cleanup; } -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) ) { psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg ); @@ -3563,7 +3816,7 @@ static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp, &global_data.ctr_drbg ) ); } else -#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ { (void) alg; MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d, @@ -3625,9 +3878,10 @@ static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp, mbedtls_mpi_free( &s ); return( mbedtls_to_psa_error( ret ) ); } -#endif /* MBEDTLS_ECDSA_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ -psa_status_t psa_sign_hash( psa_key_handle_t handle, +psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -3635,12 +3889,9 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, size_t signature_size, size_t *signature_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ *signature_length = signature_size; /* Immediately reject a zero-length signature buffer. This guarantees @@ -3650,7 +3901,9 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, if( signature_size == 0 ) return( PSA_ERROR_BUFFER_TOO_SMALL ); - status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN_HASH, alg ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_SIGN_HASH, + alg ); if( status != PSA_SUCCESS ) goto exit; if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) @@ -3659,25 +3912,21 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, goto exit; } -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) ) - { - if( drv->asymmetric == NULL || - drv->asymmetric->p_sign == NULL ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = drv->asymmetric->p_sign( drv_context, - slot->data.se.slot_number, - alg, - hash, hash_length, - signature, signature_size, - signature_length ); - } - else -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -#if defined(MBEDTLS_RSA_C) + /* Try any of the available accelerators first */ + status = psa_driver_wrapper_sign_hash( slot, + alg, + hash, + hash_length, + signature, + signature_size, + signature_length ); + if( status != PSA_ERROR_NOT_SUPPORTED || + psa_key_lifetime_is_external( slot->attr.lifetime ) ) + goto exit; + + /* If the operation was not supported by any accelerator, try fallback. */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { mbedtls_rsa_context *rsa = NULL; @@ -3699,13 +3948,14 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, mbedtls_free( rsa ); } else -#endif /* defined(MBEDTLS_RSA_C) */ -#if defined(MBEDTLS_ECP_C) +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { -#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) if( -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) PSA_ALG_IS_ECDSA( alg ) #else PSA_ALG_IS_RANDOMIZED_ECDSA( alg ) @@ -3728,13 +3978,13 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, mbedtls_free( ecp ); } else -#endif /* defined(MBEDTLS_ECDSA_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ { status = PSA_ERROR_INVALID_ARGUMENT; } } else -#endif /* defined(MBEDTLS_ECP_C) */ { status = PSA_ERROR_NOT_SUPPORTED; } @@ -3751,42 +4001,42 @@ psa_status_t psa_sign_hash( psa_key_handle_t handle, memset( signature, '!', signature_size ); /* If signature_size is 0 then we have nothing to do. We must not call * memset because signature may be NULL in this case. */ - return( status ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } -psa_status_t psa_verify_hash( psa_key_handle_t handle, +psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key, 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; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - const psa_drv_se_t *drv; - psa_drv_se_context_t *drv_context; -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY_HASH, alg ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_VERIFY_HASH, + alg ); if( status != PSA_SUCCESS ) return( status ); -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) ) - { - if( drv->asymmetric == NULL || - drv->asymmetric->p_verify == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - return( drv->asymmetric->p_verify( drv_context, - slot->data.se.slot_number, - alg, - hash, hash_length, - signature, signature_length ) ); - } - else -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -#if defined(MBEDTLS_RSA_C) + /* Try any of the available accelerators first */ + status = psa_driver_wrapper_verify_hash( slot, + alg, + hash, + hash_length, + signature, + signature_length ); + if( status != PSA_ERROR_NOT_SUPPORTED || + psa_key_lifetime_is_external( slot->attr.lifetime ) ) + goto exit; + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_rsa_context *rsa = NULL; @@ -3796,7 +4046,7 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle, slot->data.key.bytes, &rsa ); if( status != PSA_SUCCESS ) - return( status ); + goto exit; status = psa_rsa_verify( rsa, alg, @@ -3804,14 +4054,15 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle, signature, signature_length ); mbedtls_rsa_free( rsa ); mbedtls_free( rsa ); - return( status ); + goto exit; } else -#endif /* defined(MBEDTLS_RSA_C) */ -#if defined(MBEDTLS_ECP_C) +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS) */ if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { -#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) if( PSA_ALG_IS_ECDSA( alg ) ) { mbedtls_ecp_keypair *ecp = NULL; @@ -3820,28 +4071,34 @@ psa_status_t psa_verify_hash( psa_key_handle_t handle, slot->data.key.bytes, &ecp ); if( status != PSA_SUCCESS ) - return( status ); + goto exit; status = psa_ecdsa_verify( ecp, hash, hash_length, signature, signature_length ); mbedtls_ecp_keypair_free( ecp ); mbedtls_free( ecp ); - return( status ); + goto exit; } else -#endif /* defined(MBEDTLS_ECDSA_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ { - return( PSA_ERROR_INVALID_ARGUMENT ); + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; } } else -#endif /* defined(MBEDTLS_ECP_C) */ { - return( PSA_ERROR_NOT_SUPPORTED ); + status = PSA_ERROR_NOT_SUPPORTED; } + +exit: + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg, mbedtls_rsa_context *rsa ) { @@ -3850,9 +4107,9 @@ static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg, mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info ); mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg ); } -#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ -psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, +psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3862,8 +4119,9 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, size_t output_size, size_t *output_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; (void) input; (void) input_length; @@ -3876,14 +4134,19 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) || PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_rsa_context *rsa = NULL; @@ -3899,7 +4162,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, status = PSA_ERROR_BUFFER_TOO_SMALL; goto rsa_exit; } -#if defined(MBEDTLS_PKCS1_V15) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT ) { status = mbedtls_to_psa_error( @@ -3912,8 +4175,8 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, output ) ); } else -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) if( PSA_ALG_IS_RSA_OAEP( alg ) ) { psa_rsa_oaep_set_padding_mode( alg, rsa ); @@ -3928,7 +4191,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, output ) ); } else -#endif /* MBEDTLS_PKCS1_V21 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ { status = PSA_ERROR_INVALID_ARGUMENT; goto rsa_exit; @@ -3939,16 +4202,21 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, mbedtls_rsa_free( rsa ); mbedtls_free( rsa ); - return( status ); } else -#endif /* defined(MBEDTLS_RSA_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ { - return( PSA_ERROR_NOT_SUPPORTED ); + status = PSA_ERROR_NOT_SUPPORTED; } + +exit: + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } -psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, +psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3958,8 +4226,9 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, size_t output_size, size_t *output_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; (void) input; (void) input_length; @@ -3972,13 +4241,18 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } -#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { mbedtls_rsa_context *rsa = NULL; @@ -3987,7 +4261,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, slot->data.key.bytes, &rsa ); if( status != PSA_SUCCESS ) - return( status ); + goto exit; if( input_length != mbedtls_rsa_get_len( rsa ) ) { @@ -3995,7 +4269,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, goto rsa_exit; } -#if defined(MBEDTLS_PKCS1_V15) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT ) { status = mbedtls_to_psa_error( @@ -4009,8 +4283,8 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, output_size ) ); } else -#endif /* MBEDTLS_PKCS1_V15 */ -#if defined(MBEDTLS_PKCS1_V21) +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) if( PSA_ALG_IS_RSA_OAEP( alg ) ) { psa_rsa_oaep_set_padding_mode( alg, rsa ); @@ -4026,7 +4300,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, output_size ) ); } else -#endif /* MBEDTLS_PKCS1_V21 */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP */ { status = PSA_ERROR_INVALID_ARGUMENT; } @@ -4034,13 +4308,18 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, rsa_exit: mbedtls_rsa_free( rsa ); mbedtls_free( rsa ); - return( status ); } else -#endif /* defined(MBEDTLS_RSA_C) */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ { - return( PSA_ERROR_NOT_SUPPORTED ); + status = PSA_ERROR_NOT_SUPPORTED; } + +exit: + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -4049,34 +4328,14 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, /* Symmetric cryptography */ /****************************************************************/ -/* Initialize the cipher operation structure. Once this function has been - * called, psa_cipher_abort can run and will do the right thing. */ -static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation, - psa_algorithm_t alg ) -{ - if( ! PSA_ALG_IS_CIPHER( alg ) ) - { - memset( operation, 0, sizeof( *operation ) ); - return( PSA_ERROR_INVALID_ARGUMENT ); - } - - operation->alg = alg; - operation->key_set = 0; - operation->iv_set = 0; - operation->iv_required = 1; - operation->iv_size = 0; - operation->block_size = 0; - mbedtls_cipher_init( &operation->ctx.cipher ); - return( PSA_SUCCESS ); -} - static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, mbedtls_operation_t cipher_operation ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; int ret = 0; - psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_key_slot_t *slot; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; @@ -4086,19 +4345,63 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, /* A context must be freshly initialized before it can be set up. */ if( operation->alg != 0 ) - { return( PSA_ERROR_BAD_STATE ); - } - status = psa_cipher_init( operation, alg ); - if( status != PSA_SUCCESS ) - return( status ); + /* The requested algorithm must be one that can be processed by cipher. */ + if( ! PSA_ALG_IS_CIPHER( alg ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( handle, &slot, usage, alg); + /* Fetch key material from key storage. */ + status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; - key_bits = psa_get_key_slot_bits( slot ); + /* Initialize the operation struct members, except for alg. The alg member + * is used to indicate to psa_cipher_abort that there are resources to free, + * so we only set it after resources have been allocated/initialized. */ + operation->key_set = 0; + operation->iv_set = 0; + operation->mbedtls_in_use = 0; + operation->iv_size = 0; + operation->block_size = 0; + if( alg == PSA_ALG_ECB_NO_PADDING ) + operation->iv_required = 0; + else + operation->iv_required = 1; + + /* Try doing the operation through a driver before using software fallback. */ + if( cipher_operation == MBEDTLS_ENCRYPT ) + status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver, + slot, + alg ); + else + status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver, + slot, + alg ); + + if( status == PSA_SUCCESS ) + { + /* Once the driver context is initialised, it needs to be freed using + * psa_cipher_abort. Indicate this through setting alg. */ + operation->alg = alg; + } + + if( status != PSA_ERROR_NOT_SUPPORTED || + psa_key_lifetime_is_external( slot->attr.lifetime ) ) + goto exit; + + /* Proceed with initializing an mbed TLS cipher context if no driver is + * available for the given algorithm & key. */ + mbedtls_cipher_init( &operation->ctx.cipher ); + + /* Once the cipher context is initialised, it needs to be freed using + * psa_cipher_abort. Indicate there is something to be freed through setting + * alg, and indicate the operation is being done using mbedtls crypto through + * setting mbedtls_in_use. */ + operation->alg = alg; + operation->mbedtls_in_use = 1; + + key_bits = psa_get_key_slot_bits( slot ); cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL ); if( cipher_info == NULL ) { @@ -4151,39 +4454,49 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, goto exit; #endif //MBEDTLS_CIPHER_MODE_WITH_PADDING - operation->key_set = 1; operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 : PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) ); - if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) + if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 && + alg != PSA_ALG_ECB_NO_PADDING ) { operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ); } #if defined(MBEDTLS_CHACHA20_C) else - if( alg == PSA_ALG_CHACHA20 ) + if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 ) operation->iv_size = 12; #endif + status = PSA_SUCCESS; + exit: - if( status == 0 ) + if( ret != 0 ) status = mbedtls_to_psa_error( ret ); - if( status != 0 ) + if( status == PSA_SUCCESS ) + { + /* Update operation flags for both driver and software implementations */ + operation->key_set = 1; + } + else psa_cipher_abort( operation ); - return( status ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg ) { - return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) ); + return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) ); } psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_algorithm_t alg ) { - return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) ); + return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) ); } psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation, @@ -4197,6 +4510,16 @@ psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation, { return( PSA_ERROR_BAD_STATE ); } + + if( operation->mbedtls_in_use == 0 ) + { + status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver, + iv, + iv_size, + iv_length ); + goto exit; + } + if( iv_size < operation->iv_size ) { status = PSA_ERROR_BUFFER_TOO_SMALL; @@ -4214,7 +4537,9 @@ psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation, status = psa_cipher_set_iv( operation, iv, *iv_length ); exit: - if( status != PSA_SUCCESS ) + if( status == PSA_SUCCESS ) + operation->iv_set = 1; + else psa_cipher_abort( operation ); return( status ); } @@ -4229,6 +4554,15 @@ psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation, { return( PSA_ERROR_BAD_STATE ); } + + if( operation->mbedtls_in_use == 0 ) + { + status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver, + iv, + iv_length ); + goto exit; + } + if( iv_length != operation->iv_size ) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -4244,6 +4578,94 @@ psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation, return( status ); } +/* 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. */ +static psa_status_t psa_cipher_update_ecb_internal( + mbedtls_cipher_context_t *ctx, + 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 block_size = ctx->cipher_info->block_size; + 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_size -= 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_size -= 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 ); +} + psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, const uint8_t *input, size_t input_length, @@ -4251,14 +4673,27 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, size_t output_size, size_t *output_length ) { - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t expected_output_size; - if( operation->alg == 0 ) { return( PSA_ERROR_BAD_STATE ); } + if( operation->iv_required && ! operation->iv_set ) + { + return( PSA_ERROR_BAD_STATE ); + } + + if( operation->mbedtls_in_use == 0 ) + { + status = psa_driver_wrapper_cipher_update( &operation->ctx.driver, + input, + input_length, + output, + output_size, + output_length ); + goto exit; + } if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) ) { @@ -4281,9 +4716,24 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, goto exit; } - ret = mbedtls_cipher_update( &operation->ctx.cipher, input, - input_length, output, output_length ); - status = mbedtls_to_psa_error( ret ); + 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_internal( &operation->ctx.cipher, + input, + input_length, + output, + output_size, + output_length ); + } + else + { + status = mbedtls_to_psa_error( + mbedtls_cipher_update( &operation->ctx.cipher, input, + input_length, output, output_length ) ); + } exit: if( status != PSA_SUCCESS ) psa_cipher_abort( operation ); @@ -4296,10 +4746,8 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, size_t *output_length ) { psa_status_t status = PSA_ERROR_GENERIC_ERROR; - int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; - - if( ! operation->key_set ) + if( operation->alg == 0 ) { return( PSA_ERROR_BAD_STATE ); } @@ -4308,53 +4756,59 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, return( PSA_ERROR_BAD_STATE ); } - if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT && - operation->alg == PSA_ALG_CBC_NO_PADDING && - operation->ctx.cipher.unprocessed_len != 0 ) + if( operation->mbedtls_in_use == 0 ) { - status = PSA_ERROR_INVALID_ARGUMENT; - goto error; + status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver, + output, + output_size, + output_length ); + goto exit; } - cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher, - temp_output_buffer, - output_length ); - if( cipher_ret != 0 ) + if( operation->ctx.cipher.unprocessed_len != 0 ) { - status = mbedtls_to_psa_error( cipher_ret ); - goto error; + 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; - goto error; - } - - mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); - status = psa_cipher_abort( operation ); - - return( status ); - -error: - *output_length = 0; +exit: + if( operation->mbedtls_in_use == 1 ) + mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); - mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); - (void) psa_cipher_abort( operation ); + if( status == PSA_SUCCESS ) + return( psa_cipher_abort( operation ) ); + else + { + *output_length = 0; + (void) psa_cipher_abort( operation ); - return( status ); + return( status ); + } } psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) { if( operation->alg == 0 ) { - /* The object has (apparently) been initialized but it is not + /* The object has (apparently) been initialized but it is not (yet) * in use. It's ok to call abort on such an object, and there's * nothing to do. */ return( PSA_SUCCESS ); @@ -4365,11 +4819,15 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) if( ! PSA_ALG_IS_CIPHER( operation->alg ) ) return( PSA_ERROR_BAD_STATE ); - mbedtls_cipher_free( &operation->ctx.cipher ); + if( operation->mbedtls_in_use == 0 ) + psa_driver_wrapper_cipher_abort( &operation->ctx.driver ); + else + mbedtls_cipher_free( &operation->ctx.cipher ); operation->alg = 0; operation->key_set = 0; operation->iv_set = 0; + operation->mbedtls_in_use = 0; operation->iv_size = 0; operation->block_size = 0; operation->iv_required = 0; @@ -4390,6 +4848,7 @@ typedef struct const mbedtls_cipher_info_t *cipher_info; union { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ #if defined(MBEDTLS_CCM_C) mbedtls_ccm_context ccm; #endif /* MBEDTLS_CCM_C */ @@ -4405,6 +4864,8 @@ typedef struct uint8_t tag_length; } aead_operation_t; +#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0} + static void psa_aead_abort_internal( aead_operation_t *operation ) { switch( operation->core_alg ) @@ -4420,10 +4881,12 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) break; #endif /* MBEDTLS_GCM_C */ } + + psa_unlock_key_slot( operation->slot ); } static psa_status_t psa_aead_setup( aead_operation_t *operation, - psa_key_handle_t handle, + mbedtls_svc_key_id_t key, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -4431,7 +4894,8 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, size_t key_bits; mbedtls_cipher_id_t cipher_id; - status = psa_get_transparent_key( handle, &operation->slot, usage, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &operation->slot, usage, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -4441,7 +4905,10 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits, &cipher_id ); if( operation->cipher_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); + { + status = PSA_ERROR_NOT_SUPPORTED; + goto cleanup; + } switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) ) { @@ -4453,7 +4920,10 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 ) - return( PSA_ERROR_INVALID_ARGUMENT ); + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto cleanup; + } mbedtls_ccm_init( &operation->ctx.ccm ); status = mbedtls_to_psa_error( mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id, @@ -4472,7 +4942,10 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 ) - return( PSA_ERROR_INVALID_ARGUMENT ); + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto cleanup; + } mbedtls_gcm_init( &operation->ctx.gcm ); status = mbedtls_to_psa_error( mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id, @@ -4489,7 +4962,10 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, operation->full_tag_length = 16; /* We only support the default tag length. */ if( alg != PSA_ALG_CHACHA20_POLY1305 ) - return( PSA_ERROR_NOT_SUPPORTED ); + { + status = PSA_ERROR_NOT_SUPPORTED; + goto cleanup; + } mbedtls_chachapoly_init( &operation->ctx.chachapoly ); status = mbedtls_to_psa_error( mbedtls_chachapoly_setkey( &operation->ctx.chachapoly, @@ -4500,7 +4976,8 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, #endif /* MBEDTLS_CHACHAPOLY_C */ default: - return( PSA_ERROR_NOT_SUPPORTED ); + status = PSA_ERROR_NOT_SUPPORTED; + goto cleanup; } if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length ) @@ -4517,7 +4994,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, return( status ); } -psa_status_t psa_aead_encrypt( psa_key_handle_t handle, +psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -4530,12 +5007,12 @@ psa_status_t psa_aead_encrypt( psa_key_handle_t handle, size_t *ciphertext_length ) { psa_status_t status; - aead_operation_t operation; + aead_operation_t operation = AEAD_OPERATION_INIT; uint8_t *tag; *ciphertext_length = 0; - status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -4631,7 +5108,7 @@ static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length, return( PSA_SUCCESS ); } -psa_status_t psa_aead_decrypt( psa_key_handle_t handle, +psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -4644,12 +5121,12 @@ psa_status_t psa_aead_decrypt( psa_key_handle_t handle, size_t *plaintext_length ) { psa_status_t status; - aead_operation_t operation; + aead_operation_t operation = AEAD_OPERATION_INIT; const uint8_t *tag = NULL; *plaintext_length = 0; - status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -4727,6 +5204,12 @@ psa_status_t psa_aead_decrypt( psa_key_handle_t handle, /* Generators */ /****************************************************************/ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) +#define AT_LEAST_ONE_BUILTIN_KDF +#endif + #define HKDF_STATE_INIT 0 /* no input yet */ #define HKDF_STATE_STARTED 1 /* got salt */ #define HKDF_STATE_KEYED 2 /* got key */ @@ -4741,7 +5224,6 @@ static psa_algorithm_t psa_key_derivation_get_kdf_alg( return( operation->alg ); } - psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation ) { psa_status_t status = PSA_SUCCESS; @@ -4753,13 +5235,17 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation * nothing to do. */ } else -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) if( PSA_ALG_IS_HKDF( kdf_alg ) ) { mbedtls_free( operation->ctx.hkdf.info ); status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac ); } - else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) || + else +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) + if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) || /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */ PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { @@ -4783,7 +5269,8 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation * mbedtls_platform_zeroize() in the end of this function. */ } else -#endif /* MBEDTLS_MD_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) */ { status = PSA_ERROR_BAD_STATE; } @@ -4815,7 +5302,7 @@ psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *op return( PSA_SUCCESS ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) /* Read some bytes from an HKDF-based operation. This performs a chunk * of the expand phase of the HKDF algorithm. */ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf, @@ -4884,7 +5371,10 @@ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkd return( PSA_SUCCESS ); } +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( psa_tls12_prf_key_derivation_t *tls12_prf, psa_algorithm_t alg ) @@ -5031,7 +5521,8 @@ static psa_status_t psa_key_derivation_tls12_prf_read( return( PSA_SUCCESS ); } -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || + * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ psa_status_t psa_key_derivation_output_bytes( psa_key_derivation_operation_t *operation, @@ -5067,7 +5558,7 @@ psa_status_t psa_key_derivation_output_bytes( } operation->capacity -= output_length; -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) if( PSA_ALG_IS_HKDF( kdf_alg ) ) { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg ); @@ -5075,15 +5566,19 @@ psa_status_t psa_key_derivation_output_bytes( output, output_length ); } else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) || - PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) + PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf, kdf_alg, output, output_length ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || + * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ { return( PSA_ERROR_BAD_STATE ); } @@ -5148,12 +5643,14 @@ static psa_status_t psa_generate_derived_key_internal( psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, - psa_key_handle_t *handle ) + mbedtls_svc_key_id_t *key ) { psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + *key = MBEDTLS_SVC_KEY_ID_INIT; + /* Reject any attempt to create a zero-length key so that we don't * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ if( psa_get_key_bits( attributes ) == 0 ) @@ -5162,8 +5659,8 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut if( ! operation->can_output_key ) return( PSA_ERROR_NOT_PERMITTED ); - status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, - attributes, handle, &slot, &driver ); + status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes, + &slot, &driver ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if( driver != NULL ) { @@ -5178,12 +5675,10 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut operation ); } if( status == PSA_SUCCESS ) - status = psa_finish_key_creation( slot, driver ); + status = psa_finish_key_creation( slot, driver, key ); if( status != PSA_SUCCESS ) - { psa_fail_key_creation( slot, driver ); - *handle = 0; - } + return( status ); } @@ -5193,19 +5688,36 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut /* Key derivation */ /****************************************************************/ +#ifdef AT_LEAST_ONE_BUILTIN_KDF static psa_status_t psa_key_derivation_setup_kdf( psa_key_derivation_operation_t *operation, psa_algorithm_t kdf_alg ) { + int is_kdf_alg_supported; + /* Make sure that operation->ctx is properly zero-initialised. (Macro * initialisers for this union leave some bytes unspecified.) */ memset( &operation->ctx, 0, sizeof( operation->ctx ) ); /* Make sure that kdf_alg is a supported key derivation algorithm. */ -#if defined(MBEDTLS_MD_C) - if( PSA_ALG_IS_HKDF( kdf_alg ) || - PSA_ALG_IS_TLS12_PRF( kdf_alg ) || - PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) + if( PSA_ALG_IS_HKDF( kdf_alg ) ) + is_kdf_alg_supported = 1; + else +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) + if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ) + is_kdf_alg_supported = 1; + else +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) + if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) + is_kdf_alg_supported = 1; + else +#endif + is_kdf_alg_supported = 0; + + if( is_kdf_alg_supported ) { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg ); size_t hash_size = PSA_HASH_SIZE( hash_alg ); @@ -5220,10 +5732,10 @@ static psa_status_t psa_key_derivation_setup_kdf( operation->capacity = 255 * hash_size; return( PSA_SUCCESS ); } -#endif /* MBEDTLS_MD_C */ - else - return( PSA_ERROR_NOT_SUPPORTED ); + + return( PSA_ERROR_NOT_SUPPORTED ); } +#endif /* AT_LEAST_ONE_BUILTIN_KDF */ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation, psa_algorithm_t alg ) @@ -5235,6 +5747,7 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); +#ifdef AT_LEAST_ONE_BUILTIN_KDF else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) ) { psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ); @@ -5244,6 +5757,7 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation { status = psa_key_derivation_setup_kdf( operation, alg ); } +#endif else return( PSA_ERROR_INVALID_ARGUMENT ); @@ -5252,7 +5766,7 @@ psa_status_t psa_key_derivation_setup( psa_key_derivation_operation_t *operation return( status ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, psa_algorithm_t hash_alg, psa_key_derivation_step_t step, @@ -5317,7 +5831,10 @@ static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, return( PSA_ERROR_INVALID_ARGUMENT ); } } +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf, const uint8_t *data, size_t data_length ) @@ -5358,41 +5875,6 @@ static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf, return( PSA_SUCCESS ); } -static psa_status_t psa_tls12_prf_psk_to_ms_set_key( - psa_tls12_prf_key_derivation_t *prf, - psa_algorithm_t hash_alg, - const uint8_t *data, - size_t data_length ) -{ - psa_status_t status; - uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ]; - uint8_t *cur = pms; - - if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - /* Quoting RFC 4279, Section 2: - * - * The premaster secret is formed as follows: if the PSK is N octets - * long, concatenate a uint16 with the value N, N zero octets, a second - * uint16 with the value N, and the PSK itself. - */ - - *cur++ = ( data_length >> 8 ) & 0xff; - *cur++ = ( data_length >> 0 ) & 0xff; - memset( cur, 0, data_length ); - cur += data_length; - *cur++ = pms[0]; - *cur++ = pms[1]; - memcpy( cur, data, data_length ); - cur += data_length; - - status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms ); - - mbedtls_platform_zeroize( pms, sizeof( pms ) ); - return( status ); -} - static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf, const uint8_t *data, size_t data_length ) @@ -5433,6 +5915,44 @@ static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf, return( PSA_ERROR_INVALID_ARGUMENT ); } } +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || + * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) +static psa_status_t psa_tls12_prf_psk_to_ms_set_key( + psa_tls12_prf_key_derivation_t *prf, + psa_algorithm_t hash_alg, + const uint8_t *data, + size_t data_length ) +{ + psa_status_t status; + uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ]; + uint8_t *cur = pms; + + if( data_length > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + /* Quoting RFC 4279, Section 2: + * + * The premaster secret is formed as follows: if the PSK is N octets + * long, concatenate a uint16 with the value N, N zero octets, a second + * uint16 with the value N, and the PSK itself. + */ + + *cur++ = ( data_length >> 8 ) & 0xff; + *cur++ = ( data_length >> 0 ) & 0xff; + memset( cur, 0, data_length ); + cur += data_length; + *cur++ = pms[0]; + *cur++ = pms[1]; + memcpy( cur, data, data_length ); + cur += data_length; + + status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms ); + + mbedtls_platform_zeroize( pms, sizeof( pms ) ); + return( status ); +} static psa_status_t psa_tls12_prf_psk_to_ms_input( psa_tls12_prf_key_derivation_t *prf, @@ -5449,7 +5969,7 @@ static psa_status_t psa_tls12_prf_psk_to_ms_input( return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) ); } -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ /** Check whether the given key type is acceptable for the given * input step of a key derivation. @@ -5499,27 +6019,33 @@ static psa_status_t psa_key_derivation_input_internal( if( status != PSA_SUCCESS ) goto exit; -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) if( PSA_ALG_IS_HKDF( kdf_alg ) ) { status = psa_hkdf_input( &operation->ctx.hkdf, PSA_ALG_HKDF_GET_HASH( kdf_alg ), step, data, data_length ); } - else if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ) + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) + if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ) { status = psa_tls12_prf_input( &operation->ctx.tls12_prf, PSA_ALG_HKDF_GET_HASH( kdf_alg ), step, data, data_length ); } - else if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) + if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf, PSA_ALG_HKDF_GET_HASH( kdf_alg ), step, data, data_length ); } else -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ { /* This can't happen unless the operation object was not initialized */ return( PSA_ERROR_BAD_STATE ); @@ -5545,14 +6071,14 @@ psa_status_t psa_key_derivation_input_bytes( psa_status_t psa_key_derivation_input_key( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, - psa_key_handle_t handle ) + mbedtls_svc_key_id_t key ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; - status = psa_get_transparent_key( handle, &slot, - PSA_KEY_USAGE_DERIVE, - operation->alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg ); if( status != PSA_SUCCESS ) { psa_key_derivation_abort( operation ); @@ -5564,10 +6090,14 @@ psa_status_t psa_key_derivation_input_key( if( step == PSA_KEY_DERIVATION_INPUT_SECRET ) operation->can_output_key = 1; - return( psa_key_derivation_input_internal( operation, - step, slot->attr.type, - slot->data.key.data, - slot->data.key.bytes ) ); + status = psa_key_derivation_input_internal( operation, + step, slot->attr.type, + slot->data.key.data, + slot->data.key.bytes ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -5576,7 +6106,7 @@ psa_status_t psa_key_derivation_input_key( /* Key agreement */ /****************************************************************/ -#if defined(MBEDTLS_ECDH_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key, size_t peer_key_length, const mbedtls_ecp_keypair *our_key, @@ -5627,7 +6157,7 @@ static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key, return( status ); } -#endif /* MBEDTLS_ECDH_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ #define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES @@ -5641,7 +6171,7 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg, { switch( alg ) { -#if defined(MBEDTLS_ECDH_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) case PSA_ALG_ECDH: if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -5660,7 +6190,7 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg, mbedtls_ecp_keypair_free( ecp ); mbedtls_free( ecp ); return( status ); -#endif /* MBEDTLS_ECDH_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */ default: (void) private_key; (void) peer_key; @@ -5704,7 +6234,6 @@ static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t * PSA_KEY_TYPE_DERIVE, shared_secret, shared_secret_length ); - exit: mbedtls_platform_zeroize( shared_secret, shared_secret_length ); return( status ); @@ -5712,16 +6241,18 @@ static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t * psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, - psa_key_handle_t private_key, + mbedtls_svc_key_id_t private_key, const uint8_t *peer_key, size_t peer_key_length ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_status_t status; + if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( private_key, &slot, - PSA_KEY_USAGE_DERIVE, operation->alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg ); if( status != PSA_SUCCESS ) return( status ); status = psa_key_agreement_internal( operation, step, @@ -5729,27 +6260,38 @@ psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *o peer_key, peer_key_length ); if( status != PSA_SUCCESS ) psa_key_derivation_abort( operation ); - return( status ); + else + { + /* If a private key has been added as SECRET, we allow the derived + * key material to be used as a key in PSA Crypto. */ + if( step == PSA_KEY_DERIVATION_INPUT_SECRET ) + operation->can_output_key = 1; + } + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, - psa_key_handle_t private_key, + mbedtls_svc_key_id_t private_key, const uint8_t *peer_key, size_t peer_key_length, uint8_t *output, size_t output_size, size_t *output_length ) { - psa_key_slot_t *slot; - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot = NULL; if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; } - status = psa_get_transparent_key( private_key, &slot, - PSA_KEY_USAGE_DERIVE, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + private_key, &slot, PSA_KEY_USAGE_DERIVE, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -5771,7 +6313,10 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, psa_generate_random( output, output_size ); *output_length = output_size; } - return( status ); + + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -5818,7 +6363,7 @@ psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed, } #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, size_t domain_parameters_size, int *exponent ) @@ -5844,7 +6389,7 @@ static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, *exponent = acc; return( PSA_SUCCESS ); } -#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ static psa_status_t psa_generate_key_internal( psa_key_slot_t *slot, size_t bits, @@ -5882,7 +6427,7 @@ static psa_status_t psa_generate_key_internal( } else -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { mbedtls_rsa_context rsa; @@ -5930,9 +6475,9 @@ static psa_status_t psa_generate_key_internal( return( status ); } else -#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type ); @@ -5946,8 +6491,6 @@ static psa_status_t psa_generate_key_internal( return( PSA_ERROR_NOT_SUPPORTED ); if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( curve_info->bit_size != bits ) - return( PSA_ERROR_INVALID_ARGUMENT ); mbedtls_ecp_keypair_init( &ecp ); ret = mbedtls_ecp_gen_key( grp_id, &ecp, mbedtls_ctr_drbg_random, @@ -5979,7 +6522,7 @@ static psa_status_t psa_generate_key_internal( return( status ); } else -#endif /* MBEDTLS_ECP_C */ +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ { return( PSA_ERROR_NOT_SUPPORTED ); } @@ -5988,54 +6531,40 @@ static psa_status_t psa_generate_key_internal( } psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, - psa_key_handle_t *handle ) + mbedtls_svc_key_id_t *key ) { psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + *key = MBEDTLS_SVC_KEY_ID_INIT; + /* Reject any attempt to create a zero-length key so that we don't * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ if( psa_get_key_bits( attributes ) == 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, - attributes, handle, &slot, &driver ); + status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes, + &slot, &driver ); if( status != PSA_SUCCESS ) goto exit; -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( driver != NULL ) - { - const psa_drv_se_t *drv = psa_get_se_driver_methods( driver ); - size_t pubkey_length = 0; /* We don't support this feature yet */ - if( drv->key_management == NULL || - drv->key_management->p_generate == NULL ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = drv->key_management->p_generate( - psa_get_se_driver_context( driver ), - slot->data.se.slot_number, attributes, - NULL, 0, &pubkey_length ); - } - else -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - { - status = psa_generate_key_internal( - slot, attributes->core.bits, - attributes->domain_parameters, attributes->domain_parameters_size ); - } + status = psa_driver_wrapper_generate_key( attributes, + slot ); + if( status != PSA_ERROR_NOT_SUPPORTED || + psa_key_lifetime_is_external( attributes->core.lifetime ) ) + goto exit; + + status = psa_generate_key_internal( + slot, attributes->core.bits, + attributes->domain_parameters, attributes->domain_parameters_size ); exit: if( status == PSA_SUCCESS ) - status = psa_finish_key_creation( slot, driver ); + status = psa_finish_key_creation( slot, driver, key ); if( status != PSA_SUCCESS ) - { psa_fail_key_creation( slot, driver ); - *handle = 0; - } + return( status ); } diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_core.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_core.h index 9a61babb505..f61ef9550d4 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_core.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_core.h @@ -36,6 +36,32 @@ typedef struct { psa_core_key_attributes_t attr; + + /* + * Number of locks on the key slot held by the library. + * + * This counter is incremented by one each time a library function + * retrieves through one of the dedicated internal API a pointer to the + * key slot. + * + * This counter is decremented by one each time a library function stops + * accessing the key slot and states it by calling the + * psa_unlock_key_slot() API. + * + * 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 used by the library through + * another thread. + */ + size_t lock_count; + union { /* Dynamically allocated key data buffer. @@ -74,6 +100,19 @@ static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot ) return( slot->attr.type != 0 ); } +/** Test whether a key slot is locked. + * + * A key slot is locked iff its lock counter is strictly greater than 0. + * + * \param[in] slot The key slot to test. + * + * \return 1 if the slot is locked, 0 otherwise. + */ +static inline int psa_is_key_slot_locked( const psa_key_slot_t *slot ) +{ + return( slot->lock_count > 0 ); +} + /** Retrieve flags from psa_key_slot_t::attr::core::flags. * * \param[in] slot The key slot to query. @@ -130,35 +169,43 @@ static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot, * * \param[in,out] slot The key slot to wipe. * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. This includes the case of a key slot that was * already fully wiped. - * \retval PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_CORRUPTION_DETECTED */ psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ); -/** Import key data into a slot. +/** Copy key data (in export format) into an empty key slot. + * + * This function assumes that the slot does not contain + * any key material yet. On failure, the slot content is unchanged. + * + * \param[in,out] slot Key slot to copy the key into. + * \param[in] data Buffer containing the key material. + * \param data_length Size of the key buffer. + * + * \retval #PSA_SUCCESS + * The key has been copied successfully. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * Not enough memory was available for allocation of the + * copy buffer. + * \retval #PSA_ERROR_ALREADY_EXISTS + * There was other key material already present in the slot. + */ +psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot, + const uint8_t *data, + size_t data_length ); + +/** Convert an mbed TLS error code to a PSA error code * - * `slot->type` must have been set previously. - * This function assumes that the slot does not contain any key material yet. - * On failure, the slot content is unchanged. + * \note This function is provided solely for the convenience of + * Mbed TLS and may be removed at any time without notice. * - * Persistent storage is not affected. + * \param ret An mbed TLS-thrown error code * - * \param[in,out] slot The key slot to import data into. - * Its `type` field must have previously been set to - * the desired key type. - * It must not contain any key material yet. - * \param[in] data Buffer containing the key material to parse and import. - * \param data_length Size of \p data in bytes. - * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INVALID_ARGUMENT - * \retval PSA_ERROR_NOT_SUPPORTED - * \retval PSA_ERROR_INSUFFICIENT_MEMORY + * \return The corresponding PSA error code */ -psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, - const uint8_t *data, - size_t data_length ); +psa_status_t mbedtls_to_psa_error( int ret ); #endif /* PSA_CRYPTO_CORE_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.c new file mode 100644 index 00000000000..c3ea6f14238 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.c @@ -0,0 +1,993 @@ +/* + * Functions to delegate cryptographic operations to an available + * and appropriate accelerator. + * Warning: This file will be auto-generated in the future. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "psa_crypto_core.h" +#include "psa_crypto_driver_wrappers.h" +#include "mbedtls/platform.h" + +#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) + +/* Include test driver definition when running tests */ +#if defined(PSA_CRYPTO_DRIVER_TEST) +#ifndef PSA_CRYPTO_DRIVER_PRESENT +#define PSA_CRYPTO_DRIVER_PRESENT +#endif +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif +#include "test/drivers/test_driver.h" +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +/* Repeat above block for each JSON-declared driver during autogeneration */ + +/* Auto-generated values depending on which drivers are registered. ID 0 is + * reserved for unallocated operations. */ +#if defined(PSA_CRYPTO_DRIVER_TEST) +#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (1) +#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (2) +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */ + +/* 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 + +/* Start delegation functions */ +psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) + /* 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( slot->attr.lifetime, &drv, &drv_context ) ) + { + if( drv->asymmetric == NULL || + drv->asymmetric->p_sign == NULL ) + { + /* Key is defined in SE, but we have no way to exercise it */ + return( PSA_ERROR_NOT_SUPPORTED ); + } + return( drv->asymmetric->p_sign( drv_context, + slot->data.se.slot_number, + alg, + hash, hash_length, + signature, signature_size, + signature_length ) ); + } +#endif /* PSA_CRYPTO_SE_C */ + + /* Then try accelerator API */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + status = test_transparent_signature_sign_hash( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + hash, + hash_length, + signature, + signature_size, + signature_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + return( test_opaque_signature_sign_hash( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + hash, + hash_length, + signature, + signature_size, + signature_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( status ); + } +#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)slot; + (void)alg; + (void)hash; + (void)hash_length; + (void)signature; + (void)signature_size; + (void)signature_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + const uint8_t *signature, + size_t signature_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) + /* 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( slot->attr.lifetime, &drv, &drv_context ) ) + { + if( drv->asymmetric == NULL || + drv->asymmetric->p_verify == NULL ) + { + /* Key is defined in SE, but we have no way to exercise it */ + return( PSA_ERROR_NOT_SUPPORTED ); + } + return( drv->asymmetric->p_verify( drv_context, + slot->data.se.slot_number, + alg, + hash, hash_length, + signature, signature_length ) ); + } +#endif /* PSA_CRYPTO_SE_C */ + + /* Then try accelerator API */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + status = test_transparent_signature_verify_hash( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + hash, + hash_length, + signature, + signature_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + return( test_opaque_signature_verify_hash( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + hash, + hash_length, + signature, + signature_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( status ); + } +#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)slot; + (void)alg; + (void)hash; + (void)hash_length; + (void)signature; + (void)signature_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +/** Calculate the size to allocate for buffering a key with given attributes. + * + * This function provides a way to get the expected size for storing a key with + * the given attributes. This will be the size of the export representation for + * cleartext keys, and a driver-defined size for keys stored by opaque drivers. + * + * \param[in] attributes The key attribute structure of the key to store. + * \param[out] expected_size On success, a byte size large enough to contain + * the declared key. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED + */ +static psa_status_t get_expected_key_size( const psa_key_attributes_t *attributes, + size_t *expected_size ) +{ + size_t buffer_size = 0; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + psa_key_type_t key_type = attributes->core.type; + size_t key_bits = attributes->core.bits; + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + buffer_size = PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ); + + if( buffer_size == 0 ) + return( PSA_ERROR_NOT_SUPPORTED ); + + *expected_size = buffer_size; + return( PSA_SUCCESS ); + +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: +#ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION + *expected_size = test_size_function( key_type, key_bits ); + return( PSA_SUCCESS ); +#else /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */ + if( PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) ) + { + int public_key_overhead = ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ? + PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) : 0 ); + *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE + + public_key_overhead; + } + else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( attributes->core.type ) ) + { + *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE; + } + else if ( !PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) && + !PSA_KEY_TYPE_IS_PUBLIC_KEY ( attributes->core.type ) ) + { + *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + + TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR + * ( ( key_bits + 7 ) / 8 ); + } + else + { + return( PSA_ERROR_NOT_SUPPORTED ); + } + return( PSA_SUCCESS ); +#endif /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */ +#endif /* PSA_CRYPTO_DRIVER_TEST */ + + default: + return( PSA_ERROR_NOT_SUPPORTED ); + } +} +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + +psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, + psa_key_slot_t *slot ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) + /* 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( slot->attr.lifetime, &drv, &drv_context ) ) + { + size_t pubkey_length = 0; /* We don't support this feature yet */ + if( drv->key_management == NULL || + drv->key_management->p_generate == NULL ) + { + /* Key is defined as being in SE, but we have no way to generate it */ + return( PSA_ERROR_NOT_SUPPORTED ); + } + return( drv->key_management->p_generate( + drv_context, + slot->data.se.slot_number, attributes, + NULL, 0, &pubkey_length ) ); + } +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + + /* Then try accelerator API */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + size_t export_size = 0; + + status = get_expected_key_size( attributes, &export_size ); + if( status != PSA_SUCCESS ) + return( status ); + + slot->data.key.data = mbedtls_calloc(1, export_size); + if( slot->data.key.data == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + slot->data.key.bytes = export_size; + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + + /* Transparent drivers are limited to generating asymmetric keys */ + if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) ) + { + status = PSA_ERROR_NOT_SUPPORTED; + break; + } +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = test_transparent_generate_key( attributes, + slot->data.key.data, + slot->data.key.bytes, + &slot->data.key.bytes ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + break; +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + status = PSA_ERROR_NOT_SUPPORTED; + break; + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + status = test_opaque_generate_key( attributes, + slot->data.key.data, + slot->data.key.bytes, + &slot->data.key.bytes ); + break; +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + status = PSA_ERROR_INVALID_ARGUMENT; + break; + } + + if( status != PSA_SUCCESS ) + { + /* free allocated buffer */ + mbedtls_free( slot->data.key.data ); + slot->data.key.data = NULL; + slot->data.key.bytes = 0; + } + + return( status ); +#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) attributes; + (void) slot; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_validate_key( const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + size_t *bits ) +{ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + /* Try accelerators in turn */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = test_transparent_validate_key( attributes, + data, + data_length, + bits ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + + return( PSA_ERROR_NOT_SUPPORTED ); +#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + (void) attributes; + (void) data; + (void) data_length; + (void) bits; + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_export_public_key( const psa_key_slot_t *slot, + uint8_t *data, + size_t data_size, + size_t *data_length ) +{ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + status = test_transparent_export_public_key( &attributes, + slot->data.key.data, + slot->data.key.bytes, + data, + data_size, + data_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + return( test_opaque_export_public_key( &attributes, + slot->data.key.data, + slot->data.key.bytes, + data, + data_size, + data_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( status ); + } +#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + (void) slot; + (void) data; + (void) data_size; + (void) data_length; + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +} + +/* + * Cipher functions + */ +psa_status_t psa_driver_wrapper_cipher_encrypt( + psa_key_slot_t *slot, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + status = test_transparent_cipher_encrypt( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + input, + input_length, + output, + output_size, + output_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + return( test_opaque_cipher_encrypt( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + input, + input_length, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( status ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) slot; + (void) alg; + (void) input; + (void) input_length; + (void) output; + (void) output_size; + (void) output_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_decrypt( + psa_key_slot_t *slot, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + status = test_transparent_cipher_decrypt( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + input, + input_length, + output, + output_size, + output_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + return( test_opaque_cipher_decrypt( &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg, + input, + input_length, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( status ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) slot; + (void) alg; + (void) input; + (void) input_length; + (void) output; + (void) output_size; + (void) output_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_encrypt_setup( + psa_operation_driver_context_t *operation, + psa_key_slot_t *slot, + psa_algorithm_t alg ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + operation->ctx = mbedtls_calloc( 1, sizeof(test_transparent_cipher_operation_t) ); + if( operation->ctx == NULL ) + return PSA_ERROR_INSUFFICIENT_MEMORY; + + status = test_transparent_cipher_encrypt_setup( operation->ctx, + &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg ); + /* Declared with fallback == true */ + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; + else + { + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_transparent_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + } + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + operation->ctx = mbedtls_calloc( 1, sizeof(test_opaque_cipher_operation_t) ); + if( operation->ctx == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + + status = test_opaque_cipher_encrypt_setup( operation->ctx, + &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; + else + { + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_opaque_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + } + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( PSA_ERROR_NOT_SUPPORTED ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)slot; + (void)alg; + (void)operation; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_decrypt_setup( + psa_operation_driver_context_t *operation, + psa_key_slot_t *slot, + psa_algorithm_t alg ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + 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_DRIVER_TEST) + operation->ctx = mbedtls_calloc( 1, sizeof(test_transparent_cipher_operation_t) ); + if( operation->ctx == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + + status = test_transparent_cipher_decrypt_setup( operation->ctx, + &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg ); + /* Declared with fallback == true */ + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; + else + { + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_transparent_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + } + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + /* Fell through, meaning no accelerator supports this operation */ + return( PSA_ERROR_NOT_SUPPORTED ); + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + operation->ctx = mbedtls_calloc( 1, sizeof(test_opaque_cipher_operation_t) ); + if( operation->ctx == NULL ) + return PSA_ERROR_INSUFFICIENT_MEMORY; + + status = test_opaque_cipher_decrypt_setup( operation->ctx, + &attributes, + slot->data.key.data, + slot->data.key.bytes, + alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; + else + { + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_opaque_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + } + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is declared with a lifetime not known to us */ + return( PSA_ERROR_NOT_SUPPORTED ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)slot; + (void)alg; + (void)operation; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_generate_iv( + psa_operation_driver_context_t *operation, + uint8_t *iv, + size_t iv_size, + size_t *iv_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + switch( operation->id ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_generate_iv( operation->ctx, + iv, + iv_size, + iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_generate_iv( operation->ctx, + iv, + iv_size, + iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is attached to a driver not known to us */ + return( PSA_ERROR_BAD_STATE ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) operation; + (void) iv; + (void) iv_size; + (void) iv_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_set_iv( + psa_operation_driver_context_t *operation, + const uint8_t *iv, + size_t iv_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + switch( operation->id ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_set_iv( operation->ctx, + iv, + iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_set_iv( operation->ctx, + iv, + iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is attached to a driver not known to us */ + return( PSA_ERROR_BAD_STATE ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) operation; + (void) iv; + (void) iv_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_update( + psa_operation_driver_context_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + switch( operation->id ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_update( operation->ctx, + input, + input_length, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_update( operation->ctx, + input, + input_length, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is attached to a driver not known to us */ + return( PSA_ERROR_BAD_STATE ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) operation; + (void) input; + (void) input_length; + (void) output; + (void) output_length; + (void) output_size; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_finish( + psa_operation_driver_context_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + switch( operation->id ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_finish( operation->ctx, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_finish( operation->ctx, + output, + output_size, + output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Key is attached to a driver not known to us */ + return( PSA_ERROR_BAD_STATE ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void) operation; + (void) output; + (void) output_size; + (void) output_length; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +psa_status_t psa_driver_wrapper_cipher_abort( + psa_operation_driver_context_t *operation ) +{ +#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; + + /* 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. */ + if( operation->ctx == NULL && operation->id == 0 ) + return( PSA_SUCCESS ); + + switch( operation->id ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + status = test_transparent_cipher_abort( operation->ctx ); + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_transparent_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + operation->id = 0; + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + status = test_opaque_cipher_abort( operation->ctx ); + mbedtls_platform_zeroize( + operation->ctx, + sizeof( test_opaque_cipher_operation_t ) ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + operation->id = 0; + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + /* Operation is attached to a driver not known to us */ + return( PSA_ERROR_BAD_STATE ); + } +#else /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)operation; + + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +} + +/* End of automatically generated file. */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.h new file mode 100644 index 00000000000..6b5143781bc --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_driver_wrappers.h @@ -0,0 +1,124 @@ +/* + * Function signatures for functionality that can be provided by + * cryptographic accelerators. + * Warning: This file will be auto-generated in the future. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_DRIVER_WRAPPERS_H +#define PSA_CRYPTO_DRIVER_WRAPPERS_H + +#include "psa/crypto.h" +#include "psa/crypto_driver_common.h" + +/* + * Signature functions + */ +psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot, + 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 psa_driver_wrapper_verify_hash( psa_key_slot_t *slot, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + const uint8_t *signature, + size_t signature_length ); + +/* + * Key handling functions + */ + +psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, + psa_key_slot_t *slot ); + +psa_status_t psa_driver_wrapper_validate_key( const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + size_t *bits ); + +psa_status_t psa_driver_wrapper_export_public_key( const psa_key_slot_t *slot, + uint8_t *data, + size_t data_size, + size_t *data_length ); + +/* + * Cipher functions + */ +psa_status_t psa_driver_wrapper_cipher_encrypt( + psa_key_slot_t *slot, + 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 psa_driver_wrapper_cipher_decrypt( + psa_key_slot_t *slot, + 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 psa_driver_wrapper_cipher_encrypt_setup( + psa_operation_driver_context_t *operation, + psa_key_slot_t *slot, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_cipher_decrypt_setup( + psa_operation_driver_context_t *operation, + psa_key_slot_t *slot, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_cipher_generate_iv( + psa_operation_driver_context_t *operation, + uint8_t *iv, + size_t iv_size, + size_t *iv_length ); + +psa_status_t psa_driver_wrapper_cipher_set_iv( + psa_operation_driver_context_t *operation, + const uint8_t *iv, + size_t iv_length ); + +psa_status_t psa_driver_wrapper_cipher_update( + psa_operation_driver_context_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ); + +psa_status_t psa_driver_wrapper_cipher_finish( + psa_operation_driver_context_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length ); + +psa_status_t psa_driver_wrapper_cipher_abort( + psa_operation_driver_context_t *operation ); + +#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ + +/* End of automatically generated file. */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_invasive.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_invasive.h index c609c777ed6..2b4ee1f348c 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_invasive.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_invasive.h @@ -62,12 +62,12 @@ * It is called by mbedtls_psa_crypto_free(). * By default this is mbedtls_entropy_free(). * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. - * \retval PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_NOT_PERMITTED * The caller does not have the permission to configure * entropy sources. - * \retval PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_BAD_STATE * The library has already been initialized. */ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_its.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_its.h index 93c4ce981c5..11703a08f10 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_its.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_its.h @@ -72,12 +72,12 @@ struct psa_storage_info_t * * \return A status indicating the success/failure of the operation * - * \retval PSA_SUCCESS The operation completed successfully - * \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_WRITE_ONCE_FLAG - * \retval PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid - * \retval PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium - * \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - * \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`) + * \retval #PSA_SUCCESS The operation completed successfully + * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_WRITE_ONCE_FLAG + * \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium + * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) + * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`) * is invalid, for example is `NULL` or references memory the caller cannot access */ psa_status_t psa_its_set(psa_storage_uid_t uid, @@ -97,11 +97,11 @@ psa_status_t psa_its_set(psa_storage_uid_t uid, * * \return A status indicating the success/failure of the operation * - * \retval PSA_SUCCESS The operation completed successfully - * \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage - * \retval PSA_ERROR_INVALID_SIZE The operation failed because the data associated with provided uid is larger than `data_size` - * \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - * \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`) + * \retval #PSA_SUCCESS The operation completed successfully + * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage + * \retval #PSA_ERROR_INVALID_SIZE The operation failed because the data associated with provided uid is larger than `data_size` + * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) + * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`) * is invalid. For example is `NULL` or references memory the caller cannot access. * In addition, this can also happen if an invalid offset was provided. */ @@ -119,10 +119,10 @@ psa_status_t psa_its_get(psa_storage_uid_t uid, * * \return A status indicating the success/failure of the operation * - * \retval PSA_SUCCESS The operation completed successfully - * \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage - * \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) - * \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`) + * \retval #PSA_SUCCESS The operation completed successfully + * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage + * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) + * \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`) * is invalid, for example is `NULL` or references memory the caller cannot access */ psa_status_t psa_its_get_info(psa_storage_uid_t uid, @@ -135,11 +135,15 @@ psa_status_t psa_its_get_info(psa_storage_uid_t uid, * * \return A status indicating the success/failure of the operation * - * \retval PSA_SUCCESS The operation completed successfully - * \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage - * \retval PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_WRITE_ONCE_FLAG - * \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) + * \retval #PSA_SUCCESS The operation completed successfully + * \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage + * \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_WRITE_ONCE_FLAG + * \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error) */ psa_status_t psa_its_remove(psa_storage_uid_t uid); +#ifdef __cplusplus +} +#endif + #endif /* PSA_CRYPTO_ITS_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_se.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_se.h index a464232563f..67fadf8965f 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_se.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_se.h @@ -45,7 +45,7 @@ /** The base of the range of ITS file identifiers for secure element * driver persistent data. * - * We use a slice of the implemenation reserved range 0xffff0000..0xffffffff, + * We use a slice of the implementation reserved range 0xffff0000..0xffffffff, * specifically the range 0xfffffe00..0xfffffeff. The length of this range * drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is * actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE @@ -182,7 +182,6 @@ psa_status_t psa_destroy_se_persistent_data( psa_key_location_t location ); typedef struct { uint8_t slot_number[sizeof( psa_key_slot_number_t )]; - uint8_t bits[sizeof( psa_key_bits_t )]; } psa_se_key_data_storage_t; #endif /* PSA_CRYPTO_SE_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.c index a32a0279802..4c4ad0331a7 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.c @@ -51,30 +51,101 @@ typedef struct static psa_global_data_t global_data; -/* Access a key slot at the given handle. The handle of a key slot is - * the index of the slot in the global slot array, plus one so that handles - * start at 1 and not 0. */ -psa_status_t psa_get_key_slot( psa_key_handle_t handle, - psa_key_slot_t **p_slot ) +psa_status_t psa_validate_key_id( + mbedtls_svc_key_id_t key, int vendor_ok ) { + psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ); + + if( ( PSA_KEY_ID_USER_MIN <= key_id ) && + ( key_id <= PSA_KEY_ID_USER_MAX ) ) + return( PSA_SUCCESS ); + + if( vendor_ok && + ( PSA_KEY_ID_VENDOR_MIN <= key_id ) && + ( key_id <= PSA_KEY_ID_VENDOR_MAX ) ) + return( PSA_SUCCESS ); + + return( PSA_ERROR_INVALID_HANDLE ); +} + +/** Get the description in memory of a key given its identifier and lock it. + * + * The descriptions of volatile keys and loaded persistent keys are + * stored in key slots. This function returns a pointer to the key slot + * containing the description of a key given its identifier. + * + * The function searches the key slots containing the description of the key + * with \p key identifier. The function does only read accesses to the key + * slots. The function does not load any persistent key thus does not access + * any storage. + * + * For volatile key identifiers, only one key slot is queried as a volatile + * key with identifier key_id can only be stored in slot of index + * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ). + * + * On success, the function locks the key slot. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. + * + * \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 + * identified by \p key. + * + * \retval #PSA_SUCCESS + * The pointer to the key slot containing the description of the key + * identified by \p key was returned. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p key is not a valid key identifier. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * There is no key with key identifier \p key in the key slots. + */ +static psa_status_t psa_get_and_lock_key_slot_in_memory( + mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key ); + size_t slot_idx; psa_key_slot_t *slot = NULL; - if( ! global_data.key_slots_initialized ) - return( PSA_ERROR_BAD_STATE ); + if( psa_key_id_is_volatile( key_id ) ) + { + slot = &global_data.key_slots[ key_id - PSA_KEY_ID_VOLATILE_MIN ]; + + /* + * Check if both the PSA key identifier key_id and the owner + * identifier of key match those of the key slot. + * + * Note that, if the key slot is not occupied, its PSA key identifier + * is equal to zero. This is an invalid value for a PSA key identifier + * and thus cannot be equal to the valid PSA key identifier key_id. + */ + status = mbedtls_svc_key_id_equal( key, slot->attr.id ) ? + PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST; + } + else + { + status = psa_validate_key_id( key, 1 ); + if( status != PSA_SUCCESS ) + return( status ); - /* 0 is not a valid handle under any circumstance. This - * implementation provides slots number 1 to N where N is the - * number of available slots. */ - if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) ) - return( PSA_ERROR_INVALID_HANDLE ); - slot = &global_data.key_slots[handle - 1]; + for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) + { + slot = &global_data.key_slots[ slot_idx ]; + if( mbedtls_svc_key_id_equal( key, slot->attr.id ) ) + break; + } + status = ( slot_idx < PSA_KEY_SLOT_COUNT ) ? + PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST; + } - /* If the slot isn't occupied, the handle is invalid. */ - if( ! psa_is_key_slot_occupied( slot ) ) - return( PSA_ERROR_INVALID_HANDLE ); + if( status == PSA_SUCCESS ) + { + status = psa_lock_key_slot( slot ); + if( status == PSA_SUCCESS ) + *p_slot = slot; + } - *p_slot = slot; - return( PSA_SUCCESS ); + return( status ); } psa_status_t psa_initialize_key_slots( void ) @@ -88,29 +159,80 @@ psa_status_t psa_initialize_key_slots( void ) void psa_wipe_all_key_slots( void ) { - psa_key_handle_t key; - for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) + size_t slot_idx; + + for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { - psa_key_slot_t *slot = &global_data.key_slots[key - 1]; + psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; + slot->lock_count = 1; (void) psa_wipe_key_slot( slot ); } global_data.key_slots_initialized = 0; } -psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle, - psa_key_slot_t **p_slot ) +psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, + psa_key_slot_t **p_slot ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t slot_idx; + psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot; + if( ! global_data.key_slots_initialized ) - return( PSA_ERROR_BAD_STATE ); + { + status = PSA_ERROR_BAD_STATE; + goto error; + } - for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) + selected_slot = unlocked_persistent_key_slot = NULL; + for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { - *p_slot = &global_data.key_slots[*handle - 1]; - if( ! psa_is_key_slot_occupied( *p_slot ) ) - return( PSA_SUCCESS ); + psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; + if( ! psa_is_key_slot_occupied( slot ) ) + { + selected_slot = slot; + break; + } + + if( ( unlocked_persistent_key_slot == NULL ) && + ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) && + ( ! psa_is_key_slot_locked( slot ) ) ) + unlocked_persistent_key_slot = slot; + } + + /* + * If there is no unused key slot and there is at least one unlocked key + * slot containing the description of a persistent key, recycle the first + * such key slot we encountered. If we later need to operate on the + * persistent key we are evicting now, we will reload its description from + * storage. + */ + if( ( selected_slot == NULL ) && + ( unlocked_persistent_key_slot != NULL ) ) + { + selected_slot = unlocked_persistent_key_slot; + selected_slot->lock_count = 1; + psa_wipe_key_slot( selected_slot ); } + + if( selected_slot != NULL ) + { + status = psa_lock_key_slot( selected_slot ); + if( status != PSA_SUCCESS ) + goto error; + + *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + + ( (psa_key_id_t)( selected_slot - global_data.key_slots ) ); + *p_slot = selected_slot; + + return( PSA_SUCCESS ); + } + status = PSA_ERROR_INSUFFICIENT_MEMORY; + +error: *p_slot = NULL; - return( PSA_ERROR_INSUFFICIENT_MEMORY ); + *volatile_key_id = 0; + + return( status ); } #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) @@ -137,47 +259,84 @@ static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot ) data = (psa_se_key_data_storage_t *) key_data; memcpy( &slot->data.se.slot_number, &data->slot_number, sizeof( slot->data.se.slot_number ) ); - memcpy( &slot->attr.bits, &data->bits, - sizeof( slot->attr.bits ) ); } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ { - status = psa_import_key_into_slot( slot, key_data, key_data_length ); + status = psa_copy_key_material_into_slot( slot, key_data, key_data_length ); + if( status != PSA_SUCCESS ) + goto exit; } exit: psa_free_persistent_key_data( key_data, key_data_length ); return( status ); } +#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -/** Check whether a key identifier is acceptable. - * - * For backward compatibility, key identifiers that were valid in a - * past released version must remain valid, unless a migration path - * is provided. - * - * \param file_id The key identifier to check. - * \param vendor_ok Nonzero to allow key ids in the vendor range. - * 0 to allow only key ids in the application range. - * - * \return 1 if \p file_id is acceptable, otherwise 0. - */ -static int psa_is_key_id_valid( psa_key_file_id_t file_id, - int vendor_ok ) +psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot ) { - psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id ); - if( PSA_KEY_ID_USER_MIN <= key_id && key_id <= PSA_KEY_ID_USER_MAX ) - return( 1 ); - else if( vendor_ok && - PSA_KEY_ID_VENDOR_MIN <= key_id && - key_id <= PSA_KEY_ID_VENDOR_MAX ) - return( 1 ); - else - return( 0 ); -} + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + *p_slot = NULL; + if( ! global_data.key_slots_initialized ) + return( PSA_ERROR_BAD_STATE ); + + /* + * On success, the pointer to the slot is passed directly to the caller + * thus no need to unlock the key slot here. + */ + status = psa_get_and_lock_key_slot_in_memory( key, p_slot ); + if( status != PSA_ERROR_DOES_NOT_EXIST ) + return( status ); + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + psa_key_id_t volatile_key_id; + + status = psa_get_empty_key_slot( &volatile_key_id, p_slot ); + if( status != PSA_SUCCESS ) + return( status ); + + (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; + (*p_slot)->attr.id = key; + + status = psa_load_persistent_key_into_slot( *p_slot ); + if( status != PSA_SUCCESS ) + psa_wipe_key_slot( *p_slot ); + + return( status ); +#else + return( PSA_ERROR_DOES_NOT_EXIST ); #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ +} + +psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot ) +{ + if( slot == NULL ) + return( PSA_SUCCESS ); + + if( slot->lock_count > 0 ) + { + slot->lock_count--; + return( PSA_SUCCESS ); + } + + /* + * As the return error code may not be handled in case of multiple errors, + * do our best to report if the lock counter is equal to zero: if + * available call MBEDTLS_PARAM_FAILED that may terminate execution (if + * called as part of the execution of a unit test suite this will stop the + * test suite execution). + */ +#ifdef MBEDTLS_CHECK_PARAMS + MBEDTLS_PARAM_FAILED( slot->lock_count > 0 ); +#endif + + return( PSA_ERROR_CORRUPTION_DETECTED ); +} + psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime, psa_se_drv_table_entry_t **p_drv ) { @@ -203,8 +362,7 @@ psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime, return( PSA_SUCCESS ); } -psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime, - psa_key_id_t key_id ) +psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime ) { if ( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) { @@ -215,47 +373,33 @@ psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime, { /* Persistent keys require storage support */ #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( psa_is_key_id_valid( key_id, - psa_key_lifetime_is_external( lifetime ) ) ) - return( PSA_SUCCESS ); - else - return( PSA_ERROR_INVALID_ARGUMENT ); + return( PSA_SUCCESS ); #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ - (void) key_id; return( PSA_ERROR_NOT_SUPPORTED ); #endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */ } } -psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle ) +psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle ) { #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) psa_status_t status; psa_key_slot_t *slot; - *handle = 0; - - if( ! psa_is_key_id_valid( id, 1 ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - status = psa_get_empty_key_slot( handle, &slot ); + status = psa_get_and_lock_key_slot( key, &slot ); if( status != PSA_SUCCESS ) + { + *handle = PSA_KEY_HANDLE_INIT; return( status ); + } - slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; - slot->attr.id = id; + *handle = key; - status = psa_load_persistent_key_into_slot( slot ); - if( status != PSA_SUCCESS ) - { - psa_wipe_key_slot( slot ); - *handle = 0; - } - return( status ); + return( psa_unlock_key_slot( slot ) ); #else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - (void) id; - *handle = 0; + (void) key; + *handle = PSA_KEY_HANDLE_INIT; return( PSA_ERROR_NOT_SUPPORTED ); #endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ } @@ -265,23 +409,48 @@ psa_status_t psa_close_key( psa_key_handle_t handle ) psa_status_t status; psa_key_slot_t *slot; - if( handle == 0 ) + if( psa_key_handle_is_null( handle ) ) return( PSA_SUCCESS ); - status = psa_get_key_slot( handle, &slot ); + status = psa_get_and_lock_key_slot_in_memory( handle, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + if( slot->lock_count <= 1 ) + return( psa_wipe_key_slot( slot ) ); + else + return( psa_unlock_key_slot( slot ) ); +} + +psa_status_t psa_purge_key( mbedtls_svc_key_id_t key ) +{ + psa_status_t status; + psa_key_slot_t *slot; + + status = psa_get_and_lock_key_slot_in_memory( key, &slot ); if( status != PSA_SUCCESS ) return( status ); - return( psa_wipe_key_slot( slot ) ); + if( ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) && + ( slot->lock_count <= 1 ) ) + return( psa_wipe_key_slot( slot ) ); + else + return( psa_unlock_key_slot( slot ) ); } void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) { - psa_key_handle_t key; + size_t slot_idx; + memset( stats, 0, sizeof( *stats ) ); - for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) + + for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { - const psa_key_slot_t *slot = &global_data.key_slots[key - 1]; + const psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; + if( psa_is_key_slot_locked( slot ) ) + { + ++stats->locked_slots; + } if( ! psa_is_key_slot_occupied( slot ) ) { ++stats->empty_slots; @@ -291,14 +460,14 @@ void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) ++stats->volatile_slots; else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { - psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id); + psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id ); ++stats->persistent_slots; if( id > stats->max_open_internal_key_id ) stats->max_open_internal_key_id = id; } else { - psa_app_key_id_t id = PSA_KEY_FILE_GET_KEY_ID(slot->attr.id); + psa_key_id_t id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id ); ++stats->external_slots; if( id > stats->max_open_external_key_id ) stats->max_open_external_key_id = id; diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.h index 676a77e5a08..ef0814ac9e0 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_slot_management.h @@ -22,32 +22,86 @@ #define PSA_CRYPTO_SLOT_MANAGEMENT_H #include "psa/crypto.h" +#include "psa_crypto_core.h" #include "psa_crypto_se.h" /* Number of key slots (plus one because 0 is not used). * The value is a compile-time constant for now, for simplicity. */ #define PSA_KEY_SLOT_COUNT 32 -/** Access a key slot at the given handle. +/** Range of volatile key identifiers. * - * \param handle Key handle to query. + * The last 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. + */ + +/** The minimum value for a volatile key identifier. + */ +#define PSA_KEY_ID_VOLATILE_MIN ( PSA_KEY_ID_VENDOR_MAX - \ + PSA_KEY_SLOT_COUNT + 1 ) + +/** The maximum value for a volatile key identifier. + */ +#define PSA_KEY_ID_VOLATILE_MAX PSA_KEY_ID_VENDOR_MAX + +/** Test whether a key identifier is a volatile key identifier. + * + * \param key_id Key identifier to test. + * + * \retval 1 + * The key identifier is a volatile key identifier. + * \retval 0 + * The key identifier is not a volatile key identifier. + */ +static inline int psa_key_id_is_volatile( psa_key_id_t key_id ) +{ + return( ( key_id >= PSA_KEY_ID_VOLATILE_MIN ) && + ( key_id <= PSA_KEY_ID_VOLATILE_MAX ) ); +} + +/** Get the description of a key given its identifier and lock it. + * + * The descriptions of volatile keys and loaded persistent keys are stored in + * key slots. This function returns a pointer to the key slot containing the + * description of a key given its identifier. + * + * In case of a persistent key, the function loads the description of the key + * into a key slot if not already done. + * + * On success, the returned key slot is locked. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. + * + * \param key Key identifier to query. * \param[out] p_slot On success, `*p_slot` contains a pointer to the - * key slot in memory designated by \p handle. - * - * \retval PSA_SUCCESS - * Success: \p handle is a handle to `*p_slot`. Note that `*p_slot` - * may be empty or occupied. - * \retval PSA_ERROR_INVALID_HANDLE - * \p handle is out of range or is not in use. - * \retval PSA_ERROR_BAD_STATE + * key slot containing the description of the key + * identified by \p key. + * + * \retval #PSA_SUCCESS + * \p *p_slot contains a pointer to the key slot containing the + * description of the key identified by \p key. + * The key slot counter has been incremented. + * \retval #PSA_ERROR_BAD_STATE * The library has not been initialized. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p key is not a valid key identifier. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \p key is a persistent key identifier. The implementation does not + * have sufficient resources to load the persistent key. This can be + * due to a lack of empty key slot, or available memory. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * There is no key with key identifier \p key. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT */ -psa_status_t psa_get_key_slot( psa_key_handle_t handle, - psa_key_slot_t **p_slot ); +psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot ); /** Initialize the key slot structures. * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Currently this function always succeeds. */ psa_status_t psa_initialize_key_slots( void ); @@ -60,19 +114,61 @@ void psa_wipe_all_key_slots( void ); /** Find a free key slot. * * This function returns a key slot that is available for use and is in its - * ground state (all-bits-zero). + * ground state (all-bits-zero). On success, the key slot is locked. It is + * the responsibility of the caller to unlock the key slot when it does not + * access it anymore. * - * \param[out] handle On success, a slot number that can be used as a - * handle to the slot. - * \param[out] p_slot On success, a pointer to the slot. + * \param[out] volatile_key_id On success, volatile key identifier + * associated to the returned slot. + * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_BAD_STATE */ -psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle, +psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot ); +/** Lock a key slot. + * + * This function increments the key slot lock counter by one. + * + * \param[in] slot The key slot. + * + * \retval #PSA_SUCCESS + The key slot lock counter was incremented. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * The lock counter already reached its maximum value and was not + * increased. + */ +static inline psa_status_t psa_lock_key_slot( psa_key_slot_t *slot ) +{ + if( slot->lock_count >= SIZE_MAX ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + + slot->lock_count++; + + return( PSA_SUCCESS ); +} + +/** Unlock a key slot. + * + * This function decrements the key slot lock counter by one. + * + * \note To ease the handling of errors in retrieving a key slot + * a NULL input pointer is valid, and the function returns + * successfully without doing anything in that case. + * + * \param[in] slot The key slot. + * \retval #PSA_SUCCESS + * \p slot is NULL or the key slot lock counter has been + * decremented successfully. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * The lock counter was equal to 0. + * + */ +psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot ); + /** Test whether a lifetime designates a key in an external cryptoprocessor. * * \param lifetime The lifetime to test. @@ -108,19 +204,26 @@ static inline int psa_key_lifetime_is_external( psa_key_lifetime_t lifetime ) psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime, psa_se_drv_table_entry_t **p_drv ); -/** Validate that a key's persistence attributes are valid. +/** Validate the persistence of a key. * - * This function checks whether a key's declared persistence level and key ID - * attributes are valid and known to the PSA Core in its actual configuration. - * - * \param[in] lifetime The key lifetime attribute. - * \param[in] key_id The key ID attribute + * \param[in] lifetime The key lifetime attribute. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INVALID_ARGUMENT The key is persistent but persistent + * keys are not supported. */ -psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime, - psa_key_id_t key_id ); +psa_status_t psa_validate_key_persistence( psa_key_lifetime_t lifetime ); +/** Validate a key identifier. + * + * \param[in] key The key identifier. + * \param[in] vendor_ok Non-zero to indicate that key identifiers in the + * vendor range are allowed, volatile key identifiers + * excepted \c 0 otherwise. + * + * \retval #PSA_SUCCESS The identifier is valid. + * \retval #PSA_ERROR_INVALID_ARGUMENT The key identifier is not valid. + */ +psa_status_t psa_validate_key_id( mbedtls_svc_key_id_t key, int vendor_ok ); #endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */ diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.c index 103c9bbb8ea..1ebd20ee377 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.c +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.c @@ -55,27 +55,27 @@ /* Key storage */ /****************************************************************/ -/* Determine a file name (ITS file identifier) for the given key file - * identifier. The file name must be distinct from any file that is used - * for a purpose other than storing a key. Currently, the only such file - * 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( psa_key_file_id_t file_id ) +/* 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_FILE_ID_ENCODES_OWNER) && \ - defined(PSA_CRYPTO_SECURE) +#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 = (uint32_t) file_id.owner; - return( (uint64_t) unsigned_owner << 32 | file_id.key_id ); + 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_file_id_valid() in psa_crypto_slot_management.c + * 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( file_id ); + return( key ); #endif } @@ -90,13 +90,12 @@ static psa_storage_uid_t psa_its_identifier_of_slot( psa_key_file_id_t file_id ) * \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 - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_DOES_NOT_EXIST + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DOES_NOT_EXIST */ -static psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, - uint8_t *data, - size_t data_size ) +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 ); @@ -114,7 +113,7 @@ static psa_status_t psa_crypto_storage_load( const psa_key_file_id_t key, return( status ); } -int psa_is_key_present_in_storage( const psa_key_file_id_t key ) +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 ); @@ -138,12 +137,12 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key ) * \param data_length The number of bytes * that make up the data. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_STORAGE - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_ALREADY_EXISTS + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_ALREADY_EXISTS */ -static psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, +static psa_status_t psa_crypto_storage_store( const mbedtls_svc_key_id_t key, const uint8_t *data, size_t data_length ) { @@ -184,7 +183,7 @@ static psa_status_t psa_crypto_storage_store( const psa_key_file_id_t key, return( status ); } -psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) +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 ); @@ -211,11 +210,11 @@ psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ) * is to be obtained. * \param[out] data_length The number of bytes that make up the data. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_STORAGE_FAILURE */ static psa_status_t psa_crypto_storage_get_data_length( - const psa_key_file_id_t key, + const mbedtls_svc_key_id_t key, size_t *data_length ) { psa_status_t status; @@ -254,6 +253,25 @@ static psa_status_t psa_crypto_storage_get_data_length( } #endif +/* + * 16-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT16_LE +#define GET_UINT16_LE( n, b, i ) \ +{ \ + (n) = ( (uint16_t) (b)[(i) ] ) \ + | ( (uint16_t) (b)[(i) + 1] << 8 ); \ +} +#endif + +#ifndef PUT_UINT16_LE +#define PUT_UINT16_LE( n, b, i ) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ +} +#endif + /** * Persistent key storage magic header. */ @@ -264,9 +282,8 @@ 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[4]; /* Size=4 for a 2-byte type to keep the structure more - * regular and aligned and to make potential future - * extensibility easier. */ + 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[]; @@ -283,7 +300,8 @@ void psa_format_key_data_for_storage( const uint8_t *data, memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ); PUT_UINT32_LE( 0, storage_format->version, 0 ); PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); - PUT_UINT32_LE( (uint32_t) attr->type, storage_format->type, 0 ); + PUT_UINT16_LE( (uint16_t) attr->type, storage_format->type, 0 ); + PUT_UINT16_LE( (uint16_t) attr->bits, storage_format->bits, 0 ); PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); @@ -309,7 +327,6 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, const psa_persistent_key_storage_format *storage_format = (const psa_persistent_key_storage_format *)storage_data; uint32_t version; - uint32_t type; if( storage_data_length < sizeof(*storage_format) ) return( PSA_ERROR_STORAGE_FAILURE ); @@ -340,11 +357,8 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, } GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); - GET_UINT32_LE( type, storage_format->type, 0 ); - if( type <= (psa_key_type_t) -1 ) - attr->type = (psa_key_type_t) type; - else - return( PSA_ERROR_STORAGE_FAILURE ); + GET_UINT16_LE( attr->type, storage_format->type, 0 ); + GET_UINT16_LE( attr->bits, storage_format->bits, 0 ); GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); @@ -394,7 +408,7 @@ psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, psa_status_t status = PSA_SUCCESS; uint8_t *loaded_data; size_t storage_data_length = 0; - psa_key_id_t key = attr->id; + mbedtls_svc_key_id_t key = attr->id; status = psa_crypto_storage_get_data_length( key, &storage_data_length ); if( status != PSA_SUCCESS ) diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.h b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.h index debc742bd10..fbc94fc387d 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.h +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/mbedtls/psa_crypto_storage.h @@ -72,7 +72,7 @@ extern "C" { * \retval 1 * Persistent data present for slot number */ -int psa_is_key_present_in_storage( const psa_key_file_id_t key ); +int psa_is_key_present_in_storage( const mbedtls_svc_key_id_t key ); /** * \brief Format key data and metadata and save to a location for given key @@ -81,9 +81,10 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key ); * This function formats the key data and metadata and saves it to a * persistent storage backend. The storage location corresponding to the * key slot must be empty, otherwise this function will fail. This function - * should be called after psa_import_key_into_slot() to ensure the + * should be called after loading the key into an internal slot to ensure the * persistent key is not saved into a storage location corresponding to an - * already occupied non-persistent key, as well as validating the key data. + * already occupied non-persistent key, as well as ensuring the key data is + * validated. * * * \param[in] attr The attributes of the key to save. @@ -92,11 +93,11 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key ); * \param[in] data Buffer containing the key data. * \param data_length The number of bytes that make up the key data. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_MEMORY - * \retval PSA_ERROR_INSUFFICIENT_STORAGE - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_ALREADY_EXISTS + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_ALREADY_EXISTS */ psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr, const uint8_t *data, @@ -121,10 +122,10 @@ psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr, * \param[out] data Pointer to an allocated key data buffer on return. * \param[out] data_length The number of bytes that make up the key data. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_MEMORY - * \retval PSA_ERROR_STORAGE_FAILURE - * \retval PSA_ERROR_DOES_NOT_EXIST + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DOES_NOT_EXIST */ psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, uint8_t **data, @@ -136,12 +137,12 @@ psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, * \param key Persistent identifier of the key to remove * from persistent storage. * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * The key was successfully removed, * or the key did not exist. - * \retval PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_STORAGE_FAILURE */ -psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key ); +psa_status_t psa_destroy_persistent_key( const mbedtls_svc_key_id_t key ); /** * \brief Free the temporary buffer allocated by psa_load_persistent_key(). @@ -181,10 +182,10 @@ void psa_format_key_data_for_storage( const uint8_t *data, * \param[out] attr On success, the attribute structure is filled * with the loaded key metadata. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_STORAGE - * \retval PSA_ERROR_INSUFFICIENT_MEMORY - * \retval PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_STORAGE_FAILURE */ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, size_t storage_data_length, @@ -292,7 +293,7 @@ typedef union uint16_t unused1; psa_key_lifetime_t lifetime; psa_key_slot_number_t slot; - psa_key_id_t id; + mbedtls_svc_key_id_t id; } key; } psa_crypto_transaction_t;