Merge branch 'opaque_psk_implementation' into development-psa-proposed

This commit is contained in:
Hanno Becker 2018-11-23 11:12:38 +00:00
commit 485529952f
8 changed files with 1198 additions and 179 deletions

View file

@ -65,6 +65,10 @@
#include "platform_time.h" #include "platform_time.h"
#endif #endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* /*
* SSL Error codes * SSL Error codes
*/ */
@ -923,19 +927,37 @@ struct mbedtls_ssl_config
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
unsigned char *psk; /*!< pre-shared key. This field should
only be set via #if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_ssl_conf_psk() */ psa_key_slot_t psk_opaque; /*!< PSA key slot holding opaque PSK.
size_t psk_len; /*!< length of the pre-shared key. This * This field should only be set via
field should only be set via * mbedtls_ssl_conf_psk_opaque().
mbedtls_ssl_conf_psk() */ * If either no PSK or a raw PSK have
unsigned char *psk_identity; /*!< identity for PSK negotiation. This * been configured, this has value \c 0. */
field should only be set via #endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ssl_conf_psk() */
size_t psk_identity_len;/*!< length of identity. This field should unsigned char *psk; /*!< The raw pre-shared key. This field should
only be set via * only be set via mbedtls_ssl_conf_psk().
mbedtls_ssl_conf_psk() */ * If either no PSK or an opaque PSK
#endif * have been configured, this has value NULL. */
size_t psk_len; /*!< The length of the raw pre-shared key.
* This field should only be set via
* mbedtls_ssl_conf_psk().
* Its value is non-zero if and only if
* \c psk is not \c NULL. */
unsigned char *psk_identity; /*!< The PSK identity for PSK negotiation.
* This field should only be set via
* mbedtls_ssl_conf_psk().
* This is set if and only if either
* \c psk or \c psk_opaque are set. */
size_t psk_identity_len;/*!< The length of PSK identity.
* This field should only be set via
* mbedtls_ssl_conf_psk().
* Its value is non-zero if and only if
* \c psk is not \c NULL or \c psk_opaque
* is not \c 0. */
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
const char **alpn_list; /*!< ordered list of protocols */ const char **alpn_list; /*!< ordered list of protocols */
@ -2057,68 +2079,146 @@ int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
/** /**
* \brief Set the Pre Shared Key (PSK) and the expected identity name * \brief Configure a pre-shared key (PSK) and identity
* to be used in PSK-based ciphersuites.
* *
* \note This is mainly useful for clients. Servers will usually * \note This is mainly useful for clients. Servers will usually
* want to use \c mbedtls_ssl_conf_psk_cb() instead. * want to use \c mbedtls_ssl_conf_psk_cb() instead.
* *
* \note Currently clients can only register one pre-shared key. * \warning Currently, clients can only register a single pre-shared key.
* In other words, the servers' identity hint is ignored. * Calling this function or mbedtls_ssl_conf_psk_opaque() more
* than once will overwrite values configured in previous calls.
* Support for setting multiple PSKs on clients and selecting * Support for setting multiple PSKs on clients and selecting
* one based on the identity hint is not a planned feature but * one based on the identity hint is not a planned feature,
* feedback is welcomed. * but feedback is welcomed.
* *
* \param conf SSL configuration * \param conf The SSL configuration to register the PSK with.
* \param psk pointer to the pre-shared key * \param psk The pointer to the pre-shared key to use.
* \param psk_len pre-shared key length * \param psk_len The length of the pre-shared key in bytes.
* \param psk_identity pointer to the pre-shared key identity * \param psk_identity The pointer to the pre-shared key identity.
* \param psk_identity_len identity key length * \param psk_identity_len The length of the pre-shared key identity
* in bytes.
* *
* \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED * \note The PSK and its identity are copied internally and
* hence need not be preserved by the caller for the lifetime
* of the SSL configuration.
*
* \return \c 0 if successful.
* \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/ */
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len, const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len ); const unsigned char *psk_identity, size_t psk_identity_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Configure an opaque pre-shared key (PSK) and identity
* to be used in PSK-based ciphersuites.
*
* \note This is mainly useful for clients. Servers will usually
* want to use \c mbedtls_ssl_conf_psk_cb() instead.
*
* \warning Currently, clients can only register a single pre-shared key.
* Calling this function or mbedtls_ssl_conf_psk() more than
* once will overwrite values configured in previous calls.
* Support for setting multiple PSKs on clients and selecting
* one based on the identity hint is not a planned feature,
* but feedback is welcomed.
*
* \param conf The SSL configuration to register the PSK with.
* \param psk The identifier of the key slot holding the PSK.
* Until \p conf is destroyed or this function is successfully
* called again, the key slot \p psk must be populated with a
* key of type #PSA_ALG_CATEGORY_KEY_DERIVATION whose policy
* allows its use for the key derivation algorithm applied
* in the handshake.
* \param psk_identity The pointer to the pre-shared key identity.
* \param psk_identity_len The length of the pre-shared key identity
* in bytes.
*
* \note The PSK identity hint is copied internally and hence need
* not be preserved by the caller for the lifetime of the
* SSL configuration.
*
* \return \c 0 if successful.
* \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/
int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
psa_key_slot_t psk,
const unsigned char *psk_identity,
size_t psk_identity_len );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/** /**
* \brief Set the Pre Shared Key (PSK) for the current handshake * \brief Set the pre-shared Key (PSK) for the current handshake.
* *
* \note This should only be called inside the PSK callback, * \note This should only be called inside the PSK callback,
* ie the function passed to \c mbedtls_ssl_conf_psk_cb(). * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
* *
* \param ssl SSL context * \param ssl The SSL context to configure a PSK for.
* \param psk pointer to the pre-shared key * \param psk The pointer to the pre-shared key.
* \param psk_len pre-shared key length * \param psk_len The length of the pre-shared key in bytes.
* *
* \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED * \return \c 0 if successful.
* \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/ */
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
const unsigned char *psk, size_t psk_len ); const unsigned char *psk, size_t psk_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/**
* \brief Set an opaque pre-shared Key (PSK) for the current handshake.
*
* \note This should only be called inside the PSK callback,
* i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
*
* \param ssl The SSL context to configure a PSK for.
* \param psk The identifier of the key slot holding the PSK.
* For the duration of the current handshake, the key slot
* must be populated with a key of type
* #PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its
* use for the key derivation algorithm
* applied in the handshake.
*
* \return \c 0 if successful.
* \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/
int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
psa_key_slot_t psk );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/** /**
* \brief Set the PSK callback (server-side only). * \brief Set the PSK callback (server-side only).
* *
* If set, the PSK callback is called for each * If set, the PSK callback is called for each
* handshake where a PSK ciphersuite was negotiated. * handshake where a PSK-based ciphersuite was negotiated.
* The caller provides the identity received and wants to * The caller provides the identity received and wants to
* receive the actual PSK data and length. * receive the actual PSK data and length.
* *
* The callback has the following parameters: (void *parameter, * The callback has the following parameters:
* mbedtls_ssl_context *ssl, const unsigned char *psk_identity, * - \c void*: The opaque pointer \p p_psk.
* size_t identity_len) * - \c mbedtls_ssl_context*: The SSL context to which
* the operation applies.
* - \c const unsigned char*: The PSK identity
* selected by the client.
* - \c size_t: The length of the PSK identity
* selected by the client.
*
* If a valid PSK identity is found, the callback should use * If a valid PSK identity is found, the callback should use
* \c mbedtls_ssl_set_hs_psk() on the ssl context to set the * \c mbedtls_ssl_set_hs_psk() or
* correct PSK and return 0. * \c mbedtls_ssl_set_hs_psk_opaque()
* on the SSL context to set the correct PSK and return \c 0.
* Any other return value will result in a denied PSK identity. * Any other return value will result in a denied PSK identity.
* *
* \note If you set a PSK callback using this function, then you * \note If you set a PSK callback using this function, then you
* don't need to set a PSK key and identity using * don't need to set a PSK key and identity using
* \c mbedtls_ssl_conf_psk(). * \c mbedtls_ssl_conf_psk().
* *
* \param conf SSL configuration * \param conf The SSL configuration to register the callback with.
* \param f_psk PSK identity function * \param f_psk The callback for selecting and setting the PSK based
* \param p_psk PSK identity parameter * in the PSK identity chosen by the client.
* \param p_psk A pointer to an opaque structure to be passed to
* the callback, for example a PSK store.
*/ */
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,

View file

@ -283,9 +283,12 @@ struct mbedtls_ssl_handshake_params
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_key_slot_t psk_opaque; /*!< Opaque PSK from the callback */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
unsigned char *psk; /*!< PSK from the callback */ unsigned char *psk; /*!< PSK from the callback */
size_t psk_len; /*!< Length of PSK from callback */ size_t psk_len; /*!< Length of PSK from callback */
#endif #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)

View file

@ -51,6 +51,44 @@
#include "mbedtls/platform_util.h" #include "mbedtls/platform_util.h"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
{
if( conf->psk_identity == NULL ||
conf->psk_identity_len == 0 )
{
return( 0 );
}
if( conf->psk != NULL && conf->psk_len != 0 )
return( 1 );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( conf->psk_opaque != 0 )
return( 1 );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return( 0 );
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
{
if( conf->psk_identity == NULL ||
conf->psk_identity_len == 0 )
{
return( 0 );
}
if( conf->psk != NULL && conf->psk_len != 0 )
return( 1 );
return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
@ -754,6 +792,15 @@ static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_inf
return( 1 ); return( 1 );
#endif #endif
/* Don't suggest PSK-based ciphersuite if no PSK is available. */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
ssl_conf_has_static_psk( ssl->conf ) == 0 )
{
return( 1 );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
return( 0 ); return( 0 );
} }
@ -3007,10 +3054,12 @@ ecdh_calc_secret:
/* /*
* opaque psk_identity<0..2^16-1>; * opaque psk_identity<0..2^16-1>;
*/ */
if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ) if( ssl_conf_has_static_psk( ssl->conf ) == 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) ); /* We don't offer PSK suites if we don't have a PSK,
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); * and we check that the server's choice is among the
* ciphersuites we offered, so this should never happen. */
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
i = 4; i = 4;
@ -3039,6 +3088,12 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
return( ret ); return( ret );
} }
@ -3047,6 +3102,12 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* /*
* ClientDiffieHellmanPublic public (DHM send G^X mod P) * ClientDiffieHellmanPublic public (DHM send G^X mod P)
*/ */
@ -3077,6 +3138,12 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only suites. */
if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* /*
* ClientECDiffieHellmanPublic public; * ClientECDiffieHellmanPublic public;
*/ */
@ -3098,6 +3165,17 @@ ecdh_calc_secret:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 ) ciphersuite_info->key_exchange ) ) != 0 )
{ {

View file

@ -149,6 +149,48 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
{
if( conf->f_psk != NULL )
return( 1 );
if( conf->psk_identity_len == 0 || conf->psk_identity == NULL )
return( 0 );
if( conf->psk != NULL && conf->psk_len != 0 )
return( 1 );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( conf->psk_opaque != 0 )
return( 1 );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return( 0 );
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
if( ssl->conf->f_psk != NULL )
{
/* If we've used a callback to select the PSK,
* the static configuration is irrelevant. */
if( ssl->handshake->psk_opaque != 0 )
return( 1 );
return( 0 );
}
if( ssl->conf->psk_opaque != 0 )
return( 1 );
return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -867,9 +909,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
/* If the ciphersuite requires a pre-shared key and we don't /* If the ciphersuite requires a pre-shared key and we don't
* have one, skip it now rather than failing later */ * have one, skip it now rather than failing later */
if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
ssl->conf->f_psk == NULL && ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
return( 0 ); return( 0 );
@ -3648,9 +3688,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
int ret = 0; int ret = 0;
size_t n; size_t n;
if( ssl->conf->f_psk == NULL && if( ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
@ -3828,6 +3866,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
* and skip the intermediate PMS. */
if( ssl_use_opaque_psk( ssl ) == 1 )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 ) ciphersuite_info->key_exchange ) ) != 0 )
{ {
@ -3859,6 +3904,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
@ -3888,6 +3939,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif
if( p != end ) if( p != end )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
@ -3919,6 +3976,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Opaque PSKs are currently only supported for PSK-only. */
if( ssl_use_opaque_psk( ssl ) == 1 )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,

View file

@ -607,6 +607,28 @@ static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *
#endif #endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
if( ssl->conf->f_psk != NULL )
{
/* If we've used a callback to select the PSK,
* the static configuration is irrelevant. */
if( ssl->handshake->psk_opaque != 0 )
return( 1 );
return( 0 );
}
if( ssl->conf->psk_opaque != 0 )
return( 1 );
return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
{ {
int ret = 0; int ret = 0;
@ -621,6 +643,14 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
/* cf. RFC 5246, Section 8.1:
* "The master secret is always exactly 48 bytes in length." */
size_t const master_secret_len = 48;
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
unsigned char session_hash[48];
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
mbedtls_ssl_session *session = ssl->session_negotiate; mbedtls_ssl_session *session = ssl->session_negotiate;
mbedtls_ssl_transform *transform = ssl->transform_negotiate; mbedtls_ssl_transform *transform = ssl->transform_negotiate;
mbedtls_ssl_handshake_params *handshake = ssl->handshake; mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@ -700,68 +730,127 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* TLSv1+: * TLSv1+:
* master = PRF( premaster, "master secret", randbytes )[0..47] * master = PRF( premaster, "master secret", randbytes )[0..47]
*/ */
if( handshake->resume == 0 ) if( handshake->resume != 0 )
{ {
MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
handshake->pmslen ); }
else
{
/* The label for the KDF used for key expansion.
* This is either "master secret" or "extended master secret"
* depending on whether the Extended Master Secret extension
* is used. */
char const *lbl = "master secret";
/* The salt for the KDF used for key expansion.
* - If the Extended Master Secret extension is not used,
* this is ClientHello.Random + ServerHello.Random
* (see Sect. 8.1 in RFC 5246).
* - If the Extended Master Secret extension is used,
* this is the transcript of the handshake so far.
* (see Sect. 4 in RFC 7627). */
unsigned char const *salt = handshake->randbytes;
size_t salt_len = 64;
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
mbedtls_md_type_t const md_type = ciphersuite_info->mac;
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
{ {
unsigned char session_hash[48];
size_t hash_len;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
lbl = "extended master secret";
salt = session_hash;
ssl->handshake->calc_verify( ssl, session_hash ); ssl->handshake->calc_verify( ssl, session_hash );
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{ {
#if defined(MBEDTLS_SHA512_C) #if defined(MBEDTLS_SHA512_C)
if( ssl->transform_negotiate->ciphersuite_info->mac == if( md_type == MBEDTLS_MD_SHA384 )
MBEDTLS_MD_SHA384 ) salt_len = 48;
{
hash_len = 48;
}
else else
#endif #endif /* MBEDTLS_SHA512_C */
hash_len = 32; salt_len = 32;
} }
else else
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
hash_len = 36; salt_len = 36;
MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len ); MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, salt_len );
}
#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
ssl_use_opaque_psk( ssl ) == 1 )
{
/* Perform PSK-to-MS expansion in a single step. */
psa_status_t status;
psa_algorithm_t alg;
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
psa_key_slot_t psk;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
psk = ssl->conf->psk_opaque;
if( ssl->handshake->psk_opaque != 0 )
psk = ssl->handshake->psk_opaque;
if( md_type == MBEDTLS_MD_SHA384 )
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
else
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
status = psa_key_derivation( &generator, psk, alg,
salt, salt_len,
(unsigned char const *) lbl,
(size_t) strlen( lbl ),
master_secret_len );
if( status != PSA_SUCCESS )
{
psa_generator_abort( &generator );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_generator_read( &generator, session->master,
master_secret_len );
if( status != PSA_SUCCESS )
{
psa_generator_abort( &generator );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_generator_abort( &generator );
if( status != PSA_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
else
#endif
{
ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
"extended master secret", lbl, salt, salt_len,
session_hash, hash_len, session->master,
session->master, 48 ); master_secret_len );
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
return( ret ); return( ret );
} }
} MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
else handshake->premaster,
#endif handshake->pmslen );
ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
"master secret",
handshake->randbytes, 64,
session->master, 48 );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
return( ret );
}
mbedtls_platform_zeroize( handshake->premaster, mbedtls_platform_zeroize( handshake->premaster,
sizeof(handshake->premaster) ); sizeof(handshake->premaster) );
}
} }
else
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
/* /*
* Swap the client and server random values. * Swap the client and server random values.
@ -7326,23 +7415,23 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len, static void ssl_conf_remove_psk( mbedtls_ssl_config *conf )
const unsigned char *psk_identity, size_t psk_identity_len )
{ {
if( psk == NULL || psk_identity == NULL ) /* Remove reference to existing PSK, if any. */
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); #if defined(MBEDTLS_USE_PSA_CRYPTO)
if( conf->psk_opaque != 0 )
if( psk_len > MBEDTLS_PSK_MAX_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
/* Identity len will be encoded on two bytes */
if( ( psk_identity_len >> 16 ) != 0 ||
psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{ {
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); /* The maintenance of the PSK key slot is the
* user's responsibility. */
conf->psk_opaque = 0;
} }
/* This and the following branch should never
* be taken simultaenously as we maintain the
* invariant that raw and opaque PSKs are never
* configured simultaneously. As a safeguard,
* though, `else` is omitted here. */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( conf->psk != NULL ) if( conf->psk != NULL )
{ {
mbedtls_platform_zeroize( conf->psk, conf->psk_len ); mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@ -7351,32 +7440,84 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
conf->psk = NULL; conf->psk = NULL;
conf->psk_len = 0; conf->psk_len = 0;
} }
/* Remove reference to PSK identity, if any. */
if( conf->psk_identity != NULL ) if( conf->psk_identity != NULL )
{ {
mbedtls_free( conf->psk_identity ); mbedtls_free( conf->psk_identity );
conf->psk_identity = NULL; conf->psk_identity = NULL;
conf->psk_identity_len = 0; conf->psk_identity_len = 0;
} }
}
if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || /* This function assumes that PSK identity in the SSL config is unset.
( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) * It checks that the provided identity is well-formed and attempts
* to make a copy of it in the SSL config.
* On failure, the PSK identity in the config remains unset. */
static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
unsigned char const *psk_identity,
size_t psk_identity_len )
{
/* Identity len will be encoded on two bytes */
if( psk_identity == NULL ||
( psk_identity_len >> 16 ) != 0 ||
psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{ {
mbedtls_free( conf->psk ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
mbedtls_free( conf->psk_identity );
conf->psk = NULL;
conf->psk_identity = NULL;
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
} }
conf->psk_len = psk_len; conf->psk_identity = mbedtls_calloc( 1, psk_identity_len );
conf->psk_identity_len = psk_identity_len; if( conf->psk_identity == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
memcpy( conf->psk, psk, conf->psk_len ); conf->psk_identity_len = psk_identity_len;
memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
return( 0 ); return( 0 );
} }
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len )
{
int ret;
/* Remove opaque/raw PSK + PSK Identity */
ssl_conf_remove_psk( conf );
/* Check and set raw PSK */
if( psk == NULL || psk_len > MBEDTLS_PSK_MAX_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
conf->psk_len = psk_len;
memcpy( conf->psk, psk, conf->psk_len );
/* Check and set PSK Identity */
ret = ssl_conf_set_psk_identity( conf, psk_identity, psk_identity_len );
if( ret != 0 )
ssl_conf_remove_psk( conf );
return( ret );
}
static void ssl_remove_psk( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( ssl->handshake->psk_opaque != 0 )
{
ssl->handshake->psk_opaque = 0;
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ssl->handshake->psk != NULL )
{
mbedtls_platform_zeroize( ssl->handshake->psk,
ssl->handshake->psk_len );
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk_len = 0;
}
}
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
const unsigned char *psk, size_t psk_len ) const unsigned char *psk, size_t psk_len )
{ {
@ -7386,13 +7527,7 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
if( psk_len > MBEDTLS_PSK_MAX_LEN ) if( psk_len > MBEDTLS_PSK_MAX_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->handshake->psk != NULL ) ssl_remove_psk( ssl );
{
mbedtls_platform_zeroize( ssl->handshake->psk,
ssl->handshake->psk_len );
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk_len = 0;
}
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
@ -7403,6 +7538,42 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
return( 0 ); return( 0 );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
psa_key_slot_t psk_slot,
const unsigned char *psk_identity,
size_t psk_identity_len )
{
int ret;
/* Clear opaque/raw PSK + PSK Identity, if present. */
ssl_conf_remove_psk( conf );
/* Check and set opaque PSK */
if( psk_slot == 0 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
conf->psk_opaque = psk_slot;
/* Check and set PSK Identity */
ret = ssl_conf_set_psk_identity( conf, psk_identity,
psk_identity_len );
if( ret != 0 )
ssl_conf_remove_psk( conf );
return( ret );
}
int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
psa_key_slot_t psk_slot )
{
if( psk_slot == 0 || ssl->handshake == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
ssl_remove_psk( ssl );
ssl->handshake->psk_opaque = psk_slot;
return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
size_t), size_t),

View file

@ -61,6 +61,7 @@ int main( void )
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h" #include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -86,6 +87,7 @@ int main( void )
#define DFL_KEY_FILE "" #define DFL_KEY_FILE ""
#define DFL_KEY_OPAQUE 0 #define DFL_KEY_OPAQUE 0
#define DFL_PSK "" #define DFL_PSK ""
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL #define DFL_ECJPAKE_PW NULL
#define DFL_EC_MAX_OPS -1 #define DFL_EC_MAX_OPS -1
@ -147,9 +149,24 @@ int main( void )
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#define USAGE_PSK \ #define USAGE_PSK_RAW \
" psk=%%s default: \"\" (in hex, without 0x)\n" \ " psk=%%s default: \"\" (in hex, without 0x)\n" \
" psk_identity=%%s default: \"Client_identity\"\n" " psk_identity=%%s default: \"Client_identity\"\n"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#define USAGE_PSK_SLOT \
" psk_opaque=%%d default: 0 (don't use opaque static PSK)\n" \
" Enable this to store the PSK configured through command line\n" \
" parameter `psk` in a PSA-based key slot.\n" \
" Note: Currently only supported in conjunction with\n" \
" the use of min_version to force TLS 1.2 and force_ciphersuite \n" \
" to force a particular PSK-only ciphersuite.\n" \
" Note: This is to test integration of PSA-based opaque PSKs with\n" \
" Mbed TLS only. Production systems are likely to configure Mbed TLS\n" \
" with prepopulated key slots instead of importing raw key material.\n"
#else
#define USAGE_PSK_SLOT ""
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#define USAGE_PSK USAGE_PSK_RAW USAGE_PSK_SLOT
#else #else
#define USAGE_PSK "" #define USAGE_PSK ""
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
@ -347,6 +364,9 @@ struct options
const char *crt_file; /* the file with the client certificate */ const char *crt_file; /* the file with the client certificate */
const char *key_file; /* the file with the client key */ const char *key_file; /* the file with the client key */
int key_opaque; /* handle private key as if it were opaque */ int key_opaque; /* handle private key as if it were opaque */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int psk_opaque;
#endif
const char *psk; /* the pre-shared key */ const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
const char *ecjpake_pw; /* the EC J-PAKE password */ const char *ecjpake_pw; /* the EC J-PAKE password */
@ -550,6 +570,13 @@ int main( int argc, char *argv[] )
const char *pers = "ssl_client2"; const char *pers = "ssl_client2";
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_key_slot_t slot = 0;
psa_algorithm_t alg = 0;
psa_key_policy_t policy;
psa_status_t status;
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
#endif #endif
@ -572,9 +599,6 @@ int main( int argc, char *argv[] )
#endif #endif
char *p, *q; char *p, *q;
const int *list; const int *list;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status;
#endif
/* /*
* Make sure memory references are valid. * Make sure memory references are valid.
@ -642,6 +666,9 @@ int main( int argc, char *argv[] )
opt.key_file = DFL_KEY_FILE; opt.key_file = DFL_KEY_FILE;
opt.key_opaque = DFL_KEY_OPAQUE; opt.key_opaque = DFL_KEY_OPAQUE;
opt.psk = DFL_PSK; opt.psk = DFL_PSK;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
opt.psk_opaque = DFL_PSK_OPAQUE;
#endif
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.ecjpake_pw = DFL_ECJPAKE_PW; opt.ecjpake_pw = DFL_ECJPAKE_PW;
opt.ec_max_ops = DFL_EC_MAX_OPS; opt.ec_max_ops = DFL_EC_MAX_OPS;
@ -746,6 +773,10 @@ int main( int argc, char *argv[] )
#endif #endif
else if( strcmp( p, "psk" ) == 0 ) else if( strcmp( p, "psk" ) == 0 )
opt.psk = q; opt.psk = q;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
else if( strcmp( p, "psk_opaque" ) == 0 )
opt.psk_opaque = atoi( q );
#endif
else if( strcmp( p, "psk_identity" ) == 0 ) else if( strcmp( p, "psk_identity" ) == 0 )
opt.psk_identity = q; opt.psk_identity = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 ) else if( strcmp( p, "ecjpake_pw" ) == 0 )
@ -1030,57 +1061,6 @@ int main( int argc, char *argv[] )
mbedtls_debug_set_threshold( opt.debug_level ); mbedtls_debug_set_threshold( opt.debug_level );
#endif #endif
if( opt.force_ciphersuite[0] > 0 )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
ciphersuite_info =
mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
if( opt.max_version != -1 &&
ciphersuite_info->min_minor_ver > opt.max_version )
{
mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
ret = 2;
goto usage;
}
if( opt.min_version != -1 &&
ciphersuite_info->max_minor_ver < opt.min_version )
{
mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
ret = 2;
goto usage;
}
/* If the server selects a version that's not supported by
* this suite, then there will be no common ciphersuite... */
if( opt.max_version == -1 ||
opt.max_version > ciphersuite_info->max_minor_ver )
{
opt.max_version = ciphersuite_info->max_minor_ver;
}
if( opt.min_version < ciphersuite_info->min_minor_ver )
{
opt.min_version = ciphersuite_info->min_minor_ver;
/* DTLS starts with TLS 1.1 */
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
}
/* Enable RC4 if needed and not explicitly disabled */
if( ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
{
if( opt.arc4 == MBEDTLS_SSL_ARC4_DISABLED )
{
mbedtls_printf( "forced RC4 ciphersuite with RC4 disabled\n" );
ret = 2;
goto usage;
}
opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
}
}
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
/* /*
* Unhexify the pre-shared key if any is given * Unhexify the pre-shared key if any is given
@ -1131,6 +1111,101 @@ int main( int argc, char *argv[] )
} }
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
if( opt.psk == NULL )
{
mbedtls_printf( "psk_opaque set but no psk to be imported specified.\n" );
ret = 2;
goto usage;
}
if( opt.force_ciphersuite[0] <= 0 )
{
mbedtls_printf( "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n" );
ret = 2;
goto usage;
}
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( opt.force_ciphersuite[0] > 0 )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
ciphersuite_info =
mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
if( opt.max_version != -1 &&
ciphersuite_info->min_minor_ver > opt.max_version )
{
mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
ret = 2;
goto usage;
}
if( opt.min_version != -1 &&
ciphersuite_info->max_minor_ver < opt.min_version )
{
mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
ret = 2;
goto usage;
}
/* If the server selects a version that's not supported by
* this suite, then there will be no common ciphersuite... */
if( opt.max_version == -1 ||
opt.max_version > ciphersuite_info->max_minor_ver )
{
opt.max_version = ciphersuite_info->max_minor_ver;
}
if( opt.min_version < ciphersuite_info->min_minor_ver )
{
opt.min_version = ciphersuite_info->min_minor_ver;
/* DTLS starts with TLS 1.1 */
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
}
/* Enable RC4 if needed and not explicitly disabled */
if( ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
{
if( opt.arc4 == MBEDTLS_SSL_ARC4_DISABLED )
{
mbedtls_printf( "forced RC4 ciphersuite with RC4 disabled\n" );
ret = 2;
goto usage;
}
opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
/* Ensure that the chosen ciphersuite is PSK-only; we must know
* the ciphersuite in advance to set the correct policy for the
* PSK key slot. This limitation might go away in the future. */
if( ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_PSK ||
opt.min_version != MBEDTLS_SSL_MINOR_VERSION_3 )
{
mbedtls_printf( "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n" );
ret = 2;
goto usage;
}
/* Determine KDF algorithm the opaque PSK will be used in. */
#if defined(MBEDTLS_SHA512_C)
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
else
#endif /* MBEDTLS_SHA512_C */
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
if( opt.curves != NULL ) if( opt.curves != NULL )
{ {
@ -1515,6 +1590,45 @@ int main( int argc, char *argv[] )
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
/* The algorithm has already been determined earlier. */
status = mbedtls_psa_get_free_key_slot( &slot );
if( status != PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
psa_key_policy_init( &policy );
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
status = psa_set_key_policy( slot, &policy );
if( status != PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
status = psa_import_key( slot, PSA_KEY_TYPE_DERIVE, psk, psk_len );
if( status != PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
if( ( ret = mbedtls_ssl_conf_psk_opaque( &conf, slot,
(const unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_psk_opaque returned %d\n\n",
ret );
goto exit;
}
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len, if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
(const unsigned char *) opt.psk_identity, (const unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) ) ) != 0 ) strlen( opt.psk_identity ) ) ) != 0 )
@ -1523,7 +1637,7 @@ int main( int argc, char *argv[] )
ret ); ret );
goto exit; goto exit;
} }
#endif #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
if( opt.min_version != DFL_MIN_VERSION ) if( opt.min_version != DFL_MIN_VERSION )
mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3,
@ -2157,6 +2271,26 @@ exit:
mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy ); mbedtls_entropy_free( &entropy );
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
/* This is ok even if the slot hasn't been
* initialized (we might have jumed here
* immediately because of bad cmd line params,
* for example). */
status = psa_destroy_key( slot );
if( status != PSA_SUCCESS )
{
mbedtls_printf( "Failed to destroy key slot %u - error was %d",
(unsigned) slot, (int) status );
if( ret == 0 )
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */
#if defined(_WIN32) #if defined(_WIN32)
mbedtls_printf( " + Press Enter to exit this program.\n" ); mbedtls_printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar(); fflush( stdout ); getchar();

View file

@ -62,6 +62,7 @@ int main( void )
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h" #include "psa/crypto.h"
#include "mbedtls/psa_util.h"
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -123,6 +124,8 @@ int main( void )
#define DFL_ASYNC_PRIVATE_DELAY2 ( -1 ) #define DFL_ASYNC_PRIVATE_DELAY2 ( -1 )
#define DFL_ASYNC_PRIVATE_ERROR ( 0 ) #define DFL_ASYNC_PRIVATE_ERROR ( 0 )
#define DFL_PSK "" #define DFL_PSK ""
#define DFL_PSK_OPAQUE 0
#define DFL_PSK_LIST_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL #define DFL_ECJPAKE_PW NULL
#define DFL_PSK_LIST NULL #define DFL_PSK_LIST NULL
@ -224,9 +227,36 @@ int main( void )
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#define USAGE_PSK \ #define USAGE_PSK_RAW \
" psk=%%s default: \"\" (in hex, without 0x)\n" \ " psk=%%s default: \"\" (in hex, without 0x)\n" \
" psk_identity=%%s default: \"Client_identity\"\n" " psk_identity=%%s default: \"Client_identity\"\n" \
" psk_list=%%s default: \"\"\n" \
" A list of (PSK identity, PSK value) pairs in (hex format, without 0x)\n" \
" id1,psk1[,id2,psk2[,...]]\n"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#define USAGE_PSK_SLOT \
" psk_opaque=%%d default: 0 (don't use opaque static PSK)\n" \
" Enable this to store the PSK configured through command line\n" \
" parameter `psk` in a PSA-based key slot.\n" \
" Note: Currently only supported in conjunction with\n" \
" the use of min_version to force TLS 1.2 and force_ciphersuite \n" \
" to force a particular PSK-only ciphersuite.\n" \
" Note: This is to test integration of PSA-based opaque PSKs with\n" \
" Mbed TLS only. Production systems are likely to configure Mbed TLS\n" \
" with prepopulated key slots instead of importing raw key material.\n" \
" psk_list_opaque=%%d default: 0 (don't use opaque dynamic PSKs)\n" \
" Enable this to store the list of dynamically chosen PSKs configured\n" \
" through the command line parameter `psk_list` in PSA-based key slots.\n" \
" Note: Currently only supported in conjunction with\n" \
" the use of min_version to force TLS 1.2 and force_ciphersuite \n" \
" to force a particular PSK-only ciphersuite.\n" \
" Note: This is to test integration of PSA-based opaque PSKs with\n" \
" Mbed TLS only. Production systems are likely to configure Mbed TLS\n" \
" with prepopulated key slots instead of importing raw key material.\n"
#else
#define USAGE_PSK_SLOT ""
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#define USAGE_PSK USAGE_PSK_RAW USAGE_PSK_SLOT
#else #else
#define USAGE_PSK "" #define USAGE_PSK ""
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
@ -453,6 +483,10 @@ struct options
int async_private_delay1; /* number of times f_async_resume needs to be called for key 1, or -1 for no async */ int async_private_delay1; /* number of times f_async_resume needs to be called for key 1, or -1 for no async */
int async_private_delay2; /* number of times f_async_resume needs to be called for key 2, or -1 for no async */ int async_private_delay2; /* number of times f_async_resume needs to be called for key 2, or -1 for no async */
int async_private_error; /* inject error in async private callback */ int async_private_error; /* inject error in async private callback */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int psk_opaque;
int psk_list_opaque;
#endif
const char *psk; /* the pre-shared key */ const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
char *psk_list; /* list of PSK id/key pairs for callback */ char *psk_list; /* list of PSK id/key pairs for callback */
@ -771,22 +805,39 @@ struct _psk_entry
const char *name; const char *name;
size_t key_len; size_t key_len;
unsigned char key[MBEDTLS_PSK_MAX_LEN]; unsigned char key[MBEDTLS_PSK_MAX_LEN];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_key_slot_t slot;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
psk_entry *next; psk_entry *next;
}; };
/* /*
* Free a list of psk_entry's * Free a list of psk_entry's
*/ */
void psk_free( psk_entry *head ) int psk_free( psk_entry *head )
{ {
psk_entry *next; psk_entry *next;
while( head != NULL ) while( head != NULL )
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status;
psa_key_slot_t const slot = head->slot;
if( slot != 0 )
{
status = psa_destroy_key( slot );
if( status != PSA_SUCCESS )
return( status );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
next = head->next; next = head->next;
mbedtls_free( head ); mbedtls_free( head );
head = next; head = next;
} }
return( 0 );
} }
/* /*
@ -844,6 +895,11 @@ int psk_callback( void *p_info, mbedtls_ssl_context *ssl,
if( name_len == strlen( cur->name ) && if( name_len == strlen( cur->name ) &&
memcmp( name, cur->name, name_len ) == 0 ) memcmp( name, cur->name, name_len ) == 0 )
{ {
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( cur->slot != 0 )
return( mbedtls_ssl_set_hs_psk_opaque( ssl, cur->slot ) );
else
#endif
return( mbedtls_ssl_set_hs_psk( ssl, cur->key, cur->key_len ) ); return( mbedtls_ssl_set_hs_psk( ssl, cur->key, cur->key_len ) );
} }
@ -1174,12 +1230,46 @@ int idle( mbedtls_net_context *fd,
return( 0 ); return( 0 );
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static psa_status_t psa_setup_psk_key_slot( psa_key_slot_t slot,
psa_algorithm_t alg,
unsigned char *psk,
size_t psk_len )
{
psa_status_t status;
psa_key_policy_t policy;
psa_key_policy_init( &policy );
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
status = psa_set_key_policy( slot, &policy );
if( status != PSA_SUCCESS )
{
fprintf( stderr, "POLICY\n" );
return( status );
}
status = psa_import_key( slot, PSA_KEY_TYPE_DERIVE, psk, psk_len );
if( status != PSA_SUCCESS )
{
fprintf( stderr, "IMPORT\n" );
return( status );
}
return( PSA_SUCCESS );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
int ret = 0, len, written, frags, exchanges_left; int ret = 0, len, written, frags, exchanges_left;
int version_suites[4][2]; int version_suites[4][2];
unsigned char* buf = 0; unsigned char* buf = 0;
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_algorithm_t alg = 0;
psa_key_slot_t psk_slot = 0;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
unsigned char psk[MBEDTLS_PSK_MAX_LEN]; unsigned char psk[MBEDTLS_PSK_MAX_LEN];
size_t psk_len = 0; size_t psk_len = 0;
psk_entry *psk_info = NULL; psk_entry *psk_info = NULL;
@ -1342,6 +1432,10 @@ int main( int argc, char *argv[] )
opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2; opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2;
opt.async_private_error = DFL_ASYNC_PRIVATE_ERROR; opt.async_private_error = DFL_ASYNC_PRIVATE_ERROR;
opt.psk = DFL_PSK; opt.psk = DFL_PSK;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
opt.psk_opaque = DFL_PSK_OPAQUE;
opt.psk_list_opaque = DFL_PSK_LIST_OPAQUE;
#endif
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.psk_list = DFL_PSK_LIST; opt.psk_list = DFL_PSK_LIST;
opt.ecjpake_pw = DFL_ECJPAKE_PW; opt.ecjpake_pw = DFL_ECJPAKE_PW;
@ -1470,6 +1564,12 @@ int main( int argc, char *argv[] )
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
else if( strcmp( p, "psk" ) == 0 ) else if( strcmp( p, "psk" ) == 0 )
opt.psk = q; opt.psk = q;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
else if( strcmp( p, "psk_opaque" ) == 0 )
opt.psk_opaque = atoi( q );
else if( strcmp( p, "psk_list_opaque" ) == 0 )
opt.psk_list_opaque = atoi( q );
#endif
else if( strcmp( p, "psk_identity" ) == 0 ) else if( strcmp( p, "psk_identity" ) == 0 )
opt.psk_identity = q; opt.psk_identity = q;
else if( strcmp( p, "psk_list" ) == 0 ) else if( strcmp( p, "psk_list" ) == 0 )
@ -1779,6 +1879,42 @@ int main( int argc, char *argv[] )
goto exit; goto exit;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
if( strlen( opt.psk ) == 0 )
{
mbedtls_printf( "psk_opaque set but no psk to be imported specified.\n" );
ret = 2;
goto usage;
}
if( opt.force_ciphersuite[0] <= 0 )
{
mbedtls_printf( "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n" );
ret = 2;
goto usage;
}
}
if( opt.psk_list_opaque != 0 )
{
if( opt.psk_list == NULL )
{
mbedtls_printf( "psk_slot set but no psk to be imported specified.\n" );
ret = 2;
goto usage;
}
if( opt.force_ciphersuite[0] <= 0 )
{
mbedtls_printf( "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n" );
ret = 2;
goto usage;
}
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( opt.force_ciphersuite[0] > 0 ) if( opt.force_ciphersuite[0] > 0 )
{ {
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
@ -1828,6 +1964,30 @@ int main( int argc, char *argv[] )
opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED; opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
} }
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 || opt.psk_list_opaque != 0 )
{
/* Ensure that the chosen ciphersuite is PSK-only; we must know
* the ciphersuite in advance to set the correct policy for the
* PSK key slot. This limitation might go away in the future. */
if( ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_PSK ||
opt.min_version != MBEDTLS_SSL_MINOR_VERSION_3 )
{
mbedtls_printf( "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n" );
ret = 2;
goto usage;
}
/* Determine KDF algorithm the opaque PSK will be used in. */
#if defined(MBEDTLS_SHA512_C)
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
else
#endif /* MBEDTLS_SHA512_C */
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
} }
if( opt.version_suites != NULL ) if( opt.version_suites != NULL )
@ -2501,12 +2661,42 @@ int main( int argc, char *argv[] )
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 ) if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 )
{ {
ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len, #if defined(MBEDTLS_USE_PSA_CRYPTO)
(const unsigned char *) opt.psk_identity, if( opt.psk_opaque != 0 )
strlen( opt.psk_identity ) ); {
if( ret != 0 ) status = mbedtls_psa_get_free_key_slot( &psk_slot );
if( status != PSA_SUCCESS )
{
fprintf( stderr, "ALLOC FAIL\n" );
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
/* The algorithm has already been determined earlier. */
status = psa_setup_psk_key_slot( psk_slot, alg, psk, psk_len );
if( status != PSA_SUCCESS )
{
fprintf( stderr, "SETUP FAIL\n" );
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
if( ( ret = mbedtls_ssl_conf_psk_opaque( &conf, psk_slot,
(const unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_psk_opaque returned %d\n\n",
ret );
goto exit;
}
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
(const unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) ) ) != 0 )
{ {
mbedtls_printf( " failed\n mbedtls_ssl_conf_psk returned -0x%04X\n\n", - ret ); mbedtls_printf( " failed\n mbedtls_ssl_conf_psk returned -0x%04X\n\n", - ret );
goto exit; goto exit;
@ -2514,7 +2704,34 @@ int main( int argc, char *argv[] )
} }
if( opt.psk_list != NULL ) if( opt.psk_list != NULL )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_list_opaque != 0 )
{
psk_entry *cur_psk;
for( cur_psk = psk_info; cur_psk != NULL; cur_psk = cur_psk->next )
{
status = mbedtls_psa_get_free_key_slot( &cur_psk->slot );
if( status != PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
status = psa_setup_psk_key_slot( cur_psk->slot, alg,
cur_psk->key,
cur_psk->key_len );
if( status != PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
}
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ssl_conf_psk_cb( &conf, psk_callback, psk_info ); mbedtls_ssl_conf_psk_cb( &conf, psk_callback, psk_info );
}
#endif #endif
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
@ -3143,12 +3360,31 @@ exit:
sni_free( sni_info ); sni_free( sni_info );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
psk_free( psk_info ); if( ( ret = psk_free( psk_info ) ) != 0 )
mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
#endif #endif
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
mbedtls_dhm_free( &dhm ); mbedtls_dhm_free( &dhm );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
if( opt.psk_opaque != 0 )
{
/* This is ok even if the slot hasn't been
* initialized (we might have jumed here
* immediately because of bad cmd line params,
* for example). */
status = psa_destroy_key( psk_slot );
if( status != PSA_SUCCESS )
{
mbedtls_printf( "Failed to destroy key slot %u - error was %d",
(unsigned) psk_slot, (int) status );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ssl_free( &ssl ); mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf ); mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_ctr_drbg_free( &ctr_drbg );

View file

@ -3845,6 +3845,240 @@ run_test "PSK callback: psk, no callback" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: opaque psk on client, no callback" \
"$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo" \
"$P_CLI extended_ms=0 debug_level=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123 psk_opaque=1" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: opaque psk on client, no callback, SHA-384" \
"$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo" \
"$P_CLI extended_ms=0 debug_level=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=foo psk=abc123 psk_opaque=1" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: opaque psk on client, no callback, EMS" \
"$P_SRV extended_ms=1 debug_level=3 psk=abc123 psk_identity=foo" \
"$P_CLI extended_ms=1 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123 psk_opaque=1" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-c "using extended master secret"\
-s "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: opaque psk on client, no callback, SHA-384, EMS" \
"$P_SRV extended_ms=1 debug_level=3 psk=abc123 psk_identity=foo" \
"$P_CLI extended_ms=1 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=foo psk=abc123 psk_opaque=1" \
0 \
-c "skip PMS generation for opaque PSK"\
-S "skip PMS generation for opaque PSK"\
-c "using extended master secret"\
-s "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, static opaque on server, no callback" \
"$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, static opaque on server, no callback, SHA-384" \
"$P_SRV extended_ms=0 debug_level=1 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384" \
"$P_CLI extended_ms=0 debug_level=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=foo psk=abc123" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, static opaque on server, no callback, EMS" \
"$P_SRV debug_level=3 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls1_2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA extended_ms=1" \
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123 extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, static opaque on server, no callback, EMS, SHA384" \
"$P_SRV debug_level=3 psk=abc123 psk_identity=foo psk_opaque=1 min_version=tls1_2 \
force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 extended_ms=1" \
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=foo psk=abc123 extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback" \
"$P_SRV extended_ms=0 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, SHA-384" \
"$P_SRV extended_ms=0 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, EMS" \
"$P_SRV debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 \
force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA extended_ms=1" \
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=dead extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, no static PSK on server, opaque PSK from callback, EMS, SHA384" \
"$P_SRV debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 \
force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 extended_ms=1" \
"$P_CLI debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-256-CBC-SHA384 \
psk_identity=abc psk=dead extended_ms=1" \
0 \
-c "using extended master secret"\
-s "using extended master secret"\
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, mismatching static raw PSK on server, opaque PSK from callback" \
"$P_SRV extended_ms=0 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, mismatching static opaque PSK on server, opaque PSK from callback" \
"$P_SRV extended_ms=0 psk_opaque=1 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef psk_list_opaque=1 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-s "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, mismatching static opaque PSK on server, raw PSK from callback" \
"$P_SRV extended_ms=0 psk_opaque=1 psk_identity=foo psk=abc123 debug_level=3 psk_list=abc,dead,def,beef min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, id-matching but wrong raw PSK on server, opaque PSK from callback" \
"$P_SRV extended_ms=0 psk_opaque=1 psk_identity=def psk=abc123 debug_level=3 psk_list=abc,dead,def,beef min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
0 \
-C "skip PMS generation for opaque PSK"\
-C "using extended master secret"\
-S "using extended master secret"\
-S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed"
requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
run_test "PSK callback: raw psk on client, matching opaque PSK on server, wrong opaque PSK from callback" \
"$P_SRV extended_ms=0 psk_opaque=1 psk_identity=def psk=beef debug_level=3 psk_list=abc,dead,def,abc123 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA" \
"$P_CLI extended_ms=0 debug_level=3 min_version=tls1_2 force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \
1 \
-s "SSL - Verification of the message MAC failed"
run_test "PSK callback: no psk, no callback" \ run_test "PSK callback: no psk, no callback" \
"$P_SRV" \ "$P_SRV" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \