diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index df0280021..0e9575626 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -53,6 +53,11 @@ #include "ecjpake.h" #endif +#if defined(MBEDTLS_USE_TINYCRYPT) +#include "tinycrypt/ecc.h" +#include "tinycrypt/ecc_dh.h" +#endif + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -381,10 +386,17 @@ struct mbedtls_ssl_handshake_params size_t ecjpake_cache_len; /*!< Length of cached data */ #endif #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_USE_TINYCRYPT) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) uint16_t curve_tls_id; /*!< TLS ID of EC for ECDHE. */ #endif +#if defined(MBEDTLS_USE_TINYCRYPT) + uint8_t ecdh_privkey[NUM_ECC_BYTES]; + uint8_t ecdh_ownpubkey[2*NUM_ECC_BYTES]; + uint8_t ecdh_peerkey[2*NUM_ECC_BYTES]; +#endif /* MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) unsigned char *psk; /*!< PSK from the callback */ size_t psk_len; /*!< Length of PSK from callback */ @@ -890,6 +902,10 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); +#if defined(MBEDTLS_USE_TINYCRYPT) +int mbetls_uecc_rng_wrapper( uint8_t *dest, unsigned int size ); +#endif + /** * \brief Update record layer * diff --git a/library/ssl_cli.c b/library/ssl_cli.c index c72919496..582c9fdd4 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -250,7 +250,9 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_USE_TINYCRYPT) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static size_t ssl_get_ec_curve_list_length( mbedtls_ssl_context *ssl ) { @@ -332,7 +334,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, *olen = 6; } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -1073,7 +1075,9 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_USE_TINYCRYPT) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( uses_ec ) { @@ -1374,8 +1378,10 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ + defined(MBEDTLS_USE_TINYCRYPT) static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -1417,7 +1423,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -3521,10 +3527,42 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#if defined(MBEDTLS_USE_TINYCRYPT) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) + { + const struct uECC_Curve_t * uecc_curve = uECC_secp256r1(); + + uECC_set_rng( &mbetls_uecc_rng_wrapper ); + + if( !uECC_make_key( ssl->handshake->ecdh_ownpubkey, + ssl->handshake->ecdh_privkey, + uecc_curve ) ) + { + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey, + ssl->handshake->ecdh_privkey, + ssl->handshake->premaster, + uecc_curve ) ) + { + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + /* TODO: Write the client share. */ + ((void) p); + ((void) end); + ((void) ret); + ((void) n); + + mbedtls_platform_zeroize( ssl->handshake->ecdh_privkey, NUM_ECC_BYTES ); + } + else +#elif defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 8ffbf7c0b..8f75f6af7 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -276,7 +276,9 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_USE_TINYCRYPT) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len, @@ -364,7 +366,7 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, return( 0 ); } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_USE_TINYCRYPT MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -972,7 +974,8 @@ static int ssl_ciphersuite_is_match( mbedtls_ssl_context *ssl, } #endif -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_USE_TINYCRYPT) if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && ssl->handshake->curve_tls_id == 0 ) { @@ -1922,8 +1925,10 @@ read_record_header: #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_ECDH_C) || \ + defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ + defined(MBEDTLS_USE_TINYCRYPT) case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); @@ -1944,7 +1949,8 @@ read_record_header: return( ret ); break; #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED || + MBEDTLS_USE_TINYCRYPT */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: @@ -2539,7 +2545,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ + defined(MBEDTLS_USE_TINYCRYPT) static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) @@ -2936,7 +2943,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) || \ + defined(MBEDTLS_USE_TINYCRYPT) if ( mbedtls_ssl_ciphersuite_uses_ec( mbedtls_ssl_ciphersuite_from_id( mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) ) ) ) @@ -3243,6 +3251,9 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, unsigned char *dig_signed = NULL; #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ +#if defined(MBEDTLS_USE_TINYCRYPT) + const struct uECC_Curve_t * uecc_curve = uECC_secp256r1(); +#endif (void) ciphersuite_info; /* unused in some configurations */ #if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) @@ -3290,8 +3301,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, **/ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == + MBEDTLS_KEY_EXCHANGE_DHE_PSK || + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { ssl->out_msg[ssl->out_msglen++] = 0x00; ssl->out_msg[ssl->out_msglen++] = 0x00; @@ -3369,6 +3382,43 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, * ECPoint public; * } ServerECDHParams; */ + +#if defined(MBEDTLS_USE_TINYCRYPT) + uECC_set_rng( &mbetls_uecc_rng_wrapper ); + + if( ssl->handshake->curve_tls_id != 23 ) + return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); + + if( !uECC_make_key( ssl->handshake->ecdh_ownpubkey, + ssl->handshake->ecdh_privkey, + uecc_curve ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Key creation failed" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * First byte is curve_type, always named_curve + */ + ssl->out_msg[ssl->out_msglen++] = MBEDTLS_ECP_TLS_NAMED_CURVE; + + /* + * Next two bytes are the namedcurve value + */ + ssl->out_msg[ssl->out_msglen++] = ssl->handshake->curve_tls_id >> 8; + ssl->out_msg[ssl->out_msglen++] = ssl->handshake->curve_tls_id & 0xFF; + + /* Write the public key length */ + ssl->out_msg[ssl->out_msglen++] = 2*NUM_ECC_BYTES; + + memcpy( &ssl->out_msg[ssl->out_msglen], + ssl->handshake->ecdh_ownpubkey, + 2*NUM_ECC_BYTES ); + + ssl->out_msglen += 2*NUM_ECC_BYTES; + +#else /* MBEDTLS_USE_TINYCRYPT */ + const mbedtls_ecp_curve_info *curve = mbedtls_ecp_curve_info_from_tls_id( ssl->handshake->curve_tls_id ); int ret; @@ -3407,6 +3457,9 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, MBEDTLS_DEBUG_ECDH_Q ); + +#endif /* MBEDTLS_USE_TINYCRYPT */ + } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ @@ -4140,6 +4193,26 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, } else #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_USE_TINYCRYPT) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ) + { + const struct uECC_Curve_t * uecc_curve = uECC_secp256r1(); + + /* TODO: Parse the client's key share. */ + + if( !uECC_shared_secret( ssl->handshake->ecdh_peerkey, + ssl->handshake->ecdh_privkey, + ssl->handshake->premaster, + uecc_curve ) ) + { + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } + else +#endif #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 2a50db616..a1c26d075 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -12165,6 +12165,13 @@ unsigned char mbedtls_ssl_hash_from_md_alg( int md ) } } +#if defined(MBEDTLS_USE_TINYCRYPT) +int mbetls_uecc_rng_wrapper( uint8_t *dest, unsigned int size ) +{ + return( mbedtls_ssl_conf_rng_func( NULL, dest, size ) ); +} +#endif /* MBEDTLS_USE_TINYCRYPT */ + #if defined(MBEDTLS_ECP_C) /* * Check if a curve proposed by the peer is in our list.