Merge remote-tracking branch 'mbedtls/development' into mbedtls_private_with_python
Conflicts:
include/mbedtls/ssl.h
include/psa/crypto_struct.h
Conflicts fixed by using the code from development branch
and manually re-applying the MBEDTLS_PRIVATE wrapping.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index e066da7..90dee6c 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -55,9 +55,8 @@
#endif
#endif /* _WIN32 */
-#if defined(TARGET_LIKE_MBED) && \
- ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
-#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
+#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
+#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
@@ -826,6 +825,10 @@
#error "MBEDTLS_SSL_PROTO_TLS1_1 (TLS v1.1 support) was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4286"
#endif
+#if defined(MBEDTLS_CHECK_PARAMS) //no-check-names
+#error "MBEDTLS_CHECK_PARAMS was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4313"
+#endif
+
#if defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) //no-check-names
#error "MBEDTLS_SSL_CID_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/ARMmbed/mbedtls/issues/4335"
#endif
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 9cce3cd..3139b22 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -255,72 +255,6 @@
*/
//#define MBEDTLS_DEPRECATED_REMOVED
-/**
- * \def MBEDTLS_CHECK_PARAMS
- *
- * This configuration option controls whether the library validates more of
- * the parameters passed to it.
- *
- * When this flag is not defined, the library only attempts to validate an
- * input parameter if: (1) they may come from the outside world (such as the
- * network, the filesystem, etc.) or (2) not validating them could result in
- * internal memory errors such as overflowing a buffer controlled by the
- * library. On the other hand, it doesn't attempt to validate parameters whose
- * values are fully controlled by the application (such as pointers).
- *
- * When this flag is defined, the library additionally attempts to validate
- * parameters that are fully controlled by the application, and should always
- * be valid if the application code is fully correct and trusted.
- *
- * For example, when a function accepts as input a pointer to a buffer that may
- * contain untrusted data, and its documentation mentions that this pointer
- * must not be NULL:
- * - The pointer is checked to be non-NULL only if this option is enabled.
- * - The content of the buffer is always validated.
- *
- * When this flag is defined, if a library function receives a parameter that
- * is invalid:
- * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
- * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
- * will immediately return. If the function returns an Mbed TLS error code,
- * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
- *
- * When defining this flag, you also need to arrange a definition for
- * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
- * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
- * function mbedtls_param_failed(), but the library does not define this
- * function. If you do not make any other arrangements, you must provide
- * the function mbedtls_param_failed() in your application.
- * See `platform_util.h` for its prototype.
- * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
- * library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
- * You can still supply an alternative definition of
- * MBEDTLS_PARAM_FAILED(), which may call `assert`.
- * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
- * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
- * the library will call the macro that you defined and will not supply
- * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
- * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
- * files include `<assert.h>`.
- *
- * Uncomment to enable validation of application-controlled parameters.
- */
-//#define MBEDTLS_CHECK_PARAMS
-
-/**
- * \def MBEDTLS_CHECK_PARAMS_ASSERT
- *
- * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
- * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
- *
- * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
- * calling a function mbedtls_param_failed(). See the documentation of
- * #MBEDTLS_CHECK_PARAMS for details.
- *
- * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
- */
-//#define MBEDTLS_CHECK_PARAMS_ASSERT
-
/* \} name SECTION: System support */
/**
@@ -1880,18 +1814,6 @@
#define MBEDTLS_VERSION_FEATURES
/**
- * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
- *
- * If set, the X509 parser will not break-off when parsing an X509 certificate
- * and encountering an unknown critical extension.
- *
- * \warning Depending on your PKI use, enabling this can be a security risk!
- *
- * Uncomment to prevent an error.
- */
-//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-
-/**
* \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
*
* If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()`
@@ -1911,33 +1833,6 @@
//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
/**
- * \def MBEDTLS_X509_CHECK_KEY_USAGE
- *
- * Enable verification of the keyUsage extension (CA and leaf certificates).
- *
- * Disabling this avoids problems with mis-issued and/or misused
- * (intermediate) CA and leaf certificates.
- *
- * \warning Depending on your PKI use, disabling this can be a security risk!
- *
- * Comment to skip keyUsage checking for both CA and leaf certificates.
- */
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-
-/**
- * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
- *
- * Enable verification of the extendedKeyUsage extension (leaf certificates).
- *
- * Disabling this avoids problems with mis-issued and/or misused certificates.
- *
- * \warning Depending on your PKI use, disabling this can be a security risk!
- *
- * Comment to skip extendedKeyUsage checking for certificates.
- */
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-/**
* \def MBEDTLS_X509_REMOVE_INFO
*
* Disable mbedtls_x509_*_info() and related APIs.
@@ -3303,42 +3198,6 @@
//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
-/**
- * \brief This macro is invoked by the library when an invalid parameter
- * is detected that is only checked with #MBEDTLS_CHECK_PARAMS
- * (see the documentation of that option for context).
- *
- * When you leave this undefined here, the library provides
- * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
- * is defined, the default definition is `assert(cond)`,
- * otherwise the default definition calls a function
- * mbedtls_param_failed(). This function is declared in
- * `platform_util.h` for the benefit of the library, but
- * you need to define in your application.
- *
- * When you define this here, this replaces the default
- * definition in platform_util.h (which no longer declares the
- * function mbedtls_param_failed()) and it is your responsibility
- * to make sure this macro expands to something suitable (in
- * particular, that all the necessary declarations are visible
- * from within the library - you can ensure that by providing
- * them in this file next to the macro definition).
- * If you define this macro to call `assert`, also define
- * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
- * include `<assert.h>`.
- *
- * Note that you may define this macro to expand to nothing, in
- * which case you don't have to worry about declarations or
- * definitions. However, you will then be notified about invalid
- * parameters only in non-void functions, and void function will
- * just silently return early on invalid parameters, which
- * partially negates the benefits of enabling
- * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
- *
- * \param cond The expression that should evaluate to true, but doesn't.
- */
-//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
-
/* PSA options */
/**
* Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index fbc2a0d..6d9cfec 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -39,78 +39,10 @@
extern "C" {
#endif
-#if defined(MBEDTLS_CHECK_PARAMS)
-
-#if defined(MBEDTLS_CHECK_PARAMS_ASSERT)
-/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert
- * (which is what our config.h suggests). */
-#include <assert.h>
-#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */
-
-#if defined(MBEDTLS_PARAM_FAILED)
-/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
- *
- * This flag can be used to check whether it is safe to assume that
- * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
- */
-#define MBEDTLS_PARAM_FAILED_ALT
-
-#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT)
-#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
-#define MBEDTLS_PARAM_FAILED_ALT
-
-#else /* MBEDTLS_PARAM_FAILED */
-#define MBEDTLS_PARAM_FAILED( cond ) \
- mbedtls_param_failed( #cond, __FILE__, __LINE__ )
-
-/**
- * \brief User supplied callback function for parameter validation failure.
- * See #MBEDTLS_CHECK_PARAMS for context.
- *
- * This function will be called unless an alternative treatement
- * is defined through the #MBEDTLS_PARAM_FAILED macro.
- *
- * This function can return, and the operation will be aborted, or
- * alternatively, through use of setjmp()/longjmp() can resume
- * execution in the application code.
- *
- * \param failure_condition The assertion that didn't hold.
- * \param file The file where the assertion failed.
- * \param line The line in the file where the assertion failed.
- */
-void mbedtls_param_failed( const char *failure_condition,
- const char *file,
- int line );
-#endif /* MBEDTLS_PARAM_FAILED */
-
-/* Internal macro meant to be called only from within the library. */
-#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \
- do { \
- if( !(cond) ) \
- { \
- MBEDTLS_PARAM_FAILED( cond ); \
- return( ret ); \
- } \
- } while( 0 )
-
-/* Internal macro meant to be called only from within the library. */
-#define MBEDTLS_INTERNAL_VALIDATE( cond ) \
- do { \
- if( !(cond) ) \
- { \
- MBEDTLS_PARAM_FAILED( cond ); \
- return; \
- } \
- } while( 0 )
-
-#else /* MBEDTLS_CHECK_PARAMS */
-
/* Internal macros meant to be called only from within the library. */
#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 )
#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 )
-#endif /* MBEDTLS_CHECK_PARAMS */
-
/* Internal helper macros for deprecating API constants. */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index d3b695e..f29a0aa 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -131,33 +131,51 @@
/**
* \brief This function initializes an RSA context.
*
+ * \note This function initializes the padding and the hash
+ * identifier to respectively #MBEDTLS_RSA_PKCS_V15 and
+ * #MBEDTLS_MD_NONE. See mbedtls_rsa_set_padding() for more
+ * information about those parameters.
+ *
+ * \param ctx The RSA context to initialize. This must not be \c NULL.
+ */
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx );
+
+/**
+ * \brief This function sets padding for an already initialized RSA
+ * context.
+ *
* \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
* encryption scheme and the RSASSA-PSS signature scheme.
*
* \note The \p hash_id parameter is ignored when using
* #MBEDTLS_RSA_PKCS_V15 padding.
*
- * \note The choice of padding mode is strictly enforced for private key
- * operations, since there might be security concerns in
+ * \note The choice of padding mode is strictly enforced for private
+ * key operations, since there might be security concerns in
* mixing padding modes. For public key operations it is
* a default value, which can be overridden by calling specific
- * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions.
+ * \c mbedtls_rsa_rsaes_xxx or \c mbedtls_rsa_rsassa_xxx
+ * functions.
*
* \note The hash selected in \p hash_id is always used for OEAP
* encryption. For PSS signatures, it is always used for
* making signatures, but can be overridden for verifying them.
* If set to #MBEDTLS_MD_NONE, it is always overridden.
*
- * \param ctx The RSA context to initialize. This must not be \c NULL.
+ * \param ctx The initialized RSA context to be configured.
* \param padding The padding mode to use. This must be either
* #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
- * \param hash_id The hash identifier of ::mbedtls_md_type_t type, if
- * \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused
- * otherwise.
+ * \param hash_id The hash identifier for PSS or OAEP, if \p padding is
+ * #MBEDTLS_RSA_PKCS_V21. #MBEDTLS_MD_NONE is accepted by this
+ * function but may be not suitable for some operations.
+ * Ignored if \p padding is #MBEDTLS_RSA_PKCS_V15.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_RSA_INVALID_PADDING failure:
+ * \p padding or \p hash_id is invalid.
*/
-void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
- int padding,
- int hash_id );
+int mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+ mbedtls_md_type_t hash_id );
/**
* \brief This function imports a set of core parameters into an
@@ -389,18 +407,6 @@
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP );
/**
- * \brief This function sets padding for an already initialized RSA
- * context. See mbedtls_rsa_init() for details.
- *
- * \param ctx The initialized RSA context to be configured.
- * \param padding The padding mode to use. This must be either
- * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
- * \param hash_id The #MBEDTLS_RSA_PKCS_V21 hash identifier.
- */
-void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
- int hash_id );
-
-/**
* \brief This function retrieves the length of RSA modulus in Bytes.
*
* \param ctx The initialized RSA context.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index b6b9c8c..8f21a9a 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -126,14 +126,10 @@
*/
/* These are the high an low bytes of ProtocolVersion as defined by:
- * - RFC 2246: ProtocolVersion version = { 3, 1 }; // TLS v1.0
- * - RFC 4346: ProtocolVersion version = { 3, 2 }; // TLS v1.1
* - RFC 5246: ProtocolVersion version = { 3, 3 }; // TLS v1.2
* - RFC 8446: see section 4.2.1
*/
#define MBEDTLS_SSL_MAJOR_VERSION_3 3
-#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 deprecated */
-#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 deprecated */
#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */
#define MBEDTLS_SSL_MINOR_VERSION_4 4 /*!< TLS v1.3 (experimental) */
@@ -977,10 +973,8 @@
* Pointers
*/
- /** Allowed ciphersuites per version. To access list's elements, please use
- * \c mbedtls_ssl_get_protocol_version_ciphersuites
- */
- const int *MBEDTLS_PRIVATE(ciphersuite_list)[3];
+ /** Allowed ciphersuites for (D)TLS 1.2 (0-terminated) */
+ const int *MBEDTLS_PRIVATE(ciphersuite_list);
/** Callback for printing debug output */
void (*MBEDTLS_PRIVATE(f_dbg))(void *, int, const char *, int, const char *);
@@ -2509,17 +2503,6 @@
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
const int *ciphersuites );
-/**
- * \brief Get ciphersuite for given protocol's minor version.
- *
- * \param conf The SSL configuration.
- * \param prot_version Protocol version. One of MBEDTLS_SSL_MINOR_VERSION_x macros.
- * \return Ciphersuites pointer if successful.
- * \return \c NULL if no ciphersuites where found.
- */
-const int *mbedtls_ssl_get_protocol_version_ciphersuites(
- const mbedtls_ssl_config *conf, int prot_version );
-
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0
#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1
@@ -2559,27 +2542,6 @@
int ignore_other_cids );
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-/**
- * \brief Set the list of allowed ciphersuites and the
- * preference order for a specific version of the protocol.
- * (Only useful on the server side)
- *
- * The ciphersuites array is not copied, and must remain
- * valid for the lifetime of the ssl_config.
- *
- * \param conf SSL configuration
- * \param ciphersuites 0-terminated list of allowed ciphersuites
- * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3
- * supported)
- * \param minor Minor version number (only MBEDTLS_SSL_MINOR_VERSION_3
- * supported)
- *
- * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
- */
-void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
- const int *ciphersuites,
- int major, int minor );
-
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Set the X.509 security profile used for verification
@@ -3230,8 +3192,7 @@
*
* \param conf SSL configuration
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
- * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
- * MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ * \param minor Minor version number (only MBEDTLS_SSL_MINOR_VERSION_3 supported)
*/
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor );
@@ -3246,9 +3207,7 @@
*
* \param conf SSL configuration
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
- * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_1,
- * MBEDTLS_SSL_MINOR_VERSION_2,
- * MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ * \param minor Minor version number (only MBEDTLS_SSL_MINOR_VERSION_3 supported)
*/
void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor );
@@ -3578,45 +3537,15 @@
*/
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-/**
- * \brief Return the maximum fragment length (payload, in bytes) for
- * the output buffer. For the client, this is the configured
- * value. For the server, it is the minimum of two - the
- * configured value and the negotiated one.
- *
- * \sa mbedtls_ssl_conf_max_frag_len()
- * \sa mbedtls_ssl_get_max_record_payload()
- *
- * \param ssl SSL context
- *
- * \return Current maximum fragment length for the output buffer.
- */
-size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl );
-
-/**
- * \brief Return the maximum fragment length (payload, in bytes) for
- * the input buffer. This is the negotiated maximum fragment
- * length, or, if there is none, MBEDTLS_SSL_IN_CONTENT_LEN.
- * If it is not defined either, the value is 2^14. This function
- * works as its predecessor, \c mbedtls_ssl_get_max_frag_len().
- *
- * \sa mbedtls_ssl_conf_max_frag_len()
- * \sa mbedtls_ssl_get_max_record_payload()
- *
- * \param ssl SSL context
- *
- * \return Current maximum fragment length for the output buffer.
- */
-size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl );
-#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
-
/**
* \brief Return the current maximum outgoing record payload in bytes.
- * This takes into account the config.h setting \c
- * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated
- * max fragment length extension if used, and for DTLS the
- * path MTU as configured and current record expansion.
+ *
+ * \note The logic to determine the maximum outgoing record payload is
+ * version-specific. It takes into account various factors, such as
+ * the config.h setting \c MBEDTLS_SSL_OUT_CONTENT_LEN, extensions
+ * such as the max fragment length or record size limit extension if
+ * used, and for DTLS the path MTU as configured and current
+ * record expansion.
*
* \note With DTLS, \c mbedtls_ssl_write() will return an error if
* called with a larger length value.
@@ -3625,9 +3554,7 @@
* to the caller to call \c mbedtls_ssl_write() again in
* order to send the remaining bytes if any.
*
- * \sa mbedtls_ssl_set_mtu()
- * \sa mbedtls_ssl_get_output_max_frag_len()
- * \sa mbedtls_ssl_get_input_max_frag_len()
+ * \sa mbedtls_ssl_get_max_out_record_payload()
* \sa mbedtls_ssl_get_record_expansion()
*
* \param ssl SSL context
@@ -3637,6 +3564,26 @@
*/
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
+/**
+ * \brief Return the current maximum incoming record payload in bytes.
+ *
+ * \note The logic to determine the maximum outgoing record payload is
+ * version-specific. It takes into account various factors, such as
+ * the config.h setting \c MBEDTLS_SSL_IN_CONTENT_LEN, extensions
+ * such as the max fragment length extension or record size limit
+ * extension if used, and the current record expansion.
+ *
+ * \sa mbedtls_ssl_set_mtu()
+ * \sa mbedtls_ssl_get_max_in_record_payload()
+ * \sa mbedtls_ssl_get_record_expansion()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum payload for an outgoing record,
+ * or a negative error code.
+ */
+int mbedtls_ssl_get_max_in_record_payload( const mbedtls_ssl_context *ssl );
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Return the peer certificate from the current connection.
@@ -3935,7 +3882,7 @@
* or negotiated with the peer), then:
* - with TLS, less bytes than requested are written.
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
- * \c mbedtls_ssl_get_output_max_frag_len() may be used to
+ * \c mbedtls_ssl_get_max_out_record_payload() may be used to
* query the active maximum fragment length.
*
* \note Attempting to write 0 bytes will result in an empty TLS
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index f25db44..d383168 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -828,7 +828,6 @@
#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
-#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
/**
* \brief Check usage of certificate against keyUsage extension.
*
@@ -852,9 +851,7 @@
*/
int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
unsigned int usage );
-#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */
-#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
/**
* \brief Check usage of certificate against extendedKeyUsage.
*
@@ -871,7 +868,6 @@
int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
const char *usage_oid,
size_t usage_len );
-#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
#if defined(MBEDTLS_X509_CRL_PARSE_C)
/**
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 6aa7ccc..534902f 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -112,12 +112,6 @@
* This macro returns a suitable initializer for a key attribute structure
* of type #psa_key_attributes_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_KEY_ATTRIBUTES_INIT {0}
-#endif
/** Return an initial value for a key attributes structure.
*/
@@ -938,8 +932,8 @@
* \endcode
*
* This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
typedef struct psa_hash_operation_s psa_hash_operation_t;
/** \def PSA_HASH_OPERATION_INIT
@@ -947,12 +941,6 @@
* This macro returns a suitable initializer for a hash operation object
* of type #psa_hash_operation_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_HASH_OPERATION_INIT {0}
-#endif
/** Return an initial value for a hash operation object.
*/
@@ -1307,9 +1295,10 @@
* operation = psa_mac_operation_init();
* \endcode
*
+ *
* This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
typedef struct psa_mac_operation_s psa_mac_operation_t;
/** \def PSA_MAC_OPERATION_INIT
@@ -1317,12 +1306,6 @@
* This macro returns a suitable initializer for a MAC operation object of type
* #psa_mac_operation_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_MAC_OPERATION_INIT {0}
-#endif
/** Return an initial value for a MAC operation object.
*/
@@ -1732,8 +1715,8 @@
* \endcode
*
* This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
typedef struct psa_cipher_operation_s psa_cipher_operation_t;
/** \def PSA_CIPHER_OPERATION_INIT
@@ -1741,12 +1724,6 @@
* This macro returns a suitable initializer for a cipher operation object of
* type #psa_cipher_operation_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_CIPHER_OPERATION_INIT {0}
-#endif
/** Return an initial value for a cipher operation object.
*/
@@ -2261,8 +2238,8 @@
* \endcode
*
* This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation. */
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
typedef struct psa_aead_operation_s psa_aead_operation_t;
/** \def PSA_AEAD_OPERATION_INIT
@@ -2270,12 +2247,6 @@
* This macro returns a suitable initializer for an AEAD operation object of
* type #psa_aead_operation_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_AEAD_OPERATION_INIT {0}
-#endif
/** Return an initial value for an AEAD operation object.
*/
@@ -3260,8 +3231,8 @@
* \endcode
*
* This is an implementation-defined \c struct. Applications should not
- * make any assumptions about the content of this structure except
- * as directed by the documentation of a specific implementation.
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice.
*/
typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
@@ -3270,12 +3241,6 @@
* This macro returns a suitable initializer for a key derivation operation
* object of type #psa_key_derivation_operation_t.
*/
-#ifdef __DOXYGEN_ONLY__
-/* This is an example definition for documentation purposes.
- * Implementations should define a suitable value in `crypto_struct.h`.
- */
-#define PSA_KEY_DERIVATION_OPERATION_INIT {0}
-#endif
/** Return an initial value for a key derivation operation object.
*/
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 3611c41..51c0859 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -814,6 +814,1009 @@
/** @} */
+/** \addtogroup crypto_types
+ * @{
+ */
+
+#define PSA_ALG_CATEGORY_PAKE ((psa_algorithm_t)0x0a000000)
+
+/** Whether the specified algorithm is a password-authenticated key exchange.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a password-authenticated key exchange (PAKE)
+ * algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_PAKE(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_PAKE)
+
+/** The Password-authenticated key exchange by juggling (J-PAKE) algorithm.
+ *
+ * This is J-PAKE as defined by RFC 8236, instantiated with the following
+ * parameters:
+ *
+ * - The group can be either an elliptic curve or defined over a finite field.
+ * - Schnorr NIZK proof as defined by RFC 8235 and using the same group as the
+ * J-PAKE algorithm.
+ * - A cryptographic hash function.
+ *
+ * To select these parameters and set up the cipher suite, call these functions
+ * in any order:
+ *
+ * \code
+ * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_JPAKE);
+ * psa_pake_cs_set_primitive(cipher_suite,
+ * PSA_PAKE_PRIMITIVE(type, family, bits));
+ * psa_pake_cs_set_hash(cipher_suite, hash);
+ * \endcode
+ *
+ * For more information on how to set a specific curve or field, refer to the
+ * documentation of the individual \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+ *
+ * After initializing a J-PAKE operation, call
+ *
+ * \code
+ * psa_pake_setup(operation, cipher_suite);
+ * psa_pake_set_user(operation, ...);
+ * psa_pake_set_peer(operation, ...);
+ * psa_pake_set_password_key(operation, ...);
+ * \endcode
+ *
+ * The password is read as a byte array and must be non-empty. This can be the
+ * password itself (in some pre-defined character encoding) or some value
+ * derived from the password as mandated by some higher level protocol.
+ *
+ * (The implementation converts this byte array to a number as described in
+ * Section 2.3.8 of _SEC 1: Elliptic Curve Cryptography_
+ * (https://www.secg.org/sec1-v2.pdf), before reducing it modulo \c q. Here
+ * \c q is order of the group defined by the primitive set in the cipher suite.
+ * The \c psa_pake_set_password_xxx() functions return an error if the result
+ * of the reduction is 0.)
+ *
+ * The key exchange flow for J-PAKE is as follows:
+ * -# To get the first round data that needs to be sent to the peer, call
+ * \code
+ * // Get g1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get the ZKP public key for x1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get the ZKP proof for x1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * // Get g2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get the ZKP public key for x2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get the ZKP proof for x2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To provide the first round data received from the peer to the operation,
+ * call
+ * \code
+ * // Set g3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set the ZKP public key for x3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set the ZKP proof for x3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * // Set g4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set the ZKP public key for x4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set the ZKP proof for x4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To get the second round data that needs to be sent to the peer, call
+ * \code
+ * // Get A
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get ZKP public key for x2*s
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get ZKP proof for x2*s
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To provide the second round data received from the peer to the operation,
+ * call
+ * \code
+ * // Set B
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set ZKP public key for x4*s
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set ZKP proof for x4*s
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To access the shared secret call
+ * \code
+ * // Get Ka=Kb=K
+ * psa_pake_get_implicit_key()
+ * \endcode
+ *
+ * For more information consult the documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants.
+ *
+ * At this point there is a cryptographic guarantee that only the authenticated
+ * party who used the same password is able to compute the key. But there is no
+ * guarantee that the peer is the party it claims to be and was able to do so.
+ *
+ * That is, the authentication is only implicit (the peer is not authenticated
+ * at this point, and no action should be taken that assume that they are - like
+ * for example accessing restricted files).
+ *
+ * To make the authentication explicit there are various methods, see Section 5
+ * of RFC 8236 for two examples.
+ *
+ */
+#define PSA_ALG_JPAKE ((psa_algorithm_t)0x0a000100)
+
+/** @} */
+
+/** \defgroup pake Password-authenticated key exchange (PAKE)
+ *
+ * This is a proposed PAKE interface for the PSA Crypto API. It is not part of
+ * the official PSA Crypto API yet.
+ *
+ * \note The content of this section is not part of the stable API and ABI
+ * of Mbed Crypto and may change arbitrarily from version to version.
+ * Same holds for the corresponding macros #PSA_ALG_CATEGORY_PAKE and
+ * #PSA_ALG_JPAKE.
+ * @{
+ */
+
+/** \brief Encoding of the side of PAKE
+ *
+ * Encodes which side of the algorithm is being executed. For more information
+ * see the documentation of individual \c PSA_PAKE_SIDE_XXX constants.
+ */
+typedef uint8_t psa_pake_side_t;
+
+/** Encoding of input and output indicators for PAKE.
+ *
+ * Some PAKE algorithms need to exchange more data than just a single key share.
+ * This type is for encoding additional input and output data for such
+ * algorithms.
+ */
+typedef uint8_t psa_pake_step_t;
+
+/** Encoding of the type of the PAKE's primitive.
+ *
+ * Values defined by this standard will never be in the range 0x80-0xff.
+ * Vendors who define additional types must use an encoding in this range.
+ *
+ * For more information see the documentation of individual
+ * \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+ */
+typedef uint8_t psa_pake_primitive_type_t;
+
+/** \brief Encoding of the family of the primitive associated with the PAKE.
+ *
+ * For more information see the documentation of individual
+ * \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+ */
+typedef uint8_t psa_pake_family_t;
+
+/** \brief Encoding of the primitive associated with the PAKE.
+ *
+ * For more information see the documentation of the #PSA_PAKE_PRIMITIVE macro.
+ */
+typedef uint32_t psa_pake_primitive_t;
+
+/** The first peer in a balanced PAKE.
+ *
+ * Although balanced PAKE algorithms are symmetric, some of them needs an
+ * ordering of peers for the transcript calculations. If the algorithm does not
+ * need this, both #PSA_PAKE_SIDE_FIRST and #PSA_PAKE_SIDE_SECOND are
+ * accepted.
+ */
+#define PSA_PAKE_SIDE_FIRST ((psa_pake_side_t)0x01)
+
+/** The second peer in a balanced PAKE.
+ *
+ * Although balanced PAKE algorithms are symmetric, some of them needs an
+ * ordering of peers for the transcript calculations. If the algorithm does not
+ * need this, either #PSA_PAKE_SIDE_FIRST or #PSA_PAKE_SIDE_SECOND are
+ * accepted.
+ */
+#define PSA_PAKE_SIDE_SECOND ((psa_pake_side_t)0x02)
+
+/** The client in an augmented PAKE.
+ *
+ * Augmented PAKE algorithms need to differentiate between client and server.
+ */
+#define PSA_PAKE_SIDE_CLIENT ((psa_pake_side_t)0x11)
+
+/** The server in an augmented PAKE.
+ *
+ * Augmented PAKE algorithms need to differentiate between client and server.
+ */
+#define PSA_PAKE_SIDE_SERVER ((psa_pake_side_t)0x12)
+
+/** The PAKE primitive type indicating the use of elliptic curves.
+ *
+ * The values of the \c family and \c bits fields of the cipher suite identify a
+ * specific elliptic curve, using the same mapping that is used for ECC
+ * (::psa_ecc_family_t) keys.
+ *
+ * (Here \c family means the value returned by psa_pake_cs_get_family() and
+ * \c bits means the value returned by psa_pake_cs_get_bits().)
+ *
+ * Input and output during the operation can involve group elements and scalar
+ * values:
+ * -# The format for group elements is the same as for public keys on the
+ * specific curve would be. For more information, consult the documentation of
+ * psa_export_public_key().
+ * -# The format for scalars is the same as for private keys on the specific
+ * curve would be. For more information, consult the documentation of
+ * psa_export_key().
+ */
+#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t)0x01)
+
+/** The PAKE primitive type indicating the use of Diffie-Hellman groups.
+ *
+ * The values of the \c family and \c bits fields of the cipher suite identify
+ * a specific Diffie-Hellman group, using the same mapping that is used for
+ * Diffie-Hellman (::psa_dh_family_t) keys.
+ *
+ * (Here \c family means the value returned by psa_pake_cs_get_family() and
+ * \c bits means the value returned by psa_pake_cs_get_bits().)
+ *
+ * Input and output during the operation can involve group elements and scalar
+ * values:
+ * -# The format for group elements is the same as for public keys on the
+ * specific group would be. For more information, consult the documentation of
+ * psa_export_public_key().
+ * -# The format for scalars is the same as for private keys on the specific
+ * group would be. For more information, consult the documentation of
+ * psa_export_key().
+ */
+#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t)0x02)
+
+/** Construct a PAKE primitive from type, family and bit-size.
+ *
+ * \param pake_type The type of the primitive
+ * (value of type ::psa_pake_primitive_type_t).
+ * \param pake_family The family of the primitive
+ * (the type and interpretation of this parameter depends
+ * on \p type, for more information consult the
+ * documentation of individual ::psa_pake_primitive_type_t
+ * constants).
+ * \param pake_bits The bit-size of the primitive
+ * (Value of type \c size_t. The interpretation
+ * of this parameter depends on \p family, for more
+ * information consult the documentation of individual
+ * ::psa_pake_primitive_type_t constants).
+ *
+ * \return The constructed primitive value of type ::psa_pake_primitive_t.
+ * Return 0 if the requested primitive can't be encoded as
+ * ::psa_pake_primitive_t.
+ */
+#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \
+ ((pake_bits & 0xFFFF) != pake_bits) ? 0 : \
+ ((psa_pake_primitive_t) (((pake_type) << 24 | \
+ (pake_family) << 16) | (pake_bits)))
+
+/** The key share being sent to or received from the peer.
+ *
+ * The format for both input and output at this step is the same as for public
+ * keys on the group determined by the primitive (::psa_pake_primitive_t) would
+ * be.
+ *
+ * For more information on the format, consult the documentation of
+ * psa_export_public_key().
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t)0x01)
+
+/** A Schnorr NIZKP public key.
+ *
+ * This is the ephemeral public key in the Schnorr Non-Interactive
+ * Zero-Knowledge Proof (the value denoted by the letter 'V' in RFC 8235).
+ *
+ * The format for both input and output at this step is the same as for public
+ * keys on the group determined by the primitive (::psa_pake_primitive_t) would
+ * be.
+ *
+ * For more information on the format, consult the documentation of
+ * psa_export_public_key().
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t)0x02)
+
+/** A Schnorr NIZKP proof.
+ *
+ * This is the proof in the Schnorr Non-Interactive Zero-Knowledge Proof (the
+ * value denoted by the letter 'r' in RFC 8235).
+ *
+ * Both for input and output, the value at this step is an integer less than
+ * the order of the group selected in the cipher suite. The format depends on
+ * the group as well:
+ *
+ * - For Montgomery curves, the encoding is little endian.
+ * - For everything else the encoding is big endian (see Section 2.3.8 of
+ * _SEC 1: Elliptic Curve Cryptography_ at https://www.secg.org/sec1-v2.pdf).
+ *
+ * In both cases leading zeroes are allowed as long as the length in bytes does
+ * not exceed the byte length of the group order.
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t)0x03)
+
+/** The type of the data strucure for PAKE cipher suites.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice.
+ */
+typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
+
+/** Retrieve the PAKE algorithm from a PAKE cipher suite.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] cipher_suite The cipher suite structure to query.
+ *
+ * \return The PAKE algorithm stored in the cipher suite structure.
+ */
+static psa_algorithm_t psa_pake_cs_get_algorithm(
+ const psa_pake_cipher_suite_t* cipher_suite
+ );
+
+/** Declare the PAKE algorithm for the cipher suite.
+ *
+ * This function overwrites any PAKE algorithm
+ * previously set in \p cipher_suite.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * 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] cipher_suite The cipher suite structure to write to.
+ * \param algorithm The PAKE algorithm to write.
+ * (`PSA_ALG_XXX` values of type ::psa_algorithm_t
+ * such that #PSA_ALG_IS_PAKE(\c alg) is true.)
+ * If this is 0, the PAKE algorithm in
+ * \p cipher_suite becomes unspecified.
+ */
+static void psa_pake_cs_set_algorithm(
+ psa_pake_cipher_suite_t* cipher_suite,
+ psa_algorithm_t algorithm
+ );
+
+/** Retrieve the primitive from a PAKE cipher suite.
+ *
+ * This function may be declared as `static` (i.e. without external linkage).
+ * This function may be provided as a function-like macro, but in this case it
+ * must evaluate its argument exactly once.
+ *
+ * \param[in] cipher_suite The cipher suite structure to query.
+ *
+ * \return The primitive stored in the cipher suite structure.
+ */
+static psa_pake_primitive_t psa_pake_cs_get_primitive(
+ const psa_pake_cipher_suite_t* cipher_suite
+ );
+
+/** Declare the primitive for a PAKE cipher suite.
+ *
+ * This function overwrites any primitive previously set in \p cipher_suite.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * 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] cipher_suite The cipher suite structure to write to.
+ * \param primitive The primitive to write. If this is 0, the
+ * primitive type in \p cipher_suite becomes
+ * unspecified.
+ */
+static void psa_pake_cs_set_primitive(
+ psa_pake_cipher_suite_t* cipher_suite,
+ psa_pake_primitive_t primitive
+ );
+
+/** Retrieve the hash algorithm from a PAKE cipher suite.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] cipher_suite The cipher suite structure to query.
+ *
+ * \return The hash algorithm stored in the cipher suite structure. The return
+ * value is 0 if the PAKE is not parametrised by a hash algorithm or if
+ * the hash algorithm is not set.
+ */
+static psa_algorithm_t psa_pake_cs_get_hash(
+ const psa_pake_cipher_suite_t* cipher_suite
+ );
+
+/** Declare the hash algorithm for a PAKE cipher suite.
+ *
+ * This function overwrites any hash algorithm
+ * previously set in \p cipher_suite.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[out] cipher_suite The cipher suite structure to write to.
+ * \param hash The hash involved in the cipher suite.
+ * (`PSA_ALG_XXX` values of type ::psa_algorithm_t
+ * such that #PSA_ALG_IS_HASH(\c alg) is true.)
+ * If this is 0, the hash algorithm in
+ * \p cipher_suite becomes unspecified.
+ */
+static void psa_pake_cs_set_hash(
+ psa_pake_cipher_suite_t* cipher_suite,
+ psa_algorithm_t hash
+ );
+
+/** The type of the state data structure for PAKE operations.
+ *
+ * Before calling any function on a PAKE operation object, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_pake_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_pake_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_PAKE_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_pake_operation_t operation = PSA_PAKE_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_pake_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_pake_operation_t operation;
+ * operation = psa_pake_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_pake_operation_s psa_pake_operation_t;
+
+/** Return an initial value for an PAKE operation object.
+ */
+static psa_pake_operation_t psa_pake_operation_init(void);
+
+/** Set the session information for a password-authenticated key exchange.
+ *
+ * The sequence of operations to set up a password-authenticated key exchange
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_pake_operation_t, e.g.
+ * #PSA_PAKE_OPERATION_INIT.
+ * -# Call psa_pake_setup() to specify the cipher suite.
+ * -# Call \c psa_pake_set_xxx() functions on the operation to complete the
+ * setup. The exact sequence of \c psa_pake_set_xxx() functions that needs
+ * to be called depends on the algorithm in use.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * A typical sequence of calls to perform a password-authenticated key
+ * exchange:
+ * -# Call psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to get the
+ * key share that needs to be sent to the peer.
+ * -# Call psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to provide
+ * the key share that was received from the peer.
+ * -# Depending on the algorithm additional calls to psa_pake_output() and
+ * psa_pake_input() might be necessary.
+ * -# Call psa_pake_get_implicit_key() for accessing the shared secret.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * If an error occurs at any step after a call to psa_pake_setup(),
+ * the operation will need to be reset by a call to psa_pake_abort(). The
+ * application may call psa_pake_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_pake_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A call to psa_pake_abort().
+ * - A successful call to psa_pake_get_implicit_key().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized but not set up yet.
+ * \param cipher_suite The cipher suite to use. (A cipher suite fully
+ * characterizes a PAKE algorithm and determines
+ * the algorithm as well.)
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The \p cipher_suite is not supported or is not valid.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
+ psa_pake_cipher_suite_t cipher_suite);
+
+/** Set the password for a password-authenticated key exchange from key ID.
+ *
+ * Call this function when the password, or a value derived from the password,
+ * is already present in the key store.
+ *
+ * \param[in,out] operation The operation object to set the password for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the password hasn't
+ * been set yet (psa_pake_set_password_key()
+ * hasn't been called yet).
+ * \param password Identifier of the key holding the password or a
+ * value derived from the password (eg. by a
+ * memory-hard function). It must remain valid
+ * until the operation terminates. It must be of
+ * type #PSA_KEY_TYPE_PASSWORD or
+ * #PSA_KEY_TYPE_PASSWORD_HASH. It has to allow
+ * the usage #PSA_KEY_USAGE_DERIVE.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must have been set up.)
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with the algorithm or the cipher suite.
+ * \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_pake_set_password_key(psa_pake_operation_t *operation,
+ mbedtls_svc_key_id_t password);
+
+/** Set the user ID for a password-authenticated key exchange.
+ *
+ * Call this function to set the user ID. For PAKE algorithms that associate a
+ * user identifier with each side of the session you need to call
+ * psa_pake_set_peer() as well. For PAKE algorithms that associate a single
+ * user identifier with the session, call psa_pake_set_user() only.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the user ID for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the user ID hasn't
+ * been set (psa_pake_set_user() hasn't been
+ * called yet).
+ * \param[in] user_id The user ID to authenticate with.
+ * \param user_id_len Size of the \p user_id buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p user_id is NULL.
+ * \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_pake_set_user(psa_pake_operation_t *operation,
+ const uint8_t *user_id,
+ size_t user_id_len);
+
+/** Set the peer ID for a password-authenticated key exchange.
+ *
+ * Call this function in addition to psa_pake_set_user() for PAKE algorithms
+ * that associate a user identifier with each side of the session. For PAKE
+ * algorithms that associate a single user identifier with the session, call
+ * psa_pake_set_user() only.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the peer ID for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the peer ID hasn't
+ * been set (psa_pake_set_peer() hasn't been
+ * called yet).
+ * \param[in] peer_id The peer's ID to authenticate.
+ * \param peer_id_len Size of the \p peer_id buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The algorithm doesn't associate a second identity with the session.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p user_id is NULL.
+ * \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_pake_set_peer(psa_pake_operation_t *operation,
+ const uint8_t *peer_id,
+ size_t peer_id_len);
+
+/** Set the side for a password-authenticated key exchange.
+ *
+ * Not all PAKE algorithms need to differentiate the communicating entities.
+ * It is optional to call this function for PAKEs that don't require a side
+ * parameter. For such PAKEs the side parameter is ignored.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the side for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the side hasn't been
+ * set (psa_pake_set_side() hasn't been called
+ * yet).
+ * \param side A value of type ::psa_pake_side_t signaling the
+ * side of the algorithm that is being set up. For
+ * more information see the documentation of
+ * \c PSA_PAKE_SIDE_XXX constants.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The \p side for this algorithm is not supported or is not valid.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_set_side(psa_pake_operation_t *operation,
+ psa_pake_side_t side);
+
+/** Get output for a step of a password-authenticated key exchange.
+ *
+ * Depending on the algorithm being executed, you might need to call this
+ * function several times or you might not need to call this at all.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use. Refer to the documentation of
+ * individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_pake_abort().
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param step The step of the algorithm for which the output is
+ * requested.
+ * \param[out] output Buffer where the output is to be written in the
+ * format appropriate for this \p step. Refer to
+ * the documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants for more
+ * information.
+ * \param output_size Size of the \p output buffer in bytes. This must
+ * be at least #PSA_PAKE_OUTPUT_SIZE(\p alg, \c
+ * cipher_suite, \p type).
+ *
+ * \param[out] output_length On success, the number of bytes of the returned
+ * output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, but beyond that
+ * validity is specific to the algorithm).
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_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_pake_output(psa_pake_operation_t *operation,
+ psa_pake_step_t step,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Provide input for a step of a password-authenticated key exchange.
+ *
+ * Depending on the algorithm being executed, you might need to call this
+ * function several times or you might not need to call this at all.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use. Refer to the documentation of
+ * individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_pake_abort().
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param step The step for which the input is provided.
+ * \param[out] input Buffer containing the input in the format
+ * appropriate for this \p step. Refer to the
+ * documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants for more
+ * information.
+ * \param[out] input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, but beyond that
+ * validity is specific to the algorithm).
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The input is not valid for the algorithm, ciphersuite or \p step.
+ * \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_pake_input(psa_pake_operation_t *operation,
+ psa_pake_step_t step,
+ uint8_t *input,
+ size_t input_length);
+
+/** Get implicitly confirmed shared secret from a PAKE.
+ *
+ * At this point there is a cryptographic guarantee that only the authenticated
+ * party who used the same password is able to compute the key. But there is no
+ * guarantee that the peer is the party it claims to be and was able to do so.
+ *
+ * That is, the authentication is only implicit. Since the peer is not
+ * authenticated yet, no action should be taken yet that assumes that the peer
+ * is who it claims to be. For example, do not access restricted files on the
+ * peer's behalf until an explicit authentication has succeeded.
+ *
+ * This function can be called after the key exchange phase of the operation
+ * has completed. It imports the shared secret output of the PAKE into the
+ * provided derivation operation. The input step
+ * #PSA_KEY_DERIVATION_INPUT_SECRET is used when placing the shared key
+ * material in the key derivation operation.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use. Refer to the documentation of
+ * individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * When this function returns successfully, \p operation becomes inactive.
+ * If this function returns an error status, both \p operation
+ * and \p key_derivation operations enter an error state and must be aborted by
+ * calling psa_pake_abort() and psa_key_derivation_abort() respectively.
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param[out] output A key derivation operation that is ready
+ * for an input step of type
+ * #PSA_KEY_DERIVATION_INPUT_SECRET.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The PAKE operation state is not valid (it must be active, but beyond
+ * that validity is specific to the algorithm).
+ * \retval #PSA_ERROR_BAD_STATE
+ * The state of \p output is not valid for
+ * the #PSA_KEY_DERIVATION_INPUT_SECRET step. This can happen if the
+ * step is out of order or the application has done this step already
+ * and it may not be repeated.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * #PSA_KEY_DERIVATION_INPUT_SECRET is not compatible with the output’s
+ * algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_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_pake_get_implicit_key(psa_pake_operation_t *operation,
+ psa_key_derivation_operation_t *output);
+
+/**@}*/
+
+/** A sufficient output buffer size for psa_pake_output().
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_pake_output() will not fail due to an insufficient output buffer
+ * size. The actual size of the output might be smaller in any given call.
+ *
+ * See also #PSA_PAKE_OUTPUT_MAX_SIZE
+ *
+ * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive A primitive of type ::psa_pake_primitive_t that is
+ * compatible with algorithm \p alg.
+ * \param output_step A value of type ::psa_pake_step_t that is valid for the
+ * algorithm \p alg.
+ * \return A sufficient output buffer size for the specified
+ * output, cipher suite and algorithm. If the cipher suite,
+ * the output type or PAKE algorithm is not recognized, or
+ * the parameters are incompatible, return 0.
+ */
+#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) 0
+
+/** A sufficient input buffer size for psa_pake_input().
+ *
+ * The value returned by this macro is guaranteed to be large enough for any
+ * valid input to psa_pake_input() in an operation with the specified
+ * parameters.
+ *
+ * See also #PSA_PAKE_INPUT_MAX_SIZE
+ *
+ * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive A primitive of type ::psa_pake_primitive_t that is
+ * compatible with algorithm \p alg.
+ * \param input_step A value of type ::psa_pake_step_t that is valid for the
+ * algorithm \p alg.
+ * \return A sufficient input buffer size for the specified
+ * input, cipher suite and algorithm. If the cipher suite,
+ * the input type or PAKE algorithm is not recognized, or
+ * the parameters are incompatible, return 0.
+ */
+#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) 0
+
+/** Output buffer size for psa_pake_output() for any of the supported cipher
+ * suites and PAKE algorithms.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p cipher_suite, \p output).
+ */
+#define PSA_PAKE_OUTPUT_MAX_SIZE 0
+
+/** Input buffer size for psa_pake_input() for any of the supported cipher
+ * suites and PAKE algorithms.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p cipher_suite, \p input).
+ */
+#define PSA_PAKE_INPUT_MAX_SIZE 0
+
+struct psa_pake_cipher_suite_s
+{
+ psa_algorithm_t algorithm;
+ psa_pake_primitive_type_t type;
+ psa_pake_family_t family;
+ uint16_t bits;
+ psa_algorithm_t hash;
+};
+
+static inline psa_algorithm_t psa_pake_cs_get_algorithm(
+ const psa_pake_cipher_suite_t *cipher_suite)
+{
+ return(cipher_suite->algorithm);
+}
+
+static inline void psa_pake_cs_set_algorithm(
+ psa_pake_cipher_suite_t *cipher_suite,
+ psa_algorithm_t algorithm)
+{
+ if(!PSA_ALG_IS_PAKE(algorithm))
+ cipher_suite->algorithm = 0;
+ else
+ cipher_suite->algorithm = algorithm;
+}
+
+static inline psa_pake_primitive_t psa_pake_cs_get_primitive(
+ const psa_pake_cipher_suite_t *cipher_suite)
+{
+ return(PSA_PAKE_PRIMITIVE(cipher_suite->type, cipher_suite->family,
+ cipher_suite->bits));
+}
+
+static inline void psa_pake_cs_set_primitive(
+ psa_pake_cipher_suite_t *cipher_suite,
+ psa_pake_primitive_t primitive)
+{
+ cipher_suite->type = (psa_pake_primitive_type_t) (primitive >> 24);
+ cipher_suite->family = (psa_pake_family_t) (0xFF & (primitive >> 16));
+ cipher_suite->bits = (uint16_t) (0xFFFF & primitive);
+}
+
+static inline psa_algorithm_t psa_pake_cs_get_hash(
+ const psa_pake_cipher_suite_t *cipher_suite)
+{
+ return(cipher_suite->hash);
+}
+
+static inline void psa_pake_cs_set_hash(
+ psa_pake_cipher_suite_t *cipher_suite,
+ psa_algorithm_t hash)
+{
+ if(!PSA_ALG_IS_HASH(hash))
+ cipher_suite->hash = 0;
+ else
+ cipher_suite->hash = hash;
+}
+
+struct psa_pake_operation_s
+{
+ psa_algorithm_t alg;
+ union
+ {
+ /* Make the union non-empty even with no supported algorithms. */
+ uint8_t dummy;
+ } ctx;
+};
+
+/* This only zeroes out the first byte in the union, the rest is unspecified. */
+#define PSA_PAKE_OPERATION_INIT {0, {0}}
+static inline struct psa_pake_operation_s psa_pake_operation_init(void)
+{
+ const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT;
+ return(v);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 598a9a7..0afdf84 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -93,7 +93,7 @@
psa_driver_hash_context_t MBEDTLS_PRIVATE(ctx);
};
-#define PSA_HASH_OPERATION_INIT {0, {0}}
+#define PSA_HASH_OPERATION_INIT { 0, { 0 } }
static inline struct psa_hash_operation_s psa_hash_operation_init( void )
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
@@ -118,7 +118,7 @@
psa_driver_cipher_context_t MBEDTLS_PRIVATE(ctx);
};
-#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, {0}}
+#define PSA_CIPHER_OPERATION_INIT { 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;
@@ -143,7 +143,7 @@
psa_driver_mac_context_t MBEDTLS_PRIVATE(ctx);
};
-#define PSA_MAC_OPERATION_INIT {0, 0, 0, {0}}
+#define PSA_MAC_OPERATION_INIT { 0, 0, 0, { 0 } }
static inline struct psa_mac_operation_s psa_mac_operation_init( void )
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
@@ -164,7 +164,7 @@
} MBEDTLS_PRIVATE(ctx);
};
-#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, {0}}
+#define PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, 0, { 0 } }
static inline struct psa_aead_operation_s psa_aead_operation_init( void )
{
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
@@ -224,7 +224,7 @@
uint8_t MBEDTLS_PRIVATE(Ai)[PSA_HASH_MAX_SIZE];
- /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
+ /* `HMAC_hash( prk, A( i ) + seed )` in the notation of RFC 5246, Sect. 5. */
uint8_t MBEDTLS_PRIVATE(output_block)[PSA_HASH_MAX_SIZE];
} psa_tls12_prf_key_derivation_t;
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
@@ -250,8 +250,9 @@
};
/* This only zeroes out the first byte in the union, the rest is unspecified. */
-#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, 0, {0}}
-static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
+#define PSA_KEY_DERIVATION_OPERATION_INIT { 0, 0, 0, { 0 } }
+static inline struct psa_key_derivation_s psa_key_derivation_operation_init(
+ void )
{
const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
return( v );
@@ -265,7 +266,7 @@
};
typedef struct psa_key_policy_s psa_key_policy_t;
-#define PSA_KEY_POLICY_INIT {0, 0, 0}
+#define PSA_KEY_POLICY_INIT { 0, 0, 0 }
static inline struct psa_key_policy_s psa_key_policy_init( void )
{
const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
@@ -277,7 +278,7 @@
typedef uint16_t psa_key_bits_t;
/* The maximum value of the type used to represent bit-sizes.
* This is used to mark an invalid key size. */
-#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
+#define PSA_KEY_BITS_TOO_LARGE ( ( psa_key_bits_t ) -1 )
/* The maximum size of a key in bits.
* Currently defined as the maximum that can be represented, rounded down
* to a whole number of bytes.
@@ -318,7 +319,10 @@
psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags);
} psa_core_key_attributes_t;
-#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}
+#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
{
@@ -331,9 +335,9 @@
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
+#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0 }
#else
-#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
+#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0 }
#endif
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
@@ -359,7 +363,7 @@
}
static inline mbedtls_svc_key_id_t psa_get_key_id(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) );
}
@@ -372,8 +376,8 @@
}
#endif
-static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
- psa_key_lifetime_t lifetime)
+static inline void psa_set_key_lifetime( psa_key_attributes_t *attributes,
+ psa_key_lifetime_t lifetime )
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime;
if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
@@ -387,44 +391,44 @@
}
static inline psa_key_lifetime_t psa_get_key_lifetime(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) );
}
-static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
- psa_key_usage_t usage_flags)
+static inline void psa_set_key_usage_flags( psa_key_attributes_t *attributes,
+ psa_key_usage_t usage_flags )
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) );
}
-static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
- psa_algorithm_t alg)
+static inline void psa_set_key_algorithm( psa_key_attributes_t *attributes,
+ psa_algorithm_t alg )
{
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) );
}
/* This function is declared in crypto_extra.h, which comes after this
* header file, but we need the function here, so repeat the declaration. */
-psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
+psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes,
psa_key_type_t type,
const uint8_t *data,
- size_t data_length);
+ size_t data_length );
-static inline void psa_set_key_type(psa_key_attributes_t *attributes,
- psa_key_type_t type)
+static inline void psa_set_key_type( psa_key_attributes_t *attributes,
+ psa_key_type_t type )
{
if( attributes->MBEDTLS_PRIVATE(domain_parameters) == NULL )
{
@@ -442,13 +446,13 @@
}
static inline psa_key_type_t psa_get_key_type(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) );
}
-static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
- size_t bits)
+static inline void psa_set_key_bits( psa_key_attributes_t *attributes,
+ size_t bits )
{
if( bits > PSA_MAX_KEY_BITS )
attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
@@ -457,7 +461,7 @@
}
static inline size_t psa_get_key_bits(
- const psa_key_attributes_t *attributes)
+ const psa_key_attributes_t *attributes )
{
return( attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) );
}