From bb89e2727f532042ef7f3273f4058033851570e8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 8 Jan 2019 12:54:37 +0000 Subject: [PATCH] Implement ServerKeyExchange parsing for PSA-based ECDHE suites - Reformat the server's ECDH public key to make it suitable for the PSA key agreement API. Currently, the key agreement API needs a full SubjectPublicKeyInfo structure, while the TLS ServerKeyExchange message only contains a ECPoint structure. --- library/ssl_cli.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 06bcc731f..7665f332b 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -39,6 +39,10 @@ #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "mbedtls/psa_util.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + #include #include @@ -2109,6 +2113,64 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ + ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ) +static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl, + unsigned char **p, + unsigned char *end ) +{ + uint16_t tls_id; + uint8_t ecpoint_len; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + + /* + * Parse ECC group + */ + + if( end - *p < 4 ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + + /* First byte is curve_type; only named_curve is handled */ + if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + + /* Next two bytes are the namedcurve value */ + tls_id = *(*p)++; + tls_id <<= 8; + tls_id |= *(*p)++; + + /* Convert EC group to PSA key type. */ + if( ( handshake->ecdh_psa_curve = + mbedtls_psa_parse_tls_ecc_group( tls_id ) ) == 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + /* + * Put peer's ECDH public key in the format understood by PSA. + */ + + ecpoint_len = *(*p)++; + if( (size_t)( end - *p ) < ecpoint_len ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + + if( mbedtls_psa_tls_ecpoint_to_psa_ec( handshake->ecdh_psa_curve, + *p, ecpoint_len, + handshake->ecdh_psa_peerkey, + sizeof( handshake->ecdh_psa_peerkey ), + &handshake->ecdh_psa_peerkey_len ) != 0 ) + { + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + *p += ecpoint_len; + return( 0 ); +} +#endif /* MBEDTLS_USE_PSA_CRYPTO && + ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ + #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) @@ -2510,6 +2572,24 @@ start_processing: else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ + ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + { + if( ssl_parse_server_ecdh_params_psa( ssl, &p, end ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* MBEDTLS_USE_PSA_CRYPTO && + ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)