| /* |
| * TLS 1.3 client-side functions |
| * |
| * Copyright The Mbed TLS Contributors |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * This file is part of mbed TLS ( https://tls.mbed.org ) |
| */ |
| |
| #include "common.h" |
| |
| #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) |
| |
| #if defined(MBEDTLS_SSL_CLI_C) |
| |
| #include "ssl_misc.h" |
| #include <mbedtls/debug.h> |
| |
| /* Main entry point; orchestrates the other functions */ |
| static int ssl_client_hello_process( mbedtls_ssl_context* ssl ); |
| |
| int mbedtls_ssl_handshake_client_step_tls1_3( mbedtls_ssl_context *ssl ) |
| { |
| int ret = 0; |
| |
| if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) |
| { |
| MBEDTLS_SSL_DEBUG_MSG( 2, ( "Handshake completed but ssl->handshake is NULL.\n" ) ); |
| return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
| } |
| |
| MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); |
| |
| switch( ssl->state ) |
| { |
| case MBEDTLS_SSL_HELLO_REQUEST: |
| mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_HELLO ); |
| break; |
| |
| case MBEDTLS_SSL_CLIENT_HELLO: |
| ret = ssl_client_hello_process( ssl ); |
| break; |
| |
| case MBEDTLS_SSL_SERVER_HELLO: |
| // Stop here : we haven't finished whole flow |
| ret=MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
| mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS ); |
| break; |
| |
| default: |
| MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); |
| return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); |
| } |
| |
| return( ret ); |
| } |
| |
| |
| static int ssl_client_hello_prepare( mbedtls_ssl_context* ssl ); |
| static int ssl_client_hello_write_partial( mbedtls_ssl_context* ssl, |
| unsigned char* buf, size_t buflen, |
| size_t* len_without_binders, |
| size_t* len_with_binders ); |
| static int ssl_client_hello_postprocess( mbedtls_ssl_context* ssl ); |
| |
| static int ssl_client_hello_process( mbedtls_ssl_context* ssl ) |
| { |
| int ret = 0; |
| unsigned char *buf; |
| size_t buf_len, msg_len; |
| size_t len_without_binders = 0; |
| |
| MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); |
| |
| MBEDTLS_SSL_PROC_CHK( ssl_client_hello_prepare, ( ssl ) ); |
| |
| MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg, ( ssl, |
| MBEDTLS_SSL_HS_CLIENT_HELLO, &buf, &buf_len ) ); |
| |
| MBEDTLS_SSL_PROC_CHK( ssl_client_hello_write_partial, ( ssl, buf, buf_len, |
| &len_without_binders, |
| &msg_len ) ); |
| |
| mbedtls_ssl_add_hs_hdr_to_checksum( ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, |
| msg_len ); |
| ssl->handshake->update_checksum( ssl, buf, len_without_binders ); |
| |
| MBEDTLS_SSL_PROC_CHK( ssl_client_hello_postprocess, ( ssl ) ); |
| MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg, ( ssl, buf_len, msg_len ) ); |
| |
| cleanup: |
| |
| MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); |
| /* client_hello_process haven't finished */ |
| ret=MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; |
| return ret; |
| } |
| |
| static int ssl_client_hello_prepare( mbedtls_ssl_context* ssl ) |
| { |
| int ret; |
| size_t rand_bytes_len; |
| |
| if( ssl->conf->f_rng == NULL ) |
| { |
| MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided" ) ); |
| return( MBEDTLS_ERR_SSL_NO_RNG ); |
| } |
| |
| rand_bytes_len = 32; |
| |
| if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->handshake->randbytes, rand_bytes_len ) ) != 0 ) |
| { |
| MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret ); |
| return( ret ); |
| } |
| |
| return( 0 ); |
| } |
| |
| static int ssl_client_hello_postprocess( mbedtls_ssl_context* ssl ) |
| { |
| mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_HELLO ); |
| |
| return( 0 ); |
| } |
| |
| static int ssl_client_hello_write_partial( mbedtls_ssl_context* ssl, |
| unsigned char* buf, size_t buflen, |
| size_t* len_without_binders, |
| size_t* len_with_binders ) |
| { |
| ((void) ssl); |
| ((void) buf); |
| ((void) buflen); |
| ((void) len_without_binders); |
| ((void) len_with_binders); |
| return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); |
| } |
| |
| |
| |
| #endif /* MBEDTLS_SSL_CLI_C */ |
| |
| #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ |