diff --git a/CMakeLists.txt b/CMakeLists.txt index ddeb115e8..a40f737ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,12 +287,23 @@ add_subdirectory(library) # to define the test executables. # if(ENABLE_TESTING OR ENABLE_PROGRAMS) - file(GLOB MBEDTLS_TEST_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/drivers/*.c) + file(GLOB MBEDTLS_TEST_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/*.c + ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/drivers/*.c) add_library(mbedtls_test OBJECT ${MBEDTLS_TEST_FILES}) target_include_directories(mbedtls_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library) + + file(GLOB MBEDTLS_TEST_HELPER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/tests/src/test_helpers/*.c) + add_library(mbedtls_test_helpers OBJECT ${MBEDTLS_TEST_HELPER_FILES}) + target_include_directories(mbedtls_test_helpers + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/everest/include) endif() if(ENABLE_PROGRAMS) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ca477aced..10de8c702 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -50,7 +50,9 @@ function(add_test_suite suite_name) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py ${mbedtls_target} ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data ) - add_executable(test_suite_${data_name} test_suite_${data_name}.c $) + add_executable(test_suite_${data_name} test_suite_${data_name}.c + $ + $) target_link_libraries(test_suite_${data_name} ${libs}) # Include test-specific header files from ./include and private header # files (used by some invasive tests) from ../library. Public header diff --git a/tests/Makefile b/tests/Makefile index 44ff43c67..27dcacb16 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -86,7 +86,7 @@ all: $(BINARIES) $(MBEDLIBS): $(MAKE) -C ../library -MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/drivers/*.c)) +MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/drivers/*.c src/test_helpers/*.c)) mbedtls_test: $(MBEDTLS_TEST_OBJS) @@ -107,6 +107,10 @@ src/drivers/%.o : src/drivers/%.c echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< +src/test_helpers/%.o : src/test_helpers/%.c + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< + C_FILES := $(addsuffix .c,$(APPS)) c: $(C_FILES) @@ -143,7 +147,7 @@ $(BINARIES): %$(EXEXT): %.c $(MBEDLIBS) $(TEST_OBJS_DEPS) $(MBEDTLS_TEST_OBJS) clean: ifndef WINDOWS rm -rf $(BINARIES) *.c *.datax - rm -f src/*.o src/drivers/*.o src/libmbed* + rm -f src/*.o src/drivers/*.o src/test_helpers/*.o src/libmbed* rm -f include/test/instrument_record_status.h rm -rf libtestdriver1 else @@ -152,6 +156,7 @@ else if exist *.datax del /Q /F *.datax if exist src/*.o del /Q /F src/*.o if exist src/drivers/*.o del /Q /F src/drivers/*.o + if exist src/test_helpers/*.o del /Q /F src/test_helpers/*.o if exist src/libmbed* del /Q /F src/libmed* if exist include/test/instrument_record_status.h del /Q /F include/test/instrument_record_status.h endif diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 08179e2b0..f8b98c07b 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -104,11 +104,11 @@ const char *mbedtls_test_helper_is_psa_leaking(void); * `TEST_ASSERT( ! mbedtls_test_helper_is_psa_leaking( ) )` * but with a more informative message. */ -#define ASSERT_PSA_PRISTINE() \ +#define ASSERT_PSA_PRISTINE() \ do \ { \ - if (test_fail_if_psa_leaking(__LINE__, __FILE__)) \ - goto exit; \ + if (mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__)) \ + goto exit; \ } \ while (0) @@ -122,12 +122,12 @@ const char *mbedtls_test_helper_is_psa_leaking(void); * \note Persistent keys must be recorded with #TEST_USES_KEY_ID before * creating them. */ -#define PSA_DONE() \ +#define PSA_DONE() \ do \ { \ - test_fail_if_psa_leaking(__LINE__, __FILE__); \ - mbedtls_test_psa_purge_key_storage(); \ - mbedtls_psa_crypto_free(); \ + mbedtls_test_fail_if_psa_leaking(__LINE__, __FILE__); \ + mbedtls_test_psa_purge_key_storage(); \ + mbedtls_psa_crypto_free(); \ } \ while (0) @@ -193,6 +193,14 @@ psa_status_t mbedtls_test_record_status(psa_status_t status, */ psa_key_usage_t mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags); +/** Check that no PSA Crypto key slots are in use. + * + * If any slots are in use, mark the current test as failed. + * + * \return 0 if the key store is empty, 1 otherwise. + */ +int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename); + /** Skip a test case if the given key is a 192 bits AES key and the AES * implementation is at least partially provided by an accelerator or * alternative implementation. diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h new file mode 100644 index 000000000..195704383 --- /dev/null +++ b/tests/include/test/ssl_helpers.h @@ -0,0 +1,511 @@ +/** \file ssl_helpers.h + * + * \brief This file contains helper functions to set up a TLS connection. + */ + +/* + * 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. + */ + +#ifndef SSL_HELPERS_H +#define SSL_HELPERS_H + +#include + +#include +#include +#include +#include + +#if defined(MBEDTLS_SSL_TLS_C) +#include +#include +#include +#include +#include +#include +#include + +#if defined(MBEDTLS_SSL_CACHE_C) +#include "mbedtls/ssl_cache.h" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY +#endif + +enum { +#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ + tls1_3_label_ ## name, + MBEDTLS_SSL_TLS1_3_LABEL_LIST +#undef MBEDTLS_SSL_TLS1_3_LABEL +}; + +typedef struct mbedtls_test_ssl_log_pattern { + const char *pattern; + size_t counter; +} mbedtls_test_ssl_log_pattern; + +/* Invalid minor version used when not specifying a min/max version or expecting a test to fail */ +#define TEST_SSL_MINOR_VERSION_NONE -1 + +typedef struct mbedtls_test_handshake_test_options { + const char *cipher; + int client_min_version; + int client_max_version; + int server_min_version; + int server_max_version; + int expected_negotiated_version; + int pk_alg; + data_t *psk_str; + int dtls; + int srv_auth_mode; + int serialize; + int mfl; + int cli_msg_len; + int srv_msg_len; + int expected_cli_fragments; + int expected_srv_fragments; + int renegotiate; + int legacy_renegotiation; + void *srv_log_obj; + void *cli_log_obj; + void (*srv_log_fun)(void *, int, const char *, int, const char *); + void (*cli_log_fun)(void *, int, const char *, int, const char *); + int resize_buffers; +} mbedtls_test_handshake_test_options; + +/* + * Buffer structure for custom I/O callbacks. + */ +typedef struct mbedtls_test_ssl_buffer { + size_t start; + size_t content_length; + size_t capacity; + unsigned char *buffer; +} mbedtls_test_ssl_buffer; + +/* + * Context for a message metadata queue (fifo) that is on top of the ring buffer. + */ +typedef struct mbedtls_test_ssl_message_queue { + size_t *messages; + int pos; + int num; + int capacity; +} mbedtls_test_ssl_message_queue; + +/* + * Context for the I/O callbacks simulating network connection. + */ + +#define MBEDTLS_MOCK_SOCKET_CONNECTED 1 + +typedef struct mbedtls_test_mock_socket { + int status; + mbedtls_test_ssl_buffer *input; + mbedtls_test_ssl_buffer *output; + struct mbedtls_test_mock_socket *peer; +} mbedtls_test_mock_socket; + +/* Errors used in the message socket mocks */ + +#define MBEDTLS_TEST_ERROR_CONTEXT_ERROR -55 +#define MBEDTLS_TEST_ERROR_SEND_FAILED -66 +#define MBEDTLS_TEST_ERROR_RECV_FAILED -77 + +/* + * Structure used as an addon, or a wrapper, around the mocked sockets. + * Contains an input queue, to which the other socket pushes metadata, + * and an output queue, to which this one pushes metadata. This context is + * considered as an owner of the input queue only, which is initialized and + * freed in the respective setup and free calls. + */ +typedef struct mbedtls_test_message_socket_context { + mbedtls_test_ssl_message_queue *queue_input; + mbedtls_test_ssl_message_queue *queue_output; + mbedtls_test_mock_socket *socket; +} mbedtls_test_message_socket_context; + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_C) + +/* + * Structure with endpoint's certificates for SSL communication tests. + */ +typedef struct mbedtls_test_ssl_endpoint_certificate { + mbedtls_x509_crt *ca_cert; + mbedtls_x509_crt *cert; + mbedtls_pk_context *pkey; +} mbedtls_test_ssl_endpoint_certificate; + +/* + * Endpoint structure for SSL communication tests. + */ +typedef struct mbedtls_test_ssl_endpoint { + const char *name; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_entropy_context entropy; + mbedtls_test_mock_socket socket; + mbedtls_test_ssl_endpoint_certificate cert; +} mbedtls_test_ssl_endpoint; + +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && + MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ + +/* + * This function can be passed to mbedtls to receive output logs from it. In + * this case, it will count the instances of a mbedtls_test_ssl_log_pattern + * in the received logged messages. + */ +void mbedtls_test_ssl_log_analyzer(void *ctx, int level, + const char *file, int line, + const char *str); + +void mbedtls_test_init_handshake_options( + mbedtls_test_handshake_test_options *opts); + +/* + * Initialises \p buf. After calling this function it is safe to call + * `mbedtls_test_ssl_buffer_free()` on \p buf. + */ +void mbedtls_test_ssl_buffer_init(mbedtls_test_ssl_buffer *buf); + +/* + * Sets up \p buf. After calling this function it is safe to call + * `mbedtls_test_ssl_buffer_put()` and `mbedtls_test_ssl_buffer_get()` + * on \p buf. + */ +int mbedtls_test_ssl_buffer_setup(mbedtls_test_ssl_buffer *buf, + size_t capacity); + +void mbedtls_test_ssl_buffer_free(mbedtls_test_ssl_buffer *buf); + +/* + * Puts \p input_len bytes from the \p input buffer into the ring buffer \p buf. + * + * \p buf must have been initialized and set up by calling + * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`. + * + * \retval \p input_len, if the data fits. + * \retval 0 <= value < \p input_len, if the data does not fit. + * \retval -1, if \p buf is NULL, it hasn't been set up or \p input_len is not + * zero and \p input is NULL. + */ +int mbedtls_test_ssl_buffer_put(mbedtls_test_ssl_buffer *buf, + const unsigned char *input, size_t input_len); + +/* + * Gets \p output_len bytes from the ring buffer \p buf into the + * \p output buffer. The output buffer can be NULL, in this case a part of the + * ring buffer will be dropped, if the requested length is available. + * + * \p buf must have been initialized and set up by calling + * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`. + * + * \retval \p output_len, if the data is available. + * \retval 0 <= value < \p output_len, if the data is not available. + * \retval -1, if \buf is NULL or it hasn't been set up. + */ +int mbedtls_test_ssl_buffer_get(mbedtls_test_ssl_buffer *buf, + unsigned char *output, size_t output_len); + +/* + * Errors used in the message transport mock tests + */ + #define MBEDTLS_TEST_ERROR_ARG_NULL -11 + #define MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED -44 + +/* + * Setup and free functions for the message metadata queue. + * + * \p capacity describes the number of message metadata chunks that can be held + * within the queue. + * + * \retval 0, if a metadata queue of a given length can be allocated. + * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation failed. + */ +int mbedtls_test_ssl_message_queue_setup( + mbedtls_test_ssl_message_queue *queue, size_t capacity); + +void mbedtls_test_ssl_message_queue_free( + mbedtls_test_ssl_message_queue *queue); + +/* + * Push message length information onto the message metadata queue. + * This will become the last element to leave it (fifo). + * + * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. + * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the queue is full. + * \retval \p len, if the push was successful. + */ +int mbedtls_test_ssl_message_queue_push_info( + mbedtls_test_ssl_message_queue *queue, size_t len); + +/* + * Pop information about the next message length from the queue. This will be + * the oldest inserted message length(fifo). \p msg_len can be null, in which + * case the data will be popped from the queue but not copied anywhere. + * + * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. + * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty. + * \retval message length, if the pop was successful, up to the given + \p buf_len. + */ +int mbedtls_test_ssl_message_queue_pop_info( + mbedtls_test_ssl_message_queue *queue, size_t buf_len); + +/* + * Setup and teardown functions for mock sockets. + */ +void mbedtls_mock_socket_init(mbedtls_test_mock_socket *socket); + +/* + * Closes the socket \p socket. + * + * \p socket must have been previously initialized by calling + * mbedtls_mock_socket_init(). + * + * This function frees all allocated resources and both sockets are aware of the + * new connection state. + * + * That is, this function does not simulate half-open TCP connections and the + * phenomenon that when closing a UDP connection the peer is not aware of the + * connection having been closed. + */ +void mbedtls_test_mock_socket_close(mbedtls_test_mock_socket *socket); + +/* + * Establishes a connection between \p peer1 and \p peer2. + * + * \p peer1 and \p peer2 must have been previously initialized by calling + * mbedtls_mock_socket_init(). + * + * The capacities of the internal buffers are set to \p bufsize. Setting this to + * the correct value allows for simulation of MTU, sanity testing the mock + * implementation and mocking TCP connections with lower memory cost. + */ +int mbedtls_test_mock_socket_connect(mbedtls_test_mock_socket *peer1, + mbedtls_test_mock_socket *peer2, + size_t bufsize); + +/* + * Callbacks for simulating blocking I/O over connection-oriented transport. + */ +int mbedtls_test_mock_tcp_send_b(void *ctx, + const unsigned char *buf, size_t len); + +int mbedtls_test_mock_tcp_recv_b(void *ctx, unsigned char *buf, size_t len); + +/* + * Callbacks for simulating non-blocking I/O over connection-oriented transport. + */ +int mbedtls_test_mock_tcp_send_nb(void *ctx, + const unsigned char *buf, size_t len); + +int mbedtls_test_mock_tcp_recv_nb(void *ctx, unsigned char *buf, size_t len); + +void mbedtls_test_message_socket_init( + mbedtls_test_message_socket_context *ctx); + +/* + * Setup a given message socket context including initialization of + * input/output queues to a chosen capacity of messages. Also set the + * corresponding mock socket. + * + * \retval 0, if everything succeeds. + * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation of a message + * queue failed. + */ +int mbedtls_test_message_socket_setup( + mbedtls_test_ssl_message_queue *queue_input, + mbedtls_test_ssl_message_queue *queue_output, + size_t queue_capacity, + mbedtls_test_mock_socket *socket, + mbedtls_test_message_socket_context *ctx); + +/* + * Close a given message socket context, along with the socket itself. Free the + * memory allocated by the input queue. + */ +void mbedtls_test_message_socket_close( + mbedtls_test_message_socket_context *ctx); + +/* + * Send one message through a given message socket context. + * + * \retval \p len, if everything succeeds. + * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context + * elements or the context itself is null. + * \retval MBEDTLS_TEST_ERROR_SEND_FAILED if + * mbedtls_test_mock_tcp_send_b failed. + * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the output queue is full. + * + * This function will also return any error from + * mbedtls_test_ssl_message_queue_push_info. + */ +int mbedtls_test_mock_tcp_send_msg(void *ctx, + const unsigned char *buf, size_t len); + +/* + * Receive one message from a given message socket context and return message + * length or an error. + * + * \retval message length, if everything succeeds. + * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context + * elements or the context itself is null. + * \retval MBEDTLS_TEST_ERROR_RECV_FAILED if + * mbedtls_test_mock_tcp_recv_b failed. + * + * This function will also return any error other than + * MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED from + * mbedtls_test_message_queue_peek_info. + */ +int mbedtls_test_mock_tcp_recv_msg(void *ctx, + unsigned char *buf, size_t buf_len); + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_C) + +/* + * Initializes \p ep_cert structure and assigns it to endpoint + * represented by \p ep. + * + * \retval 0 on success, otherwise error code. + */ +int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep, + int pk_alg); + +/* + * Initializes \p ep structure. It is important to call + * `mbedtls_test_ssl_endpoint_free()` after calling this function + * even if it fails. + * + * \p endpoint_type must be set as MBEDTLS_SSL_IS_SERVER or + * MBEDTLS_SSL_IS_CLIENT. + * \p pk_alg the algorithm to use, currently only MBEDTLS_PK_RSA and + * MBEDTLS_PK_ECDSA are supported. + * \p dtls_context - in case of DTLS - this is the context handling metadata. + * \p input_queue - used only in case of DTLS. + * \p output_queue - used only in case of DTLS. + * + * \retval 0 on success, otherwise error code. + */ +int mbedtls_test_ssl_endpoint_init( + mbedtls_test_ssl_endpoint *ep, int endpoint_type, int pk_alg, + mbedtls_test_message_socket_context *dtls_context, + mbedtls_test_ssl_message_queue *input_queue, + mbedtls_test_ssl_message_queue *output_queue, + const mbedtls_ecp_group_id *curves); + +/* + * Deinitializes endpoint represented by \p ep. + */ +void mbedtls_test_ssl_endpoint_free( + mbedtls_test_ssl_endpoint *ep, + mbedtls_test_message_socket_context *context); + +/* + * This function moves ssl handshake from \p ssl to prescribed \p state. + * /p second_ssl is used as second endpoint and their sockets have to be + * connected before calling this function. + * + * \retval 0 on success, otherwise error code. + */ +int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, + mbedtls_ssl_context *second_ssl, + int state); + +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && + MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ + +/* + * Helper function setting up inverse record transformations + * using given cipher, hash, EtM mode, authentication tag length, + * and version. + */ + +#define CHK(x) \ + do \ + { \ + if (!(x)) \ + { \ + ret = -1; \ + goto cleanup; \ + } \ + } while (0) + +int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in, + mbedtls_ssl_transform *t_out, + int cipher_type, int hash_id, + int etm, int tag_mode, int ver, + size_t cid0_len, + size_t cid1_len); + +/* + * Populate a session structure for serialization tests. + * Choose dummy values, mostly non-0 to distinguish from the init default. + */ +int mbedtls_test_ssl_populate_session(mbedtls_ssl_session *session, + int ticket_len, + const char *crt_file); + +/* + * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the + * message was sent in the correct number of fragments. + * + * /p ssl_1 and /p ssl_2 Endpoints represented by mbedtls_ssl_context. Both + * of them must be initialized and connected + * beforehand. + * /p msg_len_1 and /p msg_len_2 specify the size of the message to send. + * /p expected_fragments_1 and /p expected_fragments_2 determine in how many + * fragments the message should be sent. + * expected_fragments is 0: can be used for DTLS testing while the message + * size is larger than MFL. In that case the message + * cannot be fragmented and sent to the second + * endpoint. + * This value can be used for negative tests. + * expected_fragments is 1: can be used for TLS/DTLS testing while the + * message size is below MFL + * expected_fragments > 1: can be used for TLS testing while the message + * size is larger than MFL + * + * \retval 0 on success, otherwise error code. + */ +int mbedtls_exchange_data(mbedtls_ssl_context *ssl_1, + int msg_len_1, const int expected_fragments_1, + mbedtls_ssl_context *ssl_2, + int msg_len_2, const int expected_fragments_2); + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_C) +void mbedtls_test_ssl_perform_handshake( + mbedtls_test_handshake_test_options *options); +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && + MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ +#endif /* MBEDTLS_SSL_TLS_C */ + +#endif /* SSL_HELPERS_H */ diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 06274d388..77c2f8976 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -138,4 +138,15 @@ psa_key_usage_t mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags) return updated_usage; } +int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename) +{ + const char *msg = mbedtls_test_helper_is_psa_leaking(); + if (msg == NULL) { + return 0; + } else { + mbedtls_test_fail(msg, line_no, filename); + return 1; + } +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c new file mode 100644 index 000000000..b7a7e86ee --- /dev/null +++ b/tests/src/test_helpers/ssl_helpers.c @@ -0,0 +1,1760 @@ +/** \file ssl_helpers.c + * + * \brief Helper functions to set up a TLS connection. + */ + +/* + * 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. + */ + +#include + +#if defined(MBEDTLS_SSL_TLS_C) + +void mbedtls_test_ssl_log_analyzer(void *ctx, int level, + const char *file, int line, + const char *str) +{ + mbedtls_test_ssl_log_pattern *p = (mbedtls_test_ssl_log_pattern *) ctx; + + (void) level; + (void) line; + (void) file; + + if (NULL != p && + NULL != p->pattern && + NULL != strstr(str, p->pattern)) { + p->counter++; + } +} + +void mbedtls_test_init_handshake_options( + mbedtls_test_handshake_test_options *opts) +{ + opts->cipher = ""; + opts->client_min_version = TEST_SSL_MINOR_VERSION_NONE; + opts->client_max_version = TEST_SSL_MINOR_VERSION_NONE; + opts->server_min_version = TEST_SSL_MINOR_VERSION_NONE; + opts->server_max_version = TEST_SSL_MINOR_VERSION_NONE; + opts->expected_negotiated_version = MBEDTLS_SSL_MINOR_VERSION_3; + opts->pk_alg = MBEDTLS_PK_RSA; + opts->psk_str = NULL; + opts->dtls = 0; + opts->srv_auth_mode = MBEDTLS_SSL_VERIFY_NONE; + opts->serialize = 0; + opts->mfl = MBEDTLS_SSL_MAX_FRAG_LEN_NONE; + opts->cli_msg_len = 100; + opts->srv_msg_len = 100; + opts->expected_cli_fragments = 1; + opts->expected_srv_fragments = 1; + opts->renegotiate = 0; + opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; + opts->srv_log_obj = NULL; + opts->srv_log_obj = NULL; + opts->srv_log_fun = NULL; + opts->cli_log_fun = NULL; + opts->resize_buffers = 1; +} + +void mbedtls_test_ssl_buffer_init(mbedtls_test_ssl_buffer *buf) +{ + memset(buf, 0, sizeof(*buf)); +} + +int mbedtls_test_ssl_buffer_setup(mbedtls_test_ssl_buffer *buf, + size_t capacity) +{ + buf->buffer = (unsigned char *) mbedtls_calloc(capacity, + sizeof(unsigned char)); + if (NULL == buf->buffer) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + buf->capacity = capacity; + + return 0; +} + +void mbedtls_test_ssl_buffer_free(mbedtls_test_ssl_buffer *buf) +{ + if (buf->buffer != NULL) { + mbedtls_free(buf->buffer); + } + + memset(buf, 0, sizeof(*buf)); +} + +int mbedtls_test_ssl_buffer_put(mbedtls_test_ssl_buffer *buf, + const unsigned char *input, size_t input_len) +{ + size_t overflow = 0; + + if ((buf == NULL) || (buf->buffer == NULL)) { + return -1; + } + + /* Reduce input_len to a number that fits in the buffer. */ + if ((buf->content_length + input_len) > buf->capacity) { + input_len = buf->capacity - buf->content_length; + } + + if (input == NULL) { + return (input_len == 0) ? 0 : -1; + } + + /* Check if the buffer has not come full circle and free space is not in + * the middle */ + if (buf->start + buf->content_length < buf->capacity) { + + /* Calculate the number of bytes that need to be placed at lower memory + * address */ + if (buf->start + buf->content_length + input_len + > buf->capacity) { + overflow = (buf->start + buf->content_length + input_len) + % buf->capacity; + } + + memcpy(buf->buffer + buf->start + buf->content_length, input, + input_len - overflow); + memcpy(buf->buffer, input + input_len - overflow, overflow); + + } else { + /* The buffer has come full circle and free space is in the middle */ + memcpy(buf->buffer + buf->start + buf->content_length - buf->capacity, + input, input_len); + } + + buf->content_length += input_len; + return (input_len > INT_MAX) ? INT_MAX : (int) input_len; +} + +int mbedtls_test_ssl_buffer_get(mbedtls_test_ssl_buffer *buf, + unsigned char *output, size_t output_len) +{ + size_t overflow = 0; + + if ((buf == NULL) || (buf->buffer == NULL)) { + return -1; + } + + if (output == NULL && output_len == 0) { + return 0; + } + + if (buf->content_length < output_len) { + output_len = buf->content_length; + } + + /* Calculate the number of bytes that need to be drawn from lower memory + * address */ + if (buf->start + output_len > buf->capacity) { + overflow = (buf->start + output_len) % buf->capacity; + } + + if (output != NULL) { + memcpy(output, buf->buffer + buf->start, output_len - overflow); + memcpy(output + output_len - overflow, buf->buffer, overflow); + } + + buf->content_length -= output_len; + buf->start = (buf->start + output_len) % buf->capacity; + + return (output_len > INT_MAX) ? INT_MAX : (int) output_len; +} + +int mbedtls_test_ssl_message_queue_setup( + mbedtls_test_ssl_message_queue *queue, size_t capacity) +{ + queue->messages = (size_t *) mbedtls_calloc(capacity, sizeof(size_t)); + if (NULL == queue->messages) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + queue->capacity = (capacity > INT_MAX) ? INT_MAX : (int) capacity; + queue->pos = 0; + queue->num = 0; + + return 0; +} + +void mbedtls_test_ssl_message_queue_free( + mbedtls_test_ssl_message_queue *queue) +{ + if (queue == NULL) { + return; + } + + if (queue->messages != NULL) { + mbedtls_free(queue->messages); + } + + memset(queue, 0, sizeof(*queue)); +} + +int mbedtls_test_ssl_message_queue_push_info( + mbedtls_test_ssl_message_queue *queue, size_t len) +{ + int place; + if (queue == NULL) { + return MBEDTLS_TEST_ERROR_ARG_NULL; + } + + if (queue->num >= queue->capacity) { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + + place = (queue->pos + queue->num) % queue->capacity; + queue->messages[place] = len; + queue->num++; + return (len > INT_MAX) ? INT_MAX : (int) len; +} + +int mbedtls_test_ssl_message_queue_pop_info( + mbedtls_test_ssl_message_queue *queue, size_t buf_len) +{ + size_t message_length; + if (queue == NULL) { + return MBEDTLS_TEST_ERROR_ARG_NULL; + } + if (queue->num == 0) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + message_length = queue->messages[queue->pos]; + queue->messages[queue->pos] = 0; + queue->num--; + queue->pos++; + queue->pos %= queue->capacity; + if (queue->pos < 0) { + queue->pos += queue->capacity; + } + + return (message_length > INT_MAX && buf_len > INT_MAX) ? INT_MAX : + (message_length > buf_len) ? (int) buf_len : (int) message_length; +} + +/* + * Take a peek on the info about the next message length from the queue. + * This will be the oldest inserted message length(fifo). + * + * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. + * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty. + * \retval 0, if the peek was successful. + * \retval MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED, if the given buffer length is + * too small to fit the message. In this case the \p msg_len will be + * set to the full message length so that the + * caller knows what portion of the message can be dropped. + */ +int mbedtls_test_message_queue_peek_info(mbedtls_test_ssl_message_queue *queue, + size_t buf_len, size_t *msg_len) +{ + if (queue == NULL || msg_len == NULL) { + return MBEDTLS_TEST_ERROR_ARG_NULL; + } + if (queue->num == 0) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + *msg_len = queue->messages[queue->pos]; + return (*msg_len > buf_len) ? MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED : 0; +} + +void mbedtls_mock_socket_init(mbedtls_test_mock_socket *socket) +{ + memset(socket, 0, sizeof(*socket)); +} + +void mbedtls_test_mock_socket_close(mbedtls_test_mock_socket *socket) +{ + if (socket == NULL) { + return; + } + + if (socket->input != NULL) { + mbedtls_test_ssl_buffer_free(socket->input); + mbedtls_free(socket->input); + } + + if (socket->output != NULL) { + mbedtls_test_ssl_buffer_free(socket->output); + mbedtls_free(socket->output); + } + + if (socket->peer != NULL) { + memset(socket->peer, 0, sizeof(*socket->peer)); + } + + memset(socket, 0, sizeof(*socket)); +} + +int mbedtls_test_mock_socket_connect(mbedtls_test_mock_socket *peer1, + mbedtls_test_mock_socket *peer2, + size_t bufsize) +{ + int ret = -1; + + peer1->output = + (mbedtls_test_ssl_buffer *) mbedtls_calloc( + 1, sizeof(mbedtls_test_ssl_buffer)); + if (peer1->output == NULL) { + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + mbedtls_test_ssl_buffer_init(peer1->output); + if (0 != (ret = mbedtls_test_ssl_buffer_setup(peer1->output, bufsize))) { + goto exit; + } + + peer2->output = + (mbedtls_test_ssl_buffer *) mbedtls_calloc( + 1, sizeof(mbedtls_test_ssl_buffer)); + if (peer2->output == NULL) { + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + mbedtls_test_ssl_buffer_init(peer2->output); + if (0 != (ret = mbedtls_test_ssl_buffer_setup(peer2->output, bufsize))) { + goto exit; + } + + peer1->peer = peer2; + peer2->peer = peer1; + peer1->input = peer2->output; + peer2->input = peer1->output; + + peer1->status = peer2->status = MBEDTLS_MOCK_SOCKET_CONNECTED; + ret = 0; + +exit: + + if (ret != 0) { + mbedtls_test_mock_socket_close(peer1); + mbedtls_test_mock_socket_close(peer2); + } + + return ret; +} + +int mbedtls_test_mock_tcp_send_b(void *ctx, + const unsigned char *buf, size_t len) +{ + mbedtls_test_mock_socket *socket = (mbedtls_test_mock_socket *) ctx; + + if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { + return -1; + } + + return mbedtls_test_ssl_buffer_put(socket->output, buf, len); +} + +int mbedtls_test_mock_tcp_recv_b(void *ctx, unsigned char *buf, size_t len) +{ + mbedtls_test_mock_socket *socket = (mbedtls_test_mock_socket *) ctx; + + if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { + return -1; + } + + return mbedtls_test_ssl_buffer_get(socket->input, buf, len); +} + +int mbedtls_test_mock_tcp_send_nb(void *ctx, + const unsigned char *buf, size_t len) +{ + mbedtls_test_mock_socket *socket = (mbedtls_test_mock_socket *) ctx; + + if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { + return -1; + } + + if (socket->output->capacity == socket->output->content_length) { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + + return mbedtls_test_ssl_buffer_put(socket->output, buf, len); +} + +int mbedtls_test_mock_tcp_recv_nb(void *ctx, unsigned char *buf, size_t len) +{ + mbedtls_test_mock_socket *socket = (mbedtls_test_mock_socket *) ctx; + + if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { + return -1; + } + + if (socket->input->content_length == 0) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + return mbedtls_test_ssl_buffer_get(socket->input, buf, len); +} + +void mbedtls_test_message_socket_init( + mbedtls_test_message_socket_context *ctx) +{ + ctx->queue_input = NULL; + ctx->queue_output = NULL; + ctx->socket = NULL; +} + +int mbedtls_test_message_socket_setup( + mbedtls_test_ssl_message_queue *queue_input, + mbedtls_test_ssl_message_queue *queue_output, + size_t queue_capacity, + mbedtls_test_mock_socket *socket, + mbedtls_test_message_socket_context *ctx) +{ + int ret = mbedtls_test_ssl_message_queue_setup(queue_input, queue_capacity); + if (ret != 0) { + return ret; + } + ctx->queue_input = queue_input; + ctx->queue_output = queue_output; + ctx->socket = socket; + mbedtls_mock_socket_init(socket); + + return 0; +} + +void mbedtls_test_message_socket_close( + mbedtls_test_message_socket_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_test_ssl_message_queue_free(ctx->queue_input); + mbedtls_test_mock_socket_close(ctx->socket); + memset(ctx, 0, sizeof(*ctx)); +} + +int mbedtls_test_mock_tcp_send_msg(void *ctx, + const unsigned char *buf, size_t len) +{ + mbedtls_test_ssl_message_queue *queue; + mbedtls_test_mock_socket *socket; + mbedtls_test_message_socket_context *context = + (mbedtls_test_message_socket_context *) ctx; + + if (context == NULL || context->socket == NULL + || context->queue_output == NULL) { + return MBEDTLS_TEST_ERROR_CONTEXT_ERROR; + } + + queue = context->queue_output; + socket = context->socket; + + if (queue->num >= queue->capacity) { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + + if (mbedtls_test_mock_tcp_send_b(socket, buf, len) != (int) len) { + return MBEDTLS_TEST_ERROR_SEND_FAILED; + } + + return mbedtls_test_ssl_message_queue_push_info(queue, len); +} + +int mbedtls_test_mock_tcp_recv_msg(void *ctx, + unsigned char *buf, size_t buf_len) +{ + mbedtls_test_ssl_message_queue *queue; + mbedtls_test_mock_socket *socket; + mbedtls_test_message_socket_context *context = + (mbedtls_test_message_socket_context *) ctx; + size_t drop_len = 0; + size_t msg_len; + int ret; + + if (context == NULL || context->socket == NULL + || context->queue_input == NULL) { + return MBEDTLS_TEST_ERROR_CONTEXT_ERROR; + } + + queue = context->queue_input; + socket = context->socket; + + /* Peek first, so that in case of a socket error the data remains in + * the queue. */ + ret = mbedtls_test_message_queue_peek_info(queue, buf_len, &msg_len); + if (ret == MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED) { + /* Calculate how much to drop */ + drop_len = msg_len - buf_len; + + /* Set the requested message len to be buffer length */ + msg_len = buf_len; + } else if (ret != 0) { + return ret; + } + + if (mbedtls_test_mock_tcp_recv_b(socket, buf, msg_len) != (int) msg_len) { + return MBEDTLS_TEST_ERROR_RECV_FAILED; + } + + if (ret == MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED) { + /* Drop the remaining part of the message */ + if (mbedtls_test_mock_tcp_recv_b(socket, NULL, drop_len) != + (int) drop_len) { + /* Inconsistent state - part of the message was read, + * and a part couldn't. Not much we can do here, but it should not + * happen in test environment, unless forced manually. */ + } + } + mbedtls_test_ssl_message_queue_pop_info(queue, buf_len); + + return (msg_len > INT_MAX) ? INT_MAX : (int) msg_len; +} + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_C) + +/* + * Deinitializes certificates from endpoint represented by \p ep. + */ +void mbedtls_endpoint_certificate_free(mbedtls_test_ssl_endpoint *ep) +{ + mbedtls_test_ssl_endpoint_certificate *cert = &(ep->cert); + if (cert != NULL) { + if (cert->ca_cert != NULL) { + mbedtls_x509_crt_free(cert->ca_cert); + mbedtls_free(cert->ca_cert); + cert->ca_cert = NULL; + } + if (cert->cert != NULL) { + mbedtls_x509_crt_free(cert->cert); + mbedtls_free(cert->cert); + cert->cert = NULL; + } + if (cert->pkey != NULL) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if (mbedtls_pk_get_type(cert->pkey) == MBEDTLS_PK_OPAQUE) { + mbedtls_svc_key_id_t *key_slot = cert->pkey->pk_ctx; + psa_destroy_key(*key_slot); + } +#endif + mbedtls_pk_free(cert->pkey); + mbedtls_free(cert->pkey); + cert->pkey = NULL; + } + } +} + +int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep, + int pk_alg) +{ + int i = 0; + int ret = -1; + mbedtls_test_ssl_endpoint_certificate *cert = NULL; + + if (ep == NULL) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + cert = &(ep->cert); + ASSERT_ALLOC(cert->ca_cert, 1); + ASSERT_ALLOC(cert->cert, 1); + ASSERT_ALLOC(cert->pkey, 1); + + mbedtls_x509_crt_init(cert->ca_cert); + mbedtls_x509_crt_init(cert->cert); + mbedtls_pk_init(cert->pkey); + + /* Load the trusted CA */ + + for (i = 0; mbedtls_test_cas_der[i] != NULL; i++) { + ret = mbedtls_x509_crt_parse_der( + cert->ca_cert, + (const unsigned char *) mbedtls_test_cas_der[i], + mbedtls_test_cas_der_len[i]); + TEST_ASSERT(ret == 0); + } + + /* Load own certificate and private key */ + + if (ep->conf.endpoint == MBEDTLS_SSL_IS_SERVER) { + if (pk_alg == MBEDTLS_PK_RSA) { + ret = mbedtls_x509_crt_parse( + cert->cert, + (const unsigned char *) mbedtls_test_srv_crt_rsa_sha256_der, + mbedtls_test_srv_crt_rsa_sha256_der_len); + TEST_ASSERT(ret == 0); + + ret = mbedtls_pk_parse_key( + cert->pkey, + (const unsigned char *) mbedtls_test_srv_key_rsa_der, + mbedtls_test_srv_key_rsa_der_len, NULL, 0); + TEST_ASSERT(ret == 0); + } else { + ret = mbedtls_x509_crt_parse( + cert->cert, + (const unsigned char *) mbedtls_test_srv_crt_ec_der, + mbedtls_test_srv_crt_ec_der_len); + TEST_ASSERT(ret == 0); + + ret = mbedtls_pk_parse_key( + cert->pkey, + (const unsigned char *) mbedtls_test_srv_key_ec_der, + mbedtls_test_srv_key_ec_der_len, NULL, 0); + TEST_ASSERT(ret == 0); + } + } else { + if (pk_alg == MBEDTLS_PK_RSA) { + ret = mbedtls_x509_crt_parse( + cert->cert, + (const unsigned char *) mbedtls_test_cli_crt_rsa_der, + mbedtls_test_cli_crt_rsa_der_len); + TEST_ASSERT(ret == 0); + + ret = mbedtls_pk_parse_key( + cert->pkey, + (const unsigned char *) mbedtls_test_cli_key_rsa_der, + mbedtls_test_cli_key_rsa_der_len, NULL, 0); + TEST_ASSERT(ret == 0); + } else { + ret = mbedtls_x509_crt_parse( + cert->cert, + (const unsigned char *) mbedtls_test_cli_crt_ec_der, + mbedtls_test_cli_crt_ec_len); + TEST_ASSERT(ret == 0); + + ret = mbedtls_pk_parse_key( + cert->pkey, + (const unsigned char *) mbedtls_test_cli_key_ec_der, + mbedtls_test_cli_key_ec_der_len, NULL, 0); + TEST_ASSERT(ret == 0); + } + } + + mbedtls_ssl_conf_ca_chain(&(ep->conf), cert->ca_cert, NULL); + + ret = mbedtls_ssl_conf_own_cert(&(ep->conf), cert->cert, + cert->pkey); + TEST_ASSERT(ret == 0); + +exit: + if (ret != 0) { + mbedtls_endpoint_certificate_free(ep); + } + + return ret; +} + +int mbedtls_test_ssl_endpoint_init( + mbedtls_test_ssl_endpoint *ep, int endpoint_type, int pk_alg, + mbedtls_test_message_socket_context *dtls_context, + mbedtls_test_ssl_message_queue *input_queue, + mbedtls_test_ssl_message_queue *output_queue, + const mbedtls_ecp_group_id *curves) +{ + int ret = -1; + + if (dtls_context != NULL && + (input_queue == NULL || output_queue == NULL)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + if (ep == NULL) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + memset(ep, 0, sizeof(*ep)); + + ep->name = (endpoint_type == MBEDTLS_SSL_IS_SERVER) ? "Server" : "Client"; + + mbedtls_ssl_init(&(ep->ssl)); + mbedtls_ssl_config_init(&(ep->conf)); + mbedtls_ctr_drbg_init(&(ep->ctr_drbg)); + mbedtls_ssl_conf_rng(&(ep->conf), + mbedtls_ctr_drbg_random, + &(ep->ctr_drbg)); + mbedtls_entropy_init(&(ep->entropy)); + if (dtls_context != NULL) { + TEST_ASSERT(mbedtls_test_message_socket_setup(input_queue, output_queue, + 100, &(ep->socket), + dtls_context) == 0); + } else { + mbedtls_mock_socket_init(&(ep->socket)); + } + + ret = mbedtls_ctr_drbg_seed(&(ep->ctr_drbg), mbedtls_entropy_func, + &(ep->entropy), + (const unsigned char *) (ep->name), + strlen(ep->name)); + TEST_ASSERT(ret == 0); + + /* Non-blocking callbacks without timeout */ + if (dtls_context != NULL) { + mbedtls_ssl_set_bio(&(ep->ssl), dtls_context, + mbedtls_test_mock_tcp_send_msg, + mbedtls_test_mock_tcp_recv_msg, + NULL); + } else { + mbedtls_ssl_set_bio(&(ep->ssl), &(ep->socket), + mbedtls_test_mock_tcp_send_nb, + mbedtls_test_mock_tcp_recv_nb, + NULL); + } + + ret = mbedtls_ssl_config_defaults(&(ep->conf), endpoint_type, + (dtls_context != NULL) ? + MBEDTLS_SSL_TRANSPORT_DATAGRAM : + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + TEST_ASSERT(ret == 0); + +#if defined(MBEDTLS_ECP_C) + if (curves != NULL) { + mbedtls_ssl_conf_curves(&(ep->conf), curves); + } +#else + (void) curves; +#endif + + ret = mbedtls_ssl_setup(&(ep->ssl), &(ep->conf)); + TEST_ASSERT(ret == 0); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C) + if (endpoint_type == MBEDTLS_SSL_IS_SERVER && dtls_context != NULL) { + mbedtls_ssl_conf_dtls_cookies(&(ep->conf), NULL, NULL, NULL); + } +#endif + + ret = mbedtls_test_ssl_endpoint_certificate_init(ep, pk_alg); + TEST_ASSERT(ret == 0); + +exit: + return ret; +} + +void mbedtls_test_ssl_endpoint_free( + mbedtls_test_ssl_endpoint *ep, + mbedtls_test_message_socket_context *context) +{ + mbedtls_endpoint_certificate_free(ep); + + mbedtls_ssl_free(&(ep->ssl)); + mbedtls_ssl_config_free(&(ep->conf)); + mbedtls_ctr_drbg_free(&(ep->ctr_drbg)); + mbedtls_entropy_free(&(ep->entropy)); + + if (context != NULL) { + mbedtls_test_message_socket_close(context); + } else { + mbedtls_test_mock_socket_close(&(ep->socket)); + } +} + +int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, + mbedtls_ssl_context *second_ssl, + int state) +{ + enum { BUFFSIZE = 1024 }; + int max_steps = 1000; + int ret = 0; + + if (ssl == NULL || second_ssl == NULL) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + /* Perform communication via connected sockets */ + while ((ssl->state != state) && (--max_steps >= 0)) { + /* If /p second_ssl ends the handshake procedure before /p ssl then + * there is no need to call the next step */ + if (second_ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { + ret = mbedtls_ssl_handshake_step(second_ssl); + if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; + } + } + + /* We only care about the \p ssl state and returns, so we call it last, + * to leave the iteration as soon as the state is as expected. */ + ret = mbedtls_ssl_handshake_step(ssl); + if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; + } + } + + return (max_steps >= 0) ? ret : -1; +} + +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && + MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ + +/* + * Write application data. Increase write counter if necessary. + */ +int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl, + unsigned char *buf, int buf_len, + int *written, + const int expected_fragments) +{ + /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is + * a valid no-op for TLS connections. */ + if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { + TEST_ASSERT(mbedtls_ssl_write(ssl, NULL, 0) == 0); + } + + int ret = mbedtls_ssl_write(ssl, buf + *written, buf_len - *written); + if (ret > 0) { + *written += ret; + } + + if (expected_fragments == 0) { + /* Used for DTLS and the message size larger than MFL. In that case + * the message can not be fragmented and the library should return + * MBEDTLS_ERR_SSL_BAD_INPUT_DATA error. This error must be returned + * to prevent a dead loop inside mbedtls_exchange_data(). */ + return ret; + } else if (expected_fragments == 1) { + /* Used for TLS/DTLS and the message size lower than MFL */ + TEST_ASSERT(ret == buf_len || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + } else { + /* Used for TLS and the message size larger than MFL */ + TEST_ASSERT(expected_fragments > 1); + TEST_ASSERT((ret >= 0 && ret <= buf_len) || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + } + + return 0; + +exit: + /* Some of the tests failed */ + return -1; +} + +/* + * Read application data and increase read counter and fragments counter + * if necessary. + */ +int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl, + unsigned char *buf, int buf_len, + int *read, int *fragments, + const int expected_fragments) +{ + /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is + * a valid no-op for TLS connections. */ + if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { + TEST_ASSERT(mbedtls_ssl_read(ssl, NULL, 0) == 0); + } + + int ret = mbedtls_ssl_read(ssl, buf + *read, buf_len - *read); + if (ret > 0) { + (*fragments)++; + *read += ret; + } + + if (expected_fragments == 0) { + TEST_ASSERT(ret == 0); + } else if (expected_fragments == 1) { + TEST_ASSERT(ret == buf_len || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + } else { + TEST_ASSERT(expected_fragments > 1); + TEST_ASSERT((ret >= 0 && ret <= buf_len) || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + } + + return 0; + +exit: + /* Some of the tests failed */ + return -1; +} + +void set_ciphersuite(mbedtls_ssl_config *conf, const char *cipher, + int *forced_ciphersuite) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + forced_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id(cipher); + forced_ciphersuite[1] = 0; + + ciphersuite_info = + mbedtls_ssl_ciphersuite_from_id(forced_ciphersuite[0]); + + TEST_ASSERT(ciphersuite_info != NULL); + TEST_ASSERT(ciphersuite_info->min_minor_ver <= conf->max_minor_ver); + TEST_ASSERT(ciphersuite_info->max_minor_ver >= conf->min_minor_ver); + + if (conf->max_minor_ver > ciphersuite_info->max_minor_ver) { + conf->max_minor_ver = ciphersuite_info->max_minor_ver; + } + if (conf->min_minor_ver < ciphersuite_info->min_minor_ver) { + conf->min_minor_ver = ciphersuite_info->min_minor_ver; + } + + mbedtls_ssl_conf_ciphersuites(conf, forced_ciphersuite); + +exit: + return; +} + +int psk_dummy_callback(void *p_info, mbedtls_ssl_context *ssl, + const unsigned char *name, size_t name_len) +{ + (void) p_info; + (void) ssl; + (void) name; + (void) name_len; + + return 0; +} + +#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX +#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX +#else +#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX +#endif + +int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in, + mbedtls_ssl_transform *t_out, + int cipher_type, int hash_id, + int etm, int tag_mode, int ver, + size_t cid0_len, + size_t cid1_len) +{ + mbedtls_cipher_info_t const *cipher_info; + int ret = 0; + + size_t keylen, maclen, ivlen; + unsigned char *key0 = NULL, *key1 = NULL; + unsigned char *md0 = NULL, *md1 = NULL; + unsigned char iv_enc[16], iv_dec[16]; + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned char cid0[SSL_CID_LEN_MIN]; + unsigned char cid1[SSL_CID_LEN_MIN]; + + mbedtls_test_rnd_std_rand(NULL, cid0, sizeof(cid0)); + mbedtls_test_rnd_std_rand(NULL, cid1, sizeof(cid1)); +#else + ((void) cid0_len); + ((void) cid1_len); +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + + maclen = 0; + + /* Pick cipher */ + cipher_info = mbedtls_cipher_info_from_type(cipher_type); + CHK(cipher_info != NULL); + CHK(cipher_info->iv_size <= 16); + CHK(cipher_info->key_bitlen % 8 == 0); + + /* Pick keys */ + keylen = cipher_info->key_bitlen / 8; + /* Allocate `keylen + 1` bytes to ensure that we get + * a non-NULL pointers from `mbedtls_calloc` even if + * `keylen == 0` in the case of the NULL cipher. */ + CHK((key0 = mbedtls_calloc(1, keylen + 1)) != NULL); + CHK((key1 = mbedtls_calloc(1, keylen + 1)) != NULL); + memset(key0, 0x1, keylen); + memset(key1, 0x2, keylen); + + /* Setup cipher contexts */ + CHK(mbedtls_cipher_setup(&t_in->cipher_ctx_enc, cipher_info) == 0); + CHK(mbedtls_cipher_setup(&t_in->cipher_ctx_dec, cipher_info) == 0); + CHK(mbedtls_cipher_setup(&t_out->cipher_ctx_enc, cipher_info) == 0); + CHK(mbedtls_cipher_setup(&t_out->cipher_ctx_dec, cipher_info) == 0); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if (cipher_info->mode == MBEDTLS_MODE_CBC) { + CHK(mbedtls_cipher_set_padding_mode(&t_in->cipher_ctx_enc, + MBEDTLS_PADDING_NONE) == 0); + CHK(mbedtls_cipher_set_padding_mode(&t_in->cipher_ctx_dec, + MBEDTLS_PADDING_NONE) == 0); + CHK(mbedtls_cipher_set_padding_mode(&t_out->cipher_ctx_enc, + MBEDTLS_PADDING_NONE) == 0); + CHK(mbedtls_cipher_set_padding_mode(&t_out->cipher_ctx_dec, + MBEDTLS_PADDING_NONE) == 0); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + CHK(mbedtls_cipher_setkey(&t_in->cipher_ctx_enc, key0, + (keylen << 3 > INT_MAX) ? INT_MAX : (int) keylen << 3, + MBEDTLS_ENCRYPT) + == 0); + CHK(mbedtls_cipher_setkey(&t_in->cipher_ctx_dec, key1, + (keylen << 3 > INT_MAX) ? INT_MAX : (int) keylen << 3, + MBEDTLS_DECRYPT) + == 0); + CHK(mbedtls_cipher_setkey(&t_out->cipher_ctx_enc, key1, + (keylen << 3 > INT_MAX) ? INT_MAX : (int) keylen << 3, + MBEDTLS_ENCRYPT) + == 0); + CHK(mbedtls_cipher_setkey(&t_out->cipher_ctx_dec, key0, + (keylen << 3 > INT_MAX) ? INT_MAX : (int) keylen << 3, + MBEDTLS_DECRYPT) + == 0); + + /* Setup MAC contexts */ +#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) + if (cipher_info->mode == MBEDTLS_MODE_CBC || + cipher_info->mode == MBEDTLS_MODE_STREAM) { + mbedtls_md_info_t const *md_info; + + /* Pick hash */ + md_info = mbedtls_md_info_from_type(hash_id); + CHK(md_info != NULL); + + /* Pick hash keys */ + maclen = mbedtls_md_get_size(md_info); + CHK((md0 = mbedtls_calloc(1, maclen)) != NULL); + CHK((md1 = mbedtls_calloc(1, maclen)) != NULL); + memset(md0, 0x5, maclen); + memset(md1, 0x6, maclen); + + CHK(mbedtls_md_setup(&t_out->md_ctx_enc, md_info, 1) == 0); + CHK(mbedtls_md_setup(&t_out->md_ctx_dec, md_info, 1) == 0); + CHK(mbedtls_md_setup(&t_in->md_ctx_enc, md_info, 1) == 0); + CHK(mbedtls_md_setup(&t_in->md_ctx_dec, md_info, 1) == 0); + + if (ver > MBEDTLS_SSL_MINOR_VERSION_0) { + CHK(mbedtls_md_hmac_starts(&t_in->md_ctx_enc, + md0, maclen) == 0); + CHK(mbedtls_md_hmac_starts(&t_in->md_ctx_dec, + md1, maclen) == 0); + CHK(mbedtls_md_hmac_starts(&t_out->md_ctx_enc, + md1, maclen) == 0); + CHK(mbedtls_md_hmac_starts(&t_out->md_ctx_dec, + md0, maclen) == 0); + } +#if defined(MBEDTLS_SSL_PROTO_SSL3) + else { + memcpy(&t_in->mac_enc, md0, maclen); + memcpy(&t_in->mac_dec, md1, maclen); + memcpy(&t_out->mac_enc, md1, maclen); + memcpy(&t_out->mac_dec, md0, maclen); + } +#endif + } +#else + ((void) hash_id); +#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ + + + /* Pick IV's (regardless of whether they + * are being used by the transform). */ + ivlen = cipher_info->iv_size; + memset(iv_enc, 0x3, sizeof(iv_enc)); + memset(iv_dec, 0x4, sizeof(iv_dec)); + + /* + * Setup transforms + */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) + t_out->encrypt_then_mac = etm; + t_in->encrypt_then_mac = etm; +#else + ((void) etm); +#endif + + t_out->minor_ver = ver; + t_in->minor_ver = ver; + t_out->ivlen = ivlen; + t_in->ivlen = ivlen; + + switch (cipher_info->mode) { + case MBEDTLS_MODE_GCM: + case MBEDTLS_MODE_CCM: +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + if (ver == MBEDTLS_SSL_MINOR_VERSION_4) { + t_out->fixed_ivlen = 12; + t_in->fixed_ivlen = 12; + } else +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + { + t_out->fixed_ivlen = 4; + t_in->fixed_ivlen = 4; + } + t_out->maclen = 0; + t_in->maclen = 0; + switch (tag_mode) { + case 0: /* Full tag */ + t_out->taglen = 16; + t_in->taglen = 16; + break; + case 1: /* Partial tag */ + t_out->taglen = 8; + t_in->taglen = 8; + break; + default: + ret = 1; + goto cleanup; + } + break; + + case MBEDTLS_MODE_CHACHAPOLY: + t_out->fixed_ivlen = 12; + t_in->fixed_ivlen = 12; + t_out->maclen = 0; + t_in->maclen = 0; + switch (tag_mode) { + case 0: /* Full tag */ + t_out->taglen = 16; + t_in->taglen = 16; + break; + case 1: /* Partial tag */ + t_out->taglen = 8; + t_in->taglen = 8; + break; + default: + ret = 1; + goto cleanup; + } + break; + + case MBEDTLS_MODE_STREAM: + case MBEDTLS_MODE_CBC: + t_out->fixed_ivlen = 0; /* redundant, must be 0 */ + t_in->fixed_ivlen = 0; /* redundant, must be 0 */ + t_out->taglen = 0; + t_in->taglen = 0; + switch (tag_mode) { + case 0: /* Full tag */ + t_out->maclen = maclen; + t_in->maclen = maclen; + break; + case 1: /* Partial tag */ + t_out->maclen = 10; + t_in->maclen = 10; + break; + default: + ret = 1; + goto cleanup; + } + break; + default: + ret = 1; + goto cleanup; + break; + } + + /* Setup IV's */ + + memcpy(&t_in->iv_dec, iv_dec, sizeof(iv_dec)); + memcpy(&t_in->iv_enc, iv_enc, sizeof(iv_enc)); + memcpy(&t_out->iv_dec, iv_enc, sizeof(iv_enc)); + memcpy(&t_out->iv_enc, iv_dec, sizeof(iv_dec)); + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* Add CID */ + memcpy(&t_in->in_cid, cid0, cid0_len); + memcpy(&t_in->out_cid, cid1, cid1_len); + t_in->in_cid_len = (uint8_t) cid0_len; + t_in->out_cid_len = (uint8_t) cid1_len; + memcpy(&t_out->in_cid, cid1, cid1_len); + memcpy(&t_out->out_cid, cid0, cid0_len); + t_out->in_cid_len = (uint8_t) cid1_len; + t_out->out_cid_len = (uint8_t) cid0_len; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +cleanup: + + mbedtls_free(key0); + mbedtls_free(key1); + + mbedtls_free(md0); + mbedtls_free(md1); + + return ret; +} + +int mbedtls_test_ssl_populate_session(mbedtls_ssl_session *session, + int ticket_len, + const char *crt_file) +{ +#if defined(MBEDTLS_HAVE_TIME) + session->start = mbedtls_time(NULL) - 42; +#endif + session->ciphersuite = 0xabcd; + session->compression = 1; + session->id_len = sizeof(session->id); + memset(session->id, 66, session->id_len); + memset(session->master, 17, sizeof(session->master)); + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_FS_IO) + if (strlen(crt_file) != 0) { + mbedtls_x509_crt tmp_crt; + int ret; + + mbedtls_x509_crt_init(&tmp_crt); + ret = mbedtls_x509_crt_parse_file(&tmp_crt, crt_file); + if (ret != 0) { + return ret; + } + +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + /* Move temporary CRT. */ + session->peer_cert = mbedtls_calloc(1, sizeof(*session->peer_cert)); + if (session->peer_cert == NULL) { + return -1; + } + *session->peer_cert = tmp_crt; + memset(&tmp_crt, 0, sizeof(tmp_crt)); +#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + /* Calculate digest of temporary CRT. */ + session->peer_cert_digest = + mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN); + if (session->peer_cert_digest == NULL) { + return -1; + } + ret = mbedtls_md(mbedtls_md_info_from_type( + MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE), + tmp_crt.raw.p, tmp_crt.raw.len, + session->peer_cert_digest); + if (ret != 0) { + return ret; + } + session->peer_cert_digest_type = + MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE; + session->peer_cert_digest_len = + MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN; +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + + mbedtls_x509_crt_free(&tmp_crt); + } +#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_FS_IO */ + (void) crt_file; +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_FS_IO */ + session->verify_result = 0xdeadbeef; + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) + if (ticket_len != 0) { + session->ticket = mbedtls_calloc(1, ticket_len); + if (session->ticket == NULL) { + return -1; + } + memset(session->ticket, 33, ticket_len); + } + session->ticket_len = ticket_len; + session->ticket_lifetime = 86401; +#else + (void) ticket_len; +#endif + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + session->mfl_code = 1; +#endif +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + session->trunc_hmac = 1; +#endif +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + session->encrypt_then_mac = 1; +#endif + + return 0; +} + +int mbedtls_exchange_data(mbedtls_ssl_context *ssl_1, + int msg_len_1, const int expected_fragments_1, + mbedtls_ssl_context *ssl_2, + int msg_len_2, const int expected_fragments_2) +{ + unsigned char *msg_buf_1 = malloc(msg_len_1); + unsigned char *msg_buf_2 = malloc(msg_len_2); + unsigned char *in_buf_1 = malloc(msg_len_2); + unsigned char *in_buf_2 = malloc(msg_len_1); + int msg_type, ret = -1; + + /* Perform this test with two message types. At first use a message + * consisting of only 0x00 for the client and only 0xFF for the server. + * At the second time use message with generated data */ + for (msg_type = 0; msg_type < 2; msg_type++) { + int written_1 = 0; + int written_2 = 0; + int read_1 = 0; + int read_2 = 0; + int fragments_1 = 0; + int fragments_2 = 0; + + if (msg_type == 0) { + memset(msg_buf_1, 0x00, msg_len_1); + memset(msg_buf_2, 0xff, msg_len_2); + } else { + int i, j = 0; + for (i = 0; i < msg_len_1; i++) { + msg_buf_1[i] = j++ & 0xFF; + } + for (i = 0; i < msg_len_2; i++) { + msg_buf_2[i] = (j -= 5) & 0xFF; + } + } + + while (read_1 < msg_len_2 || read_2 < msg_len_1) { + /* ssl_1 sending */ + if (msg_len_1 > written_1) { + ret = mbedtls_ssl_write_fragment(ssl_1, msg_buf_1, + msg_len_1, &written_1, + expected_fragments_1); + if (expected_fragments_1 == 0) { + /* This error is expected when the message is too large and + * cannot be fragmented */ + TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); + msg_len_1 = 0; + } else { + TEST_ASSERT(ret == 0); + } + } + + /* ssl_2 sending */ + if (msg_len_2 > written_2) { + ret = mbedtls_ssl_write_fragment(ssl_2, msg_buf_2, + msg_len_2, &written_2, + expected_fragments_2); + if (expected_fragments_2 == 0) { + /* This error is expected when the message is too large and + * cannot be fragmented */ + TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); + msg_len_2 = 0; + } else { + TEST_ASSERT(ret == 0); + } + } + + /* ssl_1 reading */ + if (read_1 < msg_len_2) { + ret = mbedtls_ssl_read_fragment(ssl_1, in_buf_1, + msg_len_2, &read_1, + &fragments_2, + expected_fragments_2); + TEST_ASSERT(ret == 0); + } + + /* ssl_2 reading */ + if (read_2 < msg_len_1) { + ret = mbedtls_ssl_read_fragment(ssl_2, in_buf_2, + msg_len_1, &read_2, + &fragments_1, + expected_fragments_1); + TEST_ASSERT(ret == 0); + } + } + + ret = -1; + TEST_ASSERT(0 == memcmp(msg_buf_1, in_buf_2, msg_len_1)); + TEST_ASSERT(0 == memcmp(msg_buf_2, in_buf_1, msg_len_2)); + TEST_ASSERT(fragments_1 == expected_fragments_1); + TEST_ASSERT(fragments_2 == expected_fragments_2); + } + + ret = 0; + +exit: + free(msg_buf_1); + free(in_buf_1); + free(msg_buf_2); + free(in_buf_2); + + return ret; +} + +/* + * Perform data exchanging between \p ssl_1 and \p ssl_2. Both of endpoints + * must be initialized and connected beforehand. + * + * \retval 0 on success, otherwise error code. + */ +int exchange_data(mbedtls_ssl_context *ssl_1, + mbedtls_ssl_context *ssl_2) +{ + return mbedtls_exchange_data(ssl_1, 256, 1, + ssl_2, 256, 1); +} + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_CERTS_C) && \ + defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_C) +void mbedtls_test_ssl_perform_handshake( + mbedtls_test_handshake_test_options *options) +{ + /* forced_ciphersuite needs to last until the end of the handshake */ + int forced_ciphersuite[2]; + enum { BUFFSIZE = 17000 }; + mbedtls_test_ssl_endpoint client, server; +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + const char *psk_identity = "foo"; +#endif +#if defined(MBEDTLS_TIMING_C) + mbedtls_timing_delay_context timer_client, timer_server; +#endif +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) + unsigned char *context_buf = NULL; + size_t context_buf_len; +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int ret = -1; +#endif + int expected_handshake_result = 0; + + USE_PSA_INIT(); + mbedtls_platform_zeroize(&client, sizeof(client)); + mbedtls_platform_zeroize(&server, sizeof(server)); + + mbedtls_test_ssl_message_queue server_queue, client_queue; + mbedtls_test_message_socket_context server_context, client_context; + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); + + /* Client side */ + if (options->dtls != 0) { + TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client, + MBEDTLS_SSL_IS_CLIENT, + options->pk_alg, + &client_context, + &client_queue, + &server_queue, NULL) == 0); +#if defined(MBEDTLS_TIMING_C) + mbedtls_ssl_set_timer_cb(&client.ssl, &timer_client, + mbedtls_timing_set_delay, + mbedtls_timing_get_delay); +#endif + } else { + TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client, + MBEDTLS_SSL_IS_CLIENT, + options->pk_alg, NULL, NULL, + NULL, NULL) == 0); + } + + if (options->client_min_version != TEST_SSL_MINOR_VERSION_NONE) { + mbedtls_ssl_conf_min_version(&client.conf, MBEDTLS_SSL_MAJOR_VERSION_3, + options->client_min_version); + } + + if (options->client_max_version != TEST_SSL_MINOR_VERSION_NONE) { + mbedtls_ssl_conf_max_version(&client.conf, MBEDTLS_SSL_MAJOR_VERSION_3, + options->client_max_version); + } + + if (strlen(options->cipher) > 0) { + set_ciphersuite(&client.conf, options->cipher, forced_ciphersuite); + } + +#if defined(MBEDTLS_DEBUG_C) + if (options->cli_log_fun) { + mbedtls_debug_set_threshold(4); + mbedtls_ssl_conf_dbg(&client.conf, options->cli_log_fun, + options->cli_log_obj); + } +#endif + + /* Server side */ + if (options->dtls != 0) { + TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server, + MBEDTLS_SSL_IS_SERVER, + options->pk_alg, + &server_context, + &server_queue, + &client_queue, NULL) == 0); +#if defined(MBEDTLS_TIMING_C) + mbedtls_ssl_set_timer_cb(&server.ssl, &timer_server, + mbedtls_timing_set_delay, + mbedtls_timing_get_delay); +#endif + } else { + TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server, + MBEDTLS_SSL_IS_SERVER, + options->pk_alg, NULL, NULL, + NULL, NULL) == 0); + } + + mbedtls_ssl_conf_authmode(&server.conf, options->srv_auth_mode); + + if (options->server_min_version != TEST_SSL_MINOR_VERSION_NONE) { + mbedtls_ssl_conf_min_version(&server.conf, MBEDTLS_SSL_MAJOR_VERSION_3, + options->server_min_version); + } + + if (options->server_max_version != TEST_SSL_MINOR_VERSION_NONE) { + mbedtls_ssl_conf_max_version(&server.conf, MBEDTLS_SSL_MAJOR_VERSION_3, + options->server_max_version); + } + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + TEST_ASSERT(mbedtls_ssl_conf_max_frag_len(&(server.conf), + (unsigned char) options->mfl) + == 0); + TEST_ASSERT(mbedtls_ssl_conf_max_frag_len(&(client.conf), + (unsigned char) options->mfl) + == 0); +#else + TEST_ASSERT(MBEDTLS_SSL_MAX_FRAG_LEN_NONE == options->mfl); +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + if (options->psk_str != NULL && options->psk_str->len > 0) { + TEST_ASSERT(mbedtls_ssl_conf_psk( + &client.conf, options->psk_str->x, + options->psk_str->len, + (const unsigned char *) psk_identity, + strlen(psk_identity)) == 0); + + TEST_ASSERT(mbedtls_ssl_conf_psk( + &server.conf, options->psk_str->x, + options->psk_str->len, + (const unsigned char *) psk_identity, + strlen(psk_identity)) == 0); + + mbedtls_ssl_conf_psk_cb(&server.conf, psk_dummy_callback, NULL); + } +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if (options->renegotiate) { + mbedtls_ssl_conf_renegotiation(&(server.conf), + MBEDTLS_SSL_RENEGOTIATION_ENABLED); + mbedtls_ssl_conf_renegotiation(&(client.conf), + MBEDTLS_SSL_RENEGOTIATION_ENABLED); + + mbedtls_ssl_conf_legacy_renegotiation(&(server.conf), + options->legacy_renegotiation); + mbedtls_ssl_conf_legacy_renegotiation(&(client.conf), + options->legacy_renegotiation); + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +#if defined(MBEDTLS_DEBUG_C) + if (options->srv_log_fun) { + mbedtls_debug_set_threshold(4); + mbedtls_ssl_conf_dbg(&server.conf, options->srv_log_fun, + options->srv_log_obj); + } +#endif + + TEST_ASSERT(mbedtls_test_mock_socket_connect(&(client.socket), + &(server.socket), + BUFFSIZE) == 0); + +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + if (options->resize_buffers != 0) { + /* Ensure that the buffer sizes are appropriate before resizes */ + TEST_ASSERT(client.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); + TEST_ASSERT(client.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); + TEST_ASSERT(server.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); + TEST_ASSERT(server.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); + } +#endif + + if (options->expected_negotiated_version == TEST_SSL_MINOR_VERSION_NONE) { + expected_handshake_result = MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION; + } + + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(client.ssl), &(server.ssl), MBEDTLS_SSL_HANDSHAKE_OVER) + == expected_handshake_result); + + if (expected_handshake_result != 0) { + /* Connection will have failed by this point, skip to cleanup */ + goto exit; + } + + TEST_ASSERT(client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER); + TEST_ASSERT(server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER); + + /* Check that we agree on the version... */ + TEST_ASSERT(client.ssl.minor_ver == server.ssl.minor_ver); + + /* And check that the version negotiated is the expected one. */ + TEST_EQUAL(client.ssl.minor_ver, options->expected_negotiated_version); + +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + if (options->resize_buffers != 0) { + if (options->expected_negotiated_version != MBEDTLS_SSL_MINOR_VERSION_0 && + options->expected_negotiated_version != MBEDTLS_SSL_MINOR_VERSION_1) { + /* A server, when using DTLS, might delay a buffer resize to happen + * after it receives a message, so we force it. */ + TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); + + TEST_ASSERT(client.ssl.out_buf_len == + mbedtls_ssl_get_output_buflen(&client.ssl)); + TEST_ASSERT(client.ssl.in_buf_len == + mbedtls_ssl_get_input_buflen(&client.ssl)); + TEST_ASSERT(server.ssl.out_buf_len == + mbedtls_ssl_get_output_buflen(&server.ssl)); + TEST_ASSERT(server.ssl.in_buf_len == + mbedtls_ssl_get_input_buflen(&server.ssl)); + } + } +#endif + + if (options->cli_msg_len != 0 || options->srv_msg_len != 0) { + /* Start data exchanging test */ + TEST_ASSERT(mbedtls_exchange_data(&(client.ssl), options->cli_msg_len, + options->expected_cli_fragments, + &(server.ssl), options->srv_msg_len, + options->expected_srv_fragments) + == 0); + } +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) + if (options->serialize == 1) { + TEST_ASSERT(options->dtls == 1); + + TEST_ASSERT(mbedtls_ssl_context_save(&(server.ssl), NULL, + 0, &context_buf_len) + == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); + + context_buf = mbedtls_calloc(1, context_buf_len); + TEST_ASSERT(context_buf != NULL); + + TEST_ASSERT(mbedtls_ssl_context_save(&(server.ssl), context_buf, + context_buf_len, + &context_buf_len) + == 0); + + mbedtls_ssl_free(&(server.ssl)); + mbedtls_ssl_init(&(server.ssl)); + + TEST_ASSERT(mbedtls_ssl_setup(&(server.ssl), &(server.conf)) == 0); + + mbedtls_ssl_set_bio(&(server.ssl), &server_context, + mbedtls_test_mock_tcp_send_msg, + mbedtls_test_mock_tcp_recv_msg, + NULL); + +#if defined(MBEDTLS_TIMING_C) + mbedtls_ssl_set_timer_cb(&server.ssl, &timer_server, + mbedtls_timing_set_delay, + mbedtls_timing_get_delay); +#endif +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + if (options->resize_buffers != 0) { + /* Ensure that the buffer sizes are appropriate before resizes */ + TEST_ASSERT(server.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); + TEST_ASSERT(server.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); + } +#endif + TEST_ASSERT(mbedtls_ssl_context_load(&(server.ssl), context_buf, + context_buf_len) == 0); + +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + /* Validate buffer sizes after context deserialization */ + if (options->resize_buffers != 0) { + TEST_ASSERT(server.ssl.out_buf_len == + mbedtls_ssl_get_output_buflen(&server.ssl)); + TEST_ASSERT(server.ssl.in_buf_len == + mbedtls_ssl_get_input_buflen(&server.ssl)); + } +#endif + /* Retest writing/reading */ + if (options->cli_msg_len != 0 || options->srv_msg_len != 0) { + TEST_ASSERT(mbedtls_exchange_data( + &(client.ssl), + options->cli_msg_len, + options->expected_cli_fragments, + &(server.ssl), + options->srv_msg_len, + options->expected_srv_fragments) + == 0); + } + } +#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if (options->renegotiate) { + /* Start test with renegotiation */ + TEST_ASSERT(server.ssl.renego_status == + MBEDTLS_SSL_INITIAL_HANDSHAKE); + TEST_ASSERT(client.ssl.renego_status == + MBEDTLS_SSL_INITIAL_HANDSHAKE); + + /* After calling this function for the server, it only sends a handshake + * request. All renegotiation should happen during data exchanging */ + TEST_ASSERT(mbedtls_ssl_renegotiate(&(server.ssl)) == 0); + TEST_ASSERT(server.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_PENDING); + TEST_ASSERT(client.ssl.renego_status == + MBEDTLS_SSL_INITIAL_HANDSHAKE); + + TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); + TEST_ASSERT(server.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_DONE); + TEST_ASSERT(client.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_DONE); + + /* After calling mbedtls_ssl_renegotiate for the client, + * all renegotiation should happen inside this function. + * However in this test, we cannot perform simultaneous communication + * between client and server so this function will return waiting error + * on the socket. All rest of renegotiation should happen + * during data exchanging */ + ret = mbedtls_ssl_renegotiate(&(client.ssl)); +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + if (options->resize_buffers != 0) { + /* Ensure that the buffer sizes are appropriate before resizes */ + TEST_ASSERT(client.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); + TEST_ASSERT(client.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); + } +#endif + TEST_ASSERT(ret == 0 || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + TEST_ASSERT(server.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_DONE); + TEST_ASSERT(client.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS); + + TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); + TEST_ASSERT(server.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_DONE); + TEST_ASSERT(client.ssl.renego_status == + MBEDTLS_SSL_RENEGOTIATION_DONE); +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + /* Validate buffer sizes after renegotiation */ + if (options->resize_buffers != 0) { + TEST_ASSERT(client.ssl.out_buf_len == + mbedtls_ssl_get_output_buflen(&client.ssl)); + TEST_ASSERT(client.ssl.in_buf_len == + mbedtls_ssl_get_input_buflen(&client.ssl)); + TEST_ASSERT(server.ssl.out_buf_len == + mbedtls_ssl_get_output_buflen(&server.ssl)); + TEST_ASSERT(server.ssl.in_buf_len == + mbedtls_ssl_get_input_buflen(&server.ssl)); + } +#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */ + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +exit: + mbedtls_test_ssl_endpoint_free(&client, + options->dtls != 0 ? &client_context : NULL); + mbedtls_test_ssl_endpoint_free(&server, + options->dtls != 0 ? &server_context : NULL); +#if defined(MBEDTLS_DEBUG_C) + if (options->cli_log_fun || options->srv_log_fun) { + mbedtls_debug_set_threshold(0); + } +#endif +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) + if (context_buf != NULL) { + mbedtls_free(context_buf); + } +#endif +} +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && + MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ + +#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index eb0dc03fb..efe840870 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -80,25 +80,6 @@ jmp_buf jmp_tmp; /*----------------------------------------------------------------------------*/ /* Helper Functions */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -/** Check that no PSA Crypto key slots are in use. - * - * If any slots are in use, mark the current test as failed. - * - * \return 0 if the key store is empty, 1 otherwise. - */ -int test_fail_if_psa_leaking(int line_no, const char *filename) -{ - const char *msg = mbedtls_test_helper_is_psa_leaking(); - if (msg == NULL) { - return 0; - } else { - mbedtls_test_fail(msg, line_no, filename); - return 1; - } -} -#endif /* defined(MBEDTLS_PSA_CRYPTO_C) */ - #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) static int redirect_output(FILE *out_stream, const char *path) { diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 39825ed96..996ba98f2 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1,2024 +1,10 @@ /* BEGIN_HEADER */ -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY -#endif - -enum { -#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ - tls1_3_label_ ## name, - MBEDTLS_SSL_TLS1_3_LABEL_LIST -#undef MBEDTLS_SSL_TLS1_3_LABEL -}; - -typedef struct log_pattern { - const char *pattern; - size_t counter; -} log_pattern; - -/* - * This function can be passed to mbedtls to receive output logs from it. In - * this case, it will count the instances of a log_pattern in the received - * logged messages. - */ -void log_analyzer(void *ctx, int level, - const char *file, int line, - const char *str) -{ - log_pattern *p = (log_pattern *) ctx; - - (void) level; - (void) line; - (void) file; - - if (NULL != p && - NULL != p->pattern && - NULL != strstr(str, p->pattern)) { - p->counter++; - } -} - -/* Invalid minor version used when not specifying a min/max version or expecting a test to fail */ -#define TEST_SSL_MINOR_VERSION_NONE -1 - -typedef struct handshake_test_options { - const char *cipher; - int client_min_version; - int client_max_version; - int server_min_version; - int server_max_version; - int expected_negotiated_version; - int pk_alg; - data_t *psk_str; - int dtls; - int srv_auth_mode; - int serialize; - int mfl; - int cli_msg_len; - int srv_msg_len; - int expected_cli_fragments; - int expected_srv_fragments; - int renegotiate; - int legacy_renegotiation; - void *srv_log_obj; - void *cli_log_obj; - void (*srv_log_fun)(void *, int, const char *, int, const char *); - void (*cli_log_fun)(void *, int, const char *, int, const char *); - int resize_buffers; -} handshake_test_options; - -void init_handshake_options(handshake_test_options *opts) -{ - opts->cipher = ""; - opts->client_min_version = TEST_SSL_MINOR_VERSION_NONE; - opts->client_max_version = TEST_SSL_MINOR_VERSION_NONE; - opts->server_min_version = TEST_SSL_MINOR_VERSION_NONE; - opts->server_max_version = TEST_SSL_MINOR_VERSION_NONE; - opts->expected_negotiated_version = MBEDTLS_SSL_MINOR_VERSION_3; - opts->pk_alg = MBEDTLS_PK_RSA; - opts->psk_str = NULL; - opts->dtls = 0; - opts->srv_auth_mode = MBEDTLS_SSL_VERIFY_NONE; - opts->serialize = 0; - opts->mfl = MBEDTLS_SSL_MAX_FRAG_LEN_NONE; - opts->cli_msg_len = 100; - opts->srv_msg_len = 100; - opts->expected_cli_fragments = 1; - opts->expected_srv_fragments = 1; - opts->renegotiate = 0; - opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; - opts->srv_log_obj = NULL; - opts->srv_log_obj = NULL; - opts->srv_log_fun = NULL; - opts->cli_log_fun = NULL; - opts->resize_buffers = 1; -} -/* - * Buffer structure for custom I/O callbacks. - */ - -typedef struct mbedtls_test_buffer { - size_t start; - size_t content_length; - size_t capacity; - unsigned char *buffer; -} mbedtls_test_buffer; - -/* - * Initialises \p buf. After calling this function it is safe to call - * `mbedtls_test_buffer_free()` on \p buf. - */ -void mbedtls_test_buffer_init(mbedtls_test_buffer *buf) -{ - memset(buf, 0, sizeof(*buf)); -} - -/* - * Sets up \p buf. After calling this function it is safe to call - * `mbedtls_test_buffer_put()` and `mbedtls_test_buffer_get()` on \p buf. - */ -int mbedtls_test_buffer_setup(mbedtls_test_buffer *buf, size_t capacity) -{ - buf->buffer = (unsigned char *) mbedtls_calloc(capacity, - sizeof(unsigned char)); - if (NULL == buf->buffer) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - buf->capacity = capacity; - - return 0; -} - -void mbedtls_test_buffer_free(mbedtls_test_buffer *buf) -{ - if (buf->buffer != NULL) { - mbedtls_free(buf->buffer); - } - - memset(buf, 0, sizeof(*buf)); -} - -/* - * Puts \p input_len bytes from the \p input buffer into the ring buffer \p buf. - * - * \p buf must have been initialized and set up by calling - * `mbedtls_test_buffer_init()` and `mbedtls_test_buffer_setup()`. - * - * \retval \p input_len, if the data fits. - * \retval 0 <= value < \p input_len, if the data does not fit. - * \retval -1, if \p buf is NULL, it hasn't been set up or \p input_len is not - * zero and \p input is NULL. - */ -int mbedtls_test_buffer_put(mbedtls_test_buffer *buf, - const unsigned char *input, size_t input_len) -{ - size_t overflow = 0; - - if ((buf == NULL) || (buf->buffer == NULL)) { - return -1; - } - - /* Reduce input_len to a number that fits in the buffer. */ - if ((buf->content_length + input_len) > buf->capacity) { - input_len = buf->capacity - buf->content_length; - } - - if (input == NULL) { - return (input_len == 0) ? 0 : -1; - } - - /* Check if the buffer has not come full circle and free space is not in - * the middle */ - if (buf->start + buf->content_length < buf->capacity) { - - /* Calculate the number of bytes that need to be placed at lower memory - * address */ - if (buf->start + buf->content_length + input_len - > buf->capacity) { - overflow = (buf->start + buf->content_length + input_len) - % buf->capacity; - } - - memcpy(buf->buffer + buf->start + buf->content_length, input, - input_len - overflow); - memcpy(buf->buffer, input + input_len - overflow, overflow); - - } else { - /* The buffer has come full circle and free space is in the middle */ - memcpy(buf->buffer + buf->start + buf->content_length - buf->capacity, - input, input_len); - } - - buf->content_length += input_len; - return input_len; -} - -/* - * Gets \p output_len bytes from the ring buffer \p buf into the - * \p output buffer. The output buffer can be NULL, in this case a part of the - * ring buffer will be dropped, if the requested length is available. - * - * \p buf must have been initialized and set up by calling - * `mbedtls_test_buffer_init()` and `mbedtls_test_buffer_setup()`. - * - * \retval \p output_len, if the data is available. - * \retval 0 <= value < \p output_len, if the data is not available. - * \retval -1, if \buf is NULL or it hasn't been set up. - */ -int mbedtls_test_buffer_get(mbedtls_test_buffer *buf, - unsigned char *output, size_t output_len) -{ - size_t overflow = 0; - - if ((buf == NULL) || (buf->buffer == NULL)) { - return -1; - } - - if (output == NULL && output_len == 0) { - return 0; - } - - if (buf->content_length < output_len) { - output_len = buf->content_length; - } - - /* Calculate the number of bytes that need to be drawn from lower memory - * address */ - if (buf->start + output_len > buf->capacity) { - overflow = (buf->start + output_len) % buf->capacity; - } - - if (output != NULL) { - memcpy(output, buf->buffer + buf->start, output_len - overflow); - memcpy(output + output_len - overflow, buf->buffer, overflow); - } - - buf->content_length -= output_len; - buf->start = (buf->start + output_len) % buf->capacity; - - return output_len; -} - -/* - * Errors used in the message transport mock tests - */ - #define MBEDTLS_TEST_ERROR_ARG_NULL -11 - #define MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED -44 - -/* - * Context for a message metadata queue (fifo) that is on top of the ring buffer. - */ -typedef struct mbedtls_test_message_queue { - size_t *messages; - int pos; - int num; - int capacity; -} mbedtls_test_message_queue; - -/* - * Setup and free functions for the message metadata queue. - * - * \p capacity describes the number of message metadata chunks that can be held - * within the queue. - * - * \retval 0, if a metadata queue of a given length can be allocated. - * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation failed. - */ -int mbedtls_test_message_queue_setup(mbedtls_test_message_queue *queue, - size_t capacity) -{ - queue->messages = (size_t *) mbedtls_calloc(capacity, sizeof(size_t)); - if (NULL == queue->messages) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - queue->capacity = capacity; - queue->pos = 0; - queue->num = 0; - - return 0; -} - -void mbedtls_test_message_queue_free(mbedtls_test_message_queue *queue) -{ - if (queue == NULL) { - return; - } - - if (queue->messages != NULL) { - mbedtls_free(queue->messages); - } - - memset(queue, 0, sizeof(*queue)); -} - -/* - * Push message length information onto the message metadata queue. - * This will become the last element to leave it (fifo). - * - * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. - * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the queue is full. - * \retval \p len, if the push was successful. - */ -int mbedtls_test_message_queue_push_info(mbedtls_test_message_queue *queue, - size_t len) -{ - int place; - if (queue == NULL) { - return MBEDTLS_TEST_ERROR_ARG_NULL; - } - - if (queue->num >= queue->capacity) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - - place = (queue->pos + queue->num) % queue->capacity; - queue->messages[place] = len; - queue->num++; - return len; -} - -/* - * Pop information about the next message length from the queue. This will be - * the oldest inserted message length(fifo). \p msg_len can be null, in which - * case the data will be popped from the queue but not copied anywhere. - * - * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. - * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty. - * \retval message length, if the pop was successful, up to the given - \p buf_len. - */ -int mbedtls_test_message_queue_pop_info(mbedtls_test_message_queue *queue, - size_t buf_len) -{ - size_t message_length; - if (queue == NULL) { - return MBEDTLS_TEST_ERROR_ARG_NULL; - } - if (queue->num == 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - message_length = queue->messages[queue->pos]; - queue->messages[queue->pos] = 0; - queue->num--; - queue->pos++; - queue->pos %= queue->capacity; - if (queue->pos < 0) { - queue->pos += queue->capacity; - } - - return (message_length > buf_len) ? buf_len : message_length; -} - -/* - * Take a peek on the info about the next message length from the queue. - * This will be the oldest inserted message length(fifo). - * - * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. - * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty. - * \retval 0, if the peek was successful. - * \retval MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED, if the given buffer length is - * too small to fit the message. In this case the \p msg_len will be - * set to the full message length so that the - * caller knows what portion of the message can be dropped. - */ -int mbedtls_test_message_queue_peek_info(mbedtls_test_message_queue *queue, - size_t buf_len, size_t *msg_len) -{ - if (queue == NULL || msg_len == NULL) { - return MBEDTLS_TEST_ERROR_ARG_NULL; - } - if (queue->num == 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - *msg_len = queue->messages[queue->pos]; - return (*msg_len > buf_len) ? MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED : 0; -} -/* - * Context for the I/O callbacks simulating network connection. - */ - -#define MBEDTLS_MOCK_SOCKET_CONNECTED 1 - -typedef struct mbedtls_mock_socket { - int status; - mbedtls_test_buffer *input; - mbedtls_test_buffer *output; - struct mbedtls_mock_socket *peer; -} mbedtls_mock_socket; - -/* - * Setup and teardown functions for mock sockets. - */ -void mbedtls_mock_socket_init(mbedtls_mock_socket *socket) -{ - memset(socket, 0, sizeof(*socket)); -} - -/* - * Closes the socket \p socket. - * - * \p socket must have been previously initialized by calling - * mbedtls_mock_socket_init(). - * - * This function frees all allocated resources and both sockets are aware of the - * new connection state. - * - * That is, this function does not simulate half-open TCP connections and the - * phenomenon that when closing a UDP connection the peer is not aware of the - * connection having been closed. - */ -void mbedtls_mock_socket_close(mbedtls_mock_socket *socket) -{ - if (socket == NULL) { - return; - } - - if (socket->input != NULL) { - mbedtls_test_buffer_free(socket->input); - mbedtls_free(socket->input); - } - - if (socket->output != NULL) { - mbedtls_test_buffer_free(socket->output); - mbedtls_free(socket->output); - } - - if (socket->peer != NULL) { - memset(socket->peer, 0, sizeof(*socket->peer)); - } - - memset(socket, 0, sizeof(*socket)); -} - -/* - * Establishes a connection between \p peer1 and \p peer2. - * - * \p peer1 and \p peer2 must have been previously initialized by calling - * mbedtls_mock_socket_init(). - * - * The capacities of the internal buffers are set to \p bufsize. Setting this to - * the correct value allows for simulation of MTU, sanity testing the mock - * implementation and mocking TCP connections with lower memory cost. - */ -int mbedtls_mock_socket_connect(mbedtls_mock_socket *peer1, - mbedtls_mock_socket *peer2, - size_t bufsize) -{ - int ret = -1; - - peer1->output = - (mbedtls_test_buffer *) mbedtls_calloc(1, sizeof(mbedtls_test_buffer)); - if (peer1->output == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - mbedtls_test_buffer_init(peer1->output); - if (0 != (ret = mbedtls_test_buffer_setup(peer1->output, bufsize))) { - goto exit; - } - - peer2->output = - (mbedtls_test_buffer *) mbedtls_calloc(1, sizeof(mbedtls_test_buffer)); - if (peer2->output == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - mbedtls_test_buffer_init(peer2->output); - if (0 != (ret = mbedtls_test_buffer_setup(peer2->output, bufsize))) { - goto exit; - } - - peer1->peer = peer2; - peer2->peer = peer1; - peer1->input = peer2->output; - peer2->input = peer1->output; - - peer1->status = peer2->status = MBEDTLS_MOCK_SOCKET_CONNECTED; - ret = 0; - -exit: - - if (ret != 0) { - mbedtls_mock_socket_close(peer1); - mbedtls_mock_socket_close(peer2); - } - - return ret; -} - -/* - * Callbacks for simulating blocking I/O over connection-oriented transport. - */ - -int mbedtls_mock_tcp_send_b(void *ctx, const unsigned char *buf, size_t len) -{ - mbedtls_mock_socket *socket = (mbedtls_mock_socket *) ctx; - - if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { - return -1; - } - - return mbedtls_test_buffer_put(socket->output, buf, len); -} - -int mbedtls_mock_tcp_recv_b(void *ctx, unsigned char *buf, size_t len) -{ - mbedtls_mock_socket *socket = (mbedtls_mock_socket *) ctx; - - if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { - return -1; - } - - return mbedtls_test_buffer_get(socket->input, buf, len); -} - -/* - * Callbacks for simulating non-blocking I/O over connection-oriented transport. - */ - -int mbedtls_mock_tcp_send_nb(void *ctx, const unsigned char *buf, size_t len) -{ - mbedtls_mock_socket *socket = (mbedtls_mock_socket *) ctx; - - if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { - return -1; - } - - if (socket->output->capacity == socket->output->content_length) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - - return mbedtls_test_buffer_put(socket->output, buf, len); -} - -int mbedtls_mock_tcp_recv_nb(void *ctx, unsigned char *buf, size_t len) -{ - mbedtls_mock_socket *socket = (mbedtls_mock_socket *) ctx; - - if (socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED) { - return -1; - } - - if (socket->input->content_length == 0) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - return mbedtls_test_buffer_get(socket->input, buf, len); -} - -/* Errors used in the message socket mocks */ - -#define MBEDTLS_TEST_ERROR_CONTEXT_ERROR -55 -#define MBEDTLS_TEST_ERROR_SEND_FAILED -66 -#define MBEDTLS_TEST_ERROR_RECV_FAILED -77 - -/* - * Structure used as an addon, or a wrapper, around the mocked sockets. - * Contains an input queue, to which the other socket pushes metadata, - * and an output queue, to which this one pushes metadata. This context is - * considered as an owner of the input queue only, which is initialized and - * freed in the respective setup and free calls. - */ -typedef struct mbedtls_test_message_socket_context { - mbedtls_test_message_queue *queue_input; - mbedtls_test_message_queue *queue_output; - mbedtls_mock_socket *socket; -} mbedtls_test_message_socket_context; - -void mbedtls_message_socket_init(mbedtls_test_message_socket_context *ctx) -{ - ctx->queue_input = NULL; - ctx->queue_output = NULL; - ctx->socket = NULL; -} - -/* - * Setup a given message socket context including initialization of - * input/output queues to a chosen capacity of messages. Also set the - * corresponding mock socket. - * - * \retval 0, if everything succeeds. - * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation of a message - * queue failed. - */ -int mbedtls_message_socket_setup(mbedtls_test_message_queue *queue_input, - mbedtls_test_message_queue *queue_output, - size_t queue_capacity, - mbedtls_mock_socket *socket, - mbedtls_test_message_socket_context *ctx) -{ - int ret = mbedtls_test_message_queue_setup(queue_input, queue_capacity); - if (ret != 0) { - return ret; - } - ctx->queue_input = queue_input; - ctx->queue_output = queue_output; - ctx->socket = socket; - mbedtls_mock_socket_init(socket); - - return 0; -} - -/* - * Close a given message socket context, along with the socket itself. Free the - * memory allocated by the input queue. - */ -void mbedtls_message_socket_close(mbedtls_test_message_socket_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_test_message_queue_free(ctx->queue_input); - mbedtls_mock_socket_close(ctx->socket); - memset(ctx, 0, sizeof(*ctx)); -} - -/* - * Send one message through a given message socket context. - * - * \retval \p len, if everything succeeds. - * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context - * elements or the context itself is null. - * \retval MBEDTLS_TEST_ERROR_SEND_FAILED if mbedtls_mock_tcp_send_b failed. - * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the output queue is full. - * - * This function will also return any error from - * mbedtls_test_message_queue_push_info. - */ -int mbedtls_mock_tcp_send_msg(void *ctx, const unsigned char *buf, size_t len) -{ - mbedtls_test_message_queue *queue; - mbedtls_mock_socket *socket; - mbedtls_test_message_socket_context *context = (mbedtls_test_message_socket_context *) ctx; - - if (context == NULL || context->socket == NULL - || context->queue_output == NULL) { - return MBEDTLS_TEST_ERROR_CONTEXT_ERROR; - } - - queue = context->queue_output; - socket = context->socket; - - if (queue->num >= queue->capacity) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - - if (mbedtls_mock_tcp_send_b(socket, buf, len) != (int) len) { - return MBEDTLS_TEST_ERROR_SEND_FAILED; - } - - return mbedtls_test_message_queue_push_info(queue, len); -} - -/* - * Receive one message from a given message socket context and return message - * length or an error. - * - * \retval message length, if everything succeeds. - * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context - * elements or the context itself is null. - * \retval MBEDTLS_TEST_ERROR_RECV_FAILED if mbedtls_mock_tcp_recv_b failed. - * - * This function will also return any error other than - * MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED from mbedtls_test_message_queue_peek_info. - */ -int mbedtls_mock_tcp_recv_msg(void *ctx, unsigned char *buf, size_t buf_len) -{ - mbedtls_test_message_queue *queue; - mbedtls_mock_socket *socket; - mbedtls_test_message_socket_context *context = (mbedtls_test_message_socket_context *) ctx; - size_t drop_len = 0; - size_t msg_len; - int ret; - - if (context == NULL || context->socket == NULL - || context->queue_input == NULL) { - return MBEDTLS_TEST_ERROR_CONTEXT_ERROR; - } - - queue = context->queue_input; - socket = context->socket; - - /* Peek first, so that in case of a socket error the data remains in - * the queue. */ - ret = mbedtls_test_message_queue_peek_info(queue, buf_len, &msg_len); - if (ret == MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED) { - /* Calculate how much to drop */ - drop_len = msg_len - buf_len; - - /* Set the requested message len to be buffer length */ - msg_len = buf_len; - } else if (ret != 0) { - return ret; - } - - if (mbedtls_mock_tcp_recv_b(socket, buf, msg_len) != (int) msg_len) { - return MBEDTLS_TEST_ERROR_RECV_FAILED; - } - - if (ret == MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED) { - /* Drop the remaining part of the message */ - if (mbedtls_mock_tcp_recv_b(socket, NULL, drop_len) != (int) drop_len) { - /* Inconsistent state - part of the message was read, - * and a part couldn't. Not much we can do here, but it should not - * happen in test environment, unless forced manually. */ - } - } - mbedtls_test_message_queue_pop_info(queue, buf_len); - - return msg_len; -} - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ - defined(MBEDTLS_CERTS_C) && \ - defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_CTR_DRBG_C) - -/* - * Structure with endpoint's certificates for SSL communication tests. - */ -typedef struct mbedtls_endpoint_certificate { - mbedtls_x509_crt *ca_cert; - mbedtls_x509_crt *cert; - mbedtls_pk_context *pkey; -} mbedtls_endpoint_certificate; - -/* - * Endpoint structure for SSL communication tests. - */ -typedef struct mbedtls_endpoint { - const char *name; - mbedtls_ssl_context ssl; - mbedtls_ssl_config conf; - mbedtls_ctr_drbg_context ctr_drbg; - mbedtls_entropy_context entropy; - mbedtls_mock_socket socket; - mbedtls_endpoint_certificate cert; -} mbedtls_endpoint; - -/* - * Deinitializes certificates from endpoint represented by \p ep. - */ -void mbedtls_endpoint_certificate_free(mbedtls_endpoint *ep) -{ - mbedtls_endpoint_certificate *cert = &(ep->cert); - if (cert != NULL) { - if (cert->ca_cert != NULL) { - mbedtls_x509_crt_free(cert->ca_cert); - mbedtls_free(cert->ca_cert); - cert->ca_cert = NULL; - } - if (cert->cert != NULL) { - mbedtls_x509_crt_free(cert->cert); - mbedtls_free(cert->cert); - cert->cert = NULL; - } - if (cert->pkey != NULL) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(cert->pkey) == MBEDTLS_PK_OPAQUE) { - mbedtls_svc_key_id_t *key_slot = cert->pkey->pk_ctx; - psa_destroy_key(*key_slot); - } -#endif - mbedtls_pk_free(cert->pkey); - mbedtls_free(cert->pkey); - cert->pkey = NULL; - } - } -} - -/* - * Initializes \p ep_cert structure and assigns it to endpoint - * represented by \p ep. - * - * \retval 0 on success, otherwise error code. - */ -int mbedtls_endpoint_certificate_init(mbedtls_endpoint *ep, int pk_alg) -{ - int i = 0; - int ret = -1; - mbedtls_endpoint_certificate *cert = NULL; - - if (ep == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - cert = &(ep->cert); - ASSERT_ALLOC(cert->ca_cert, 1); - ASSERT_ALLOC(cert->cert, 1); - ASSERT_ALLOC(cert->pkey, 1); - - mbedtls_x509_crt_init(cert->ca_cert); - mbedtls_x509_crt_init(cert->cert); - mbedtls_pk_init(cert->pkey); - - /* Load the trusted CA */ - - for (i = 0; mbedtls_test_cas_der[i] != NULL; i++) { - ret = mbedtls_x509_crt_parse_der(cert->ca_cert, - (const unsigned char *) mbedtls_test_cas_der[i], - mbedtls_test_cas_der_len[i]); - TEST_ASSERT(ret == 0); - } - - /* Load own certificate and private key */ - - if (ep->conf.endpoint == MBEDTLS_SSL_IS_SERVER) { - if (pk_alg == MBEDTLS_PK_RSA) { - ret = mbedtls_x509_crt_parse(cert->cert, - (const unsigned char *) mbedtls_test_srv_crt_rsa_sha256_der, - mbedtls_test_srv_crt_rsa_sha256_der_len); - TEST_ASSERT(ret == 0); - - ret = mbedtls_pk_parse_key(cert->pkey, - (const unsigned char *) mbedtls_test_srv_key_rsa_der, - mbedtls_test_srv_key_rsa_der_len, NULL, 0); - TEST_ASSERT(ret == 0); - } else { - ret = mbedtls_x509_crt_parse(cert->cert, - (const unsigned char *) mbedtls_test_srv_crt_ec_der, - mbedtls_test_srv_crt_ec_der_len); - TEST_ASSERT(ret == 0); - - ret = mbedtls_pk_parse_key(cert->pkey, - (const unsigned char *) mbedtls_test_srv_key_ec_der, - mbedtls_test_srv_key_ec_der_len, NULL, 0); - TEST_ASSERT(ret == 0); - } - } else { - if (pk_alg == MBEDTLS_PK_RSA) { - ret = mbedtls_x509_crt_parse(cert->cert, - (const unsigned char *) mbedtls_test_cli_crt_rsa_der, - mbedtls_test_cli_crt_rsa_der_len); - TEST_ASSERT(ret == 0); - - ret = mbedtls_pk_parse_key(cert->pkey, - (const unsigned char *) mbedtls_test_cli_key_rsa_der, - mbedtls_test_cli_key_rsa_der_len, NULL, 0); - TEST_ASSERT(ret == 0); - } else { - ret = mbedtls_x509_crt_parse(cert->cert, - (const unsigned char *) mbedtls_test_cli_crt_ec_der, - mbedtls_test_cli_crt_ec_len); - TEST_ASSERT(ret == 0); - - ret = mbedtls_pk_parse_key(cert->pkey, - (const unsigned char *) mbedtls_test_cli_key_ec_der, - mbedtls_test_cli_key_ec_der_len, NULL, 0); - TEST_ASSERT(ret == 0); - } - } - - mbedtls_ssl_conf_ca_chain(&(ep->conf), cert->ca_cert, NULL); - - ret = mbedtls_ssl_conf_own_cert(&(ep->conf), cert->cert, - cert->pkey); - TEST_ASSERT(ret == 0); - -exit: - if (ret != 0) { - mbedtls_endpoint_certificate_free(ep); - } - - return ret; -} - -/* - * Initializes \p ep structure. It is important to call `mbedtls_endpoint_free()` - * after calling this function even if it fails. - * - * \p endpoint_type must be set as MBEDTLS_SSL_IS_SERVER or - * MBEDTLS_SSL_IS_CLIENT. - * \p pk_alg the algorithm to use, currently only MBEDTLS_PK_RSA and - * MBEDTLS_PK_ECDSA are supported. - * \p dtls_context - in case of DTLS - this is the context handling metadata. - * \p input_queue - used only in case of DTLS. - * \p output_queue - used only in case of DTLS. - * - * \retval 0 on success, otherwise error code. - */ -int mbedtls_endpoint_init(mbedtls_endpoint *ep, int endpoint_type, int pk_alg, - mbedtls_test_message_socket_context *dtls_context, - mbedtls_test_message_queue *input_queue, - mbedtls_test_message_queue *output_queue, - const mbedtls_ecp_group_id *curves) -{ - int ret = -1; - - if (dtls_context != NULL && (input_queue == NULL || output_queue == NULL)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (ep == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - memset(ep, 0, sizeof(*ep)); - - ep->name = (endpoint_type == MBEDTLS_SSL_IS_SERVER) ? "Server" : "Client"; - - mbedtls_ssl_init(&(ep->ssl)); - mbedtls_ssl_config_init(&(ep->conf)); - mbedtls_ctr_drbg_init(&(ep->ctr_drbg)); - mbedtls_ssl_conf_rng(&(ep->conf), - mbedtls_ctr_drbg_random, - &(ep->ctr_drbg)); - mbedtls_entropy_init(&(ep->entropy)); - if (dtls_context != NULL) { - TEST_ASSERT(mbedtls_message_socket_setup(input_queue, output_queue, - 100, &(ep->socket), - dtls_context) == 0); - } else { - mbedtls_mock_socket_init(&(ep->socket)); - } - - ret = mbedtls_ctr_drbg_seed(&(ep->ctr_drbg), mbedtls_entropy_func, - &(ep->entropy), (const unsigned char *) (ep->name), - strlen(ep->name)); - TEST_ASSERT(ret == 0); - - /* Non-blocking callbacks without timeout */ - if (dtls_context != NULL) { - mbedtls_ssl_set_bio(&(ep->ssl), dtls_context, - mbedtls_mock_tcp_send_msg, - mbedtls_mock_tcp_recv_msg, - NULL); - } else { - mbedtls_ssl_set_bio(&(ep->ssl), &(ep->socket), - mbedtls_mock_tcp_send_nb, - mbedtls_mock_tcp_recv_nb, - NULL); - } - - ret = mbedtls_ssl_config_defaults(&(ep->conf), endpoint_type, - (dtls_context != NULL) ? - MBEDTLS_SSL_TRANSPORT_DATAGRAM : - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); - TEST_ASSERT(ret == 0); - -#if defined(MBEDTLS_ECP_C) - if (curves != NULL) { - mbedtls_ssl_conf_curves(&(ep->conf), curves); - } -#else - (void) curves; -#endif - - ret = mbedtls_ssl_setup(&(ep->ssl), &(ep->conf)); - TEST_ASSERT(ret == 0); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C) - if (endpoint_type == MBEDTLS_SSL_IS_SERVER && dtls_context != NULL) { - mbedtls_ssl_conf_dtls_cookies(&(ep->conf), NULL, NULL, NULL); - } -#endif - - ret = mbedtls_endpoint_certificate_init(ep, pk_alg); - TEST_ASSERT(ret == 0); - -exit: - return ret; -} - -/* - * Deinitializes endpoint represented by \p ep. - */ -void mbedtls_endpoint_free(mbedtls_endpoint *ep, - mbedtls_test_message_socket_context *context) -{ - mbedtls_endpoint_certificate_free(ep); - - mbedtls_ssl_free(&(ep->ssl)); - mbedtls_ssl_config_free(&(ep->conf)); - mbedtls_ctr_drbg_free(&(ep->ctr_drbg)); - mbedtls_entropy_free(&(ep->entropy)); - - if (context != NULL) { - mbedtls_message_socket_close(context); - } else { - mbedtls_mock_socket_close(&(ep->socket)); - } -} - -/* - * This function moves ssl handshake from \p ssl to prescribed \p state. - * /p second_ssl is used as second endpoint and their sockets have to be - * connected before calling this function. - * - * \retval 0 on success, otherwise error code. - */ -int mbedtls_move_handshake_to_state(mbedtls_ssl_context *ssl, - mbedtls_ssl_context *second_ssl, - int state) -{ - enum { BUFFSIZE = 1024 }; - int max_steps = 1000; - int ret = 0; - - if (ssl == NULL || second_ssl == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - /* Perform communication via connected sockets */ - while ((ssl->state != state) && (--max_steps >= 0)) { - /* If /p second_ssl ends the handshake procedure before /p ssl then - * there is no need to call the next step */ - if (second_ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - ret = mbedtls_ssl_handshake_step(second_ssl); - if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - return ret; - } - } - - /* We only care about the \p ssl state and returns, so we call it last, - * to leave the iteration as soon as the state is as expected. */ - ret = mbedtls_ssl_handshake_step(ssl); - if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - return ret; - } - } - - return (max_steps >= 0) ? ret : -1; -} - -#endif \ - /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ - -/* - * Write application data. Increase write counter if necessary. - */ -int mbedtls_ssl_write_fragment(mbedtls_ssl_context *ssl, unsigned char *buf, - int buf_len, int *written, - const int expected_fragments) -{ - /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is - * a valid no-op for TLS connections. */ - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - TEST_ASSERT(mbedtls_ssl_write(ssl, NULL, 0) == 0); - } - - int ret = mbedtls_ssl_write(ssl, buf + *written, buf_len - *written); - if (ret > 0) { - *written += ret; - } - - if (expected_fragments == 0) { - /* Used for DTLS and the message size larger than MFL. In that case - * the message can not be fragmented and the library should return - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA error. This error must be returned - * to prevent a dead loop inside mbedtls_exchange_data(). */ - return ret; - } else if (expected_fragments == 1) { - /* Used for TLS/DTLS and the message size lower than MFL */ - TEST_ASSERT(ret == buf_len || - ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - } else { - /* Used for TLS and the message size larger than MFL */ - TEST_ASSERT(expected_fragments > 1); - TEST_ASSERT((ret >= 0 && ret <= buf_len) || - ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - } - - return 0; - -exit: - /* Some of the tests failed */ - return -1; -} - -/* - * Read application data and increase read counter and fragments counter if necessary. - */ -int mbedtls_ssl_read_fragment(mbedtls_ssl_context *ssl, unsigned char *buf, - int buf_len, int *read, - int *fragments, const int expected_fragments) -{ - /* Verify that calling mbedtls_ssl_write with a NULL buffer and zero length is - * a valid no-op for TLS connections. */ - if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - TEST_ASSERT(mbedtls_ssl_read(ssl, NULL, 0) == 0); - } - - int ret = mbedtls_ssl_read(ssl, buf + *read, buf_len - *read); - if (ret > 0) { - (*fragments)++; - *read += ret; - } - - if (expected_fragments == 0) { - TEST_ASSERT(ret == 0); - } else if (expected_fragments == 1) { - TEST_ASSERT(ret == buf_len || - ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - } else { - TEST_ASSERT(expected_fragments > 1); - TEST_ASSERT((ret >= 0 && ret <= buf_len) || - ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - } - - return 0; - -exit: - /* Some of the tests failed */ - return -1; -} - -/* - * Helper function setting up inverse record transformations - * using given cipher, hash, EtM mode, authentication tag length, - * and version. - */ - -#define CHK(x) \ - do \ - { \ - if (!(x)) \ - { \ - ret = -1; \ - goto cleanup; \ - } \ - } while (0) - -void set_ciphersuite(mbedtls_ssl_config *conf, const char *cipher, - int *forced_ciphersuite) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - forced_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id(cipher); - forced_ciphersuite[1] = 0; - - ciphersuite_info = - mbedtls_ssl_ciphersuite_from_id(forced_ciphersuite[0]); - - TEST_ASSERT(ciphersuite_info != NULL); - TEST_ASSERT(ciphersuite_info->min_minor_ver <= conf->max_minor_ver); - TEST_ASSERT(ciphersuite_info->max_minor_ver >= conf->min_minor_ver); - - if (conf->max_minor_ver > ciphersuite_info->max_minor_ver) { - conf->max_minor_ver = ciphersuite_info->max_minor_ver; - } - if (conf->min_minor_ver < ciphersuite_info->min_minor_ver) { - conf->min_minor_ver = ciphersuite_info->min_minor_ver; - } - - mbedtls_ssl_conf_ciphersuites(conf, forced_ciphersuite); - -exit: - return; -} - -int psk_dummy_callback(void *p_info, mbedtls_ssl_context *ssl, - const unsigned char *name, size_t name_len) -{ - (void) p_info; - (void) ssl; - (void) name; - (void) name_len; - - return 0; -} - -#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX -#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX -#else -#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX -#endif - -static int build_transforms(mbedtls_ssl_transform *t_in, - mbedtls_ssl_transform *t_out, - int cipher_type, int hash_id, - int etm, int tag_mode, int ver, - size_t cid0_len, - size_t cid1_len) -{ - mbedtls_cipher_info_t const *cipher_info; - int ret = 0; - - size_t keylen, maclen, ivlen; - unsigned char *key0 = NULL, *key1 = NULL; - unsigned char *md0 = NULL, *md1 = NULL; - unsigned char iv_enc[16], iv_dec[16]; - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - unsigned char cid0[SSL_CID_LEN_MIN]; - unsigned char cid1[SSL_CID_LEN_MIN]; - - mbedtls_test_rnd_std_rand(NULL, cid0, sizeof(cid0)); - mbedtls_test_rnd_std_rand(NULL, cid1, sizeof(cid1)); -#else - ((void) cid0_len); - ((void) cid1_len); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - - maclen = 0; - - /* Pick cipher */ - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - CHK(cipher_info != NULL); - CHK(cipher_info->iv_size <= 16); - CHK(cipher_info->key_bitlen % 8 == 0); - - /* Pick keys */ - keylen = cipher_info->key_bitlen / 8; - /* Allocate `keylen + 1` bytes to ensure that we get - * a non-NULL pointers from `mbedtls_calloc` even if - * `keylen == 0` in the case of the NULL cipher. */ - CHK((key0 = mbedtls_calloc(1, keylen + 1)) != NULL); - CHK((key1 = mbedtls_calloc(1, keylen + 1)) != NULL); - memset(key0, 0x1, keylen); - memset(key1, 0x2, keylen); - - /* Setup cipher contexts */ - CHK(mbedtls_cipher_setup(&t_in->cipher_ctx_enc, cipher_info) == 0); - CHK(mbedtls_cipher_setup(&t_in->cipher_ctx_dec, cipher_info) == 0); - CHK(mbedtls_cipher_setup(&t_out->cipher_ctx_enc, cipher_info) == 0); - CHK(mbedtls_cipher_setup(&t_out->cipher_ctx_dec, cipher_info) == 0); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if (cipher_info->mode == MBEDTLS_MODE_CBC) { - CHK(mbedtls_cipher_set_padding_mode(&t_in->cipher_ctx_enc, - MBEDTLS_PADDING_NONE) == 0); - CHK(mbedtls_cipher_set_padding_mode(&t_in->cipher_ctx_dec, - MBEDTLS_PADDING_NONE) == 0); - CHK(mbedtls_cipher_set_padding_mode(&t_out->cipher_ctx_enc, - MBEDTLS_PADDING_NONE) == 0); - CHK(mbedtls_cipher_set_padding_mode(&t_out->cipher_ctx_dec, - MBEDTLS_PADDING_NONE) == 0); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - CHK(mbedtls_cipher_setkey(&t_in->cipher_ctx_enc, key0, - keylen << 3, MBEDTLS_ENCRYPT) == 0); - CHK(mbedtls_cipher_setkey(&t_in->cipher_ctx_dec, key1, - keylen << 3, MBEDTLS_DECRYPT) == 0); - CHK(mbedtls_cipher_setkey(&t_out->cipher_ctx_enc, key1, - keylen << 3, MBEDTLS_ENCRYPT) == 0); - CHK(mbedtls_cipher_setkey(&t_out->cipher_ctx_dec, key0, - keylen << 3, MBEDTLS_DECRYPT) == 0); - - /* Setup MAC contexts */ -#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - if (cipher_info->mode == MBEDTLS_MODE_CBC || - cipher_info->mode == MBEDTLS_MODE_STREAM) { - mbedtls_md_info_t const *md_info; - - /* Pick hash */ - md_info = mbedtls_md_info_from_type(hash_id); - CHK(md_info != NULL); - - /* Pick hash keys */ - maclen = mbedtls_md_get_size(md_info); - CHK((md0 = mbedtls_calloc(1, maclen)) != NULL); - CHK((md1 = mbedtls_calloc(1, maclen)) != NULL); - memset(md0, 0x5, maclen); - memset(md1, 0x6, maclen); - - CHK(mbedtls_md_setup(&t_out->md_ctx_enc, md_info, 1) == 0); - CHK(mbedtls_md_setup(&t_out->md_ctx_dec, md_info, 1) == 0); - CHK(mbedtls_md_setup(&t_in->md_ctx_enc, md_info, 1) == 0); - CHK(mbedtls_md_setup(&t_in->md_ctx_dec, md_info, 1) == 0); - - if (ver > MBEDTLS_SSL_MINOR_VERSION_0) { - CHK(mbedtls_md_hmac_starts(&t_in->md_ctx_enc, - md0, maclen) == 0); - CHK(mbedtls_md_hmac_starts(&t_in->md_ctx_dec, - md1, maclen) == 0); - CHK(mbedtls_md_hmac_starts(&t_out->md_ctx_enc, - md1, maclen) == 0); - CHK(mbedtls_md_hmac_starts(&t_out->md_ctx_dec, - md0, maclen) == 0); - } -#if defined(MBEDTLS_SSL_PROTO_SSL3) - else { - memcpy(&t_in->mac_enc, md0, maclen); - memcpy(&t_in->mac_dec, md1, maclen); - memcpy(&t_out->mac_enc, md1, maclen); - memcpy(&t_out->mac_dec, md0, maclen); - } -#endif - } -#else - ((void) hash_id); -#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ - - - /* Pick IV's (regardless of whether they - * are being used by the transform). */ - ivlen = cipher_info->iv_size; - memset(iv_enc, 0x3, sizeof(iv_enc)); - memset(iv_dec, 0x4, sizeof(iv_dec)); - - /* - * Setup transforms - */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) - t_out->encrypt_then_mac = etm; - t_in->encrypt_then_mac = etm; -#else - ((void) etm); -#endif - - t_out->minor_ver = ver; - t_in->minor_ver = ver; - t_out->ivlen = ivlen; - t_in->ivlen = ivlen; - - switch (cipher_info->mode) { - case MBEDTLS_MODE_GCM: - case MBEDTLS_MODE_CCM: -#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) - if (ver == MBEDTLS_SSL_MINOR_VERSION_4) { - t_out->fixed_ivlen = 12; - t_in->fixed_ivlen = 12; - } else -#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ - { - t_out->fixed_ivlen = 4; - t_in->fixed_ivlen = 4; - } - t_out->maclen = 0; - t_in->maclen = 0; - switch (tag_mode) { - case 0: /* Full tag */ - t_out->taglen = 16; - t_in->taglen = 16; - break; - case 1: /* Partial tag */ - t_out->taglen = 8; - t_in->taglen = 8; - break; - default: - ret = 1; - goto cleanup; - } - break; - - case MBEDTLS_MODE_CHACHAPOLY: - t_out->fixed_ivlen = 12; - t_in->fixed_ivlen = 12; - t_out->maclen = 0; - t_in->maclen = 0; - switch (tag_mode) { - case 0: /* Full tag */ - t_out->taglen = 16; - t_in->taglen = 16; - break; - case 1: /* Partial tag */ - t_out->taglen = 8; - t_in->taglen = 8; - break; - default: - ret = 1; - goto cleanup; - } - break; - - case MBEDTLS_MODE_STREAM: - case MBEDTLS_MODE_CBC: - t_out->fixed_ivlen = 0; /* redundant, must be 0 */ - t_in->fixed_ivlen = 0; /* redundant, must be 0 */ - t_out->taglen = 0; - t_in->taglen = 0; - switch (tag_mode) { - case 0: /* Full tag */ - t_out->maclen = maclen; - t_in->maclen = maclen; - break; - case 1: /* Partial tag */ - t_out->maclen = 10; - t_in->maclen = 10; - break; - default: - ret = 1; - goto cleanup; - } - break; - default: - ret = 1; - goto cleanup; - break; - } - - /* Setup IV's */ - - memcpy(&t_in->iv_dec, iv_dec, sizeof(iv_dec)); - memcpy(&t_in->iv_enc, iv_enc, sizeof(iv_enc)); - memcpy(&t_out->iv_dec, iv_enc, sizeof(iv_enc)); - memcpy(&t_out->iv_enc, iv_dec, sizeof(iv_dec)); - -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) - /* Add CID */ - memcpy(&t_in->in_cid, cid0, cid0_len); - memcpy(&t_in->out_cid, cid1, cid1_len); - t_in->in_cid_len = cid0_len; - t_in->out_cid_len = cid1_len; - memcpy(&t_out->in_cid, cid1, cid1_len); - memcpy(&t_out->out_cid, cid0, cid0_len); - t_out->in_cid_len = cid1_len; - t_out->out_cid_len = cid0_len; -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ - -cleanup: - - mbedtls_free(key0); - mbedtls_free(key1); - - mbedtls_free(md0); - mbedtls_free(md1); - - return ret; -} - -/* - * Populate a session structure for serialization tests. - * Choose dummy values, mostly non-0 to distinguish from the init default. - */ -static int ssl_populate_session(mbedtls_ssl_session *session, - int ticket_len, - const char *crt_file) -{ -#if defined(MBEDTLS_HAVE_TIME) - session->start = mbedtls_time(NULL) - 42; -#endif - session->ciphersuite = 0xabcd; - session->compression = 1; - session->id_len = sizeof(session->id); - memset(session->id, 66, session->id_len); - memset(session->master, 17, sizeof(session->master)); - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ - defined(MBEDTLS_CERTS_C) && \ - defined(MBEDTLS_FS_IO) - if (strlen(crt_file) != 0) { - mbedtls_x509_crt tmp_crt; - int ret; - - mbedtls_x509_crt_init(&tmp_crt); - ret = mbedtls_x509_crt_parse_file(&tmp_crt, crt_file); - if (ret != 0) { - return ret; - } - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* Move temporary CRT. */ - session->peer_cert = mbedtls_calloc(1, sizeof(*session->peer_cert)); - if (session->peer_cert == NULL) { - return -1; - } - *session->peer_cert = tmp_crt; - memset(&tmp_crt, 0, sizeof(tmp_crt)); -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Calculate digest of temporary CRT. */ - session->peer_cert_digest = - mbedtls_calloc(1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN); - if (session->peer_cert_digest == NULL) { - return -1; - } - ret = mbedtls_md(mbedtls_md_info_from_type( - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE), - tmp_crt.raw.p, tmp_crt.raw.len, - session->peer_cert_digest); - if (ret != 0) { - return ret; - } - session->peer_cert_digest_type = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE; - session->peer_cert_digest_len = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - mbedtls_x509_crt_free(&tmp_crt); - } -#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_FS_IO */ - (void) crt_file; -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_FS_IO */ - session->verify_result = 0xdeadbeef; - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - if (ticket_len != 0) { - session->ticket = mbedtls_calloc(1, ticket_len); - if (session->ticket == NULL) { - return -1; - } - memset(session->ticket, 33, ticket_len); - } - session->ticket_len = ticket_len; - session->ticket_lifetime = 86401; -#else - (void) ticket_len; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - session->mfl_code = 1; -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - session->trunc_hmac = 1; -#endif -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - session->encrypt_then_mac = 1; -#endif - - return 0; -} - -/* - * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the - * message was sent in the correct number of fragments. - * - * /p ssl_1 and /p ssl_2 Endpoints represented by mbedtls_ssl_context. Both - * of them must be initialized and connected beforehand. - * /p msg_len_1 and /p msg_len_2 specify the size of the message to send. - * /p expected_fragments_1 and /p expected_fragments_2 determine in how many - * fragments the message should be sent. - * expected_fragments is 0: can be used for DTLS testing while the message - * size is larger than MFL. In that case the message - * cannot be fragmented and sent to the second endpoint. - * This value can be used for negative tests. - * expected_fragments is 1: can be used for TLS/DTLS testing while the - * message size is below MFL - * expected_fragments > 1: can be used for TLS testing while the message - * size is larger than MFL - * - * \retval 0 on success, otherwise error code. - */ -int mbedtls_exchange_data(mbedtls_ssl_context *ssl_1, - int msg_len_1, const int expected_fragments_1, - mbedtls_ssl_context *ssl_2, - int msg_len_2, const int expected_fragments_2) -{ - unsigned char *msg_buf_1 = malloc(msg_len_1); - unsigned char *msg_buf_2 = malloc(msg_len_2); - unsigned char *in_buf_1 = malloc(msg_len_2); - unsigned char *in_buf_2 = malloc(msg_len_1); - int msg_type, ret = -1; - - /* Perform this test with two message types. At first use a message - * consisting of only 0x00 for the client and only 0xFF for the server. - * At the second time use message with generated data */ - for (msg_type = 0; msg_type < 2; msg_type++) { - int written_1 = 0; - int written_2 = 0; - int read_1 = 0; - int read_2 = 0; - int fragments_1 = 0; - int fragments_2 = 0; - - if (msg_type == 0) { - memset(msg_buf_1, 0x00, msg_len_1); - memset(msg_buf_2, 0xff, msg_len_2); - } else { - int i, j = 0; - for (i = 0; i < msg_len_1; i++) { - msg_buf_1[i] = j++ & 0xFF; - } - for (i = 0; i < msg_len_2; i++) { - msg_buf_2[i] = (j -= 5) & 0xFF; - } - } - - while (read_1 < msg_len_2 || read_2 < msg_len_1) { - /* ssl_1 sending */ - if (msg_len_1 > written_1) { - ret = mbedtls_ssl_write_fragment(ssl_1, msg_buf_1, - msg_len_1, &written_1, - expected_fragments_1); - if (expected_fragments_1 == 0) { - /* This error is expected when the message is too large and - * cannot be fragmented */ - TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); - msg_len_1 = 0; - } else { - TEST_ASSERT(ret == 0); - } - } - - /* ssl_2 sending */ - if (msg_len_2 > written_2) { - ret = mbedtls_ssl_write_fragment(ssl_2, msg_buf_2, - msg_len_2, &written_2, - expected_fragments_2); - if (expected_fragments_2 == 0) { - /* This error is expected when the message is too large and - * cannot be fragmented */ - TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); - msg_len_2 = 0; - } else { - TEST_ASSERT(ret == 0); - } - } - - /* ssl_1 reading */ - if (read_1 < msg_len_2) { - ret = mbedtls_ssl_read_fragment(ssl_1, in_buf_1, - msg_len_2, &read_1, - &fragments_2, - expected_fragments_2); - TEST_ASSERT(ret == 0); - } - - /* ssl_2 reading */ - if (read_2 < msg_len_1) { - ret = mbedtls_ssl_read_fragment(ssl_2, in_buf_2, - msg_len_1, &read_2, - &fragments_1, - expected_fragments_1); - TEST_ASSERT(ret == 0); - } - } - - ret = -1; - TEST_ASSERT(0 == memcmp(msg_buf_1, in_buf_2, msg_len_1)); - TEST_ASSERT(0 == memcmp(msg_buf_2, in_buf_1, msg_len_2)); - TEST_ASSERT(fragments_1 == expected_fragments_1); - TEST_ASSERT(fragments_2 == expected_fragments_2); - } - - ret = 0; - -exit: - free(msg_buf_1); - free(in_buf_1); - free(msg_buf_2); - free(in_buf_2); - - return ret; -} - -/* - * Perform data exchanging between \p ssl_1 and \p ssl_2. Both of endpoints - * must be initialized and connected beforehand. - * - * \retval 0 on success, otherwise error code. - */ -int exchange_data(mbedtls_ssl_context *ssl_1, - mbedtls_ssl_context *ssl_2) -{ - return mbedtls_exchange_data(ssl_1, 256, 1, - ssl_2, 256, 1); -} - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ - defined(MBEDTLS_CERTS_C) && \ - defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_CTR_DRBG_C) -void perform_handshake(handshake_test_options *options) -{ - /* forced_ciphersuite needs to last until the end of the handshake */ - int forced_ciphersuite[2]; - enum { BUFFSIZE = 17000 }; - mbedtls_endpoint client, server; -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - const char *psk_identity = "foo"; -#endif -#if defined(MBEDTLS_TIMING_C) - mbedtls_timing_delay_context timer_client, timer_server; -#endif -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - unsigned char *context_buf = NULL; - size_t context_buf_len; -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int ret = -1; -#endif - int expected_handshake_result = 0; - - USE_PSA_INIT(); - mbedtls_platform_zeroize(&client, sizeof(client)); - mbedtls_platform_zeroize(&server, sizeof(server)); - - mbedtls_test_message_queue server_queue, client_queue; - mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); - - /* Client side */ - if (options->dtls != 0) { - TEST_ASSERT(mbedtls_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, - options->pk_alg, &client_context, - &client_queue, - &server_queue, NULL) == 0); -#if defined(MBEDTLS_TIMING_C) - mbedtls_ssl_set_timer_cb(&client.ssl, &timer_client, - mbedtls_timing_set_delay, - mbedtls_timing_get_delay); -#endif - } else { - TEST_ASSERT(mbedtls_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, - options->pk_alg, NULL, NULL, - NULL, NULL) == 0); - } - - if (options->client_min_version != TEST_SSL_MINOR_VERSION_NONE) { - mbedtls_ssl_conf_min_version(&client.conf, MBEDTLS_SSL_MAJOR_VERSION_3, - options->client_min_version); - } - - if (options->client_max_version != TEST_SSL_MINOR_VERSION_NONE) { - mbedtls_ssl_conf_max_version(&client.conf, MBEDTLS_SSL_MAJOR_VERSION_3, - options->client_max_version); - } - - if (strlen(options->cipher) > 0) { - set_ciphersuite(&client.conf, options->cipher, forced_ciphersuite); - } - -#if defined(MBEDTLS_DEBUG_C) - if (options->cli_log_fun) { - mbedtls_debug_set_threshold(4); - mbedtls_ssl_conf_dbg(&client.conf, options->cli_log_fun, - options->cli_log_obj); - } -#endif - - /* Server side */ - if (options->dtls != 0) { - TEST_ASSERT(mbedtls_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, - options->pk_alg, &server_context, - &server_queue, - &client_queue, NULL) == 0); -#if defined(MBEDTLS_TIMING_C) - mbedtls_ssl_set_timer_cb(&server.ssl, &timer_server, - mbedtls_timing_set_delay, - mbedtls_timing_get_delay); -#endif - } else { - TEST_ASSERT(mbedtls_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, - options->pk_alg, NULL, NULL, - NULL, NULL) == 0); - } - - mbedtls_ssl_conf_authmode(&server.conf, options->srv_auth_mode); - - if (options->server_min_version != TEST_SSL_MINOR_VERSION_NONE) { - mbedtls_ssl_conf_min_version(&server.conf, MBEDTLS_SSL_MAJOR_VERSION_3, - options->server_min_version); - } - - if (options->server_max_version != TEST_SSL_MINOR_VERSION_NONE) { - mbedtls_ssl_conf_max_version(&server.conf, MBEDTLS_SSL_MAJOR_VERSION_3, - options->server_max_version); - } - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - TEST_ASSERT(mbedtls_ssl_conf_max_frag_len(&(server.conf), - (unsigned char) options->mfl) == 0); - TEST_ASSERT(mbedtls_ssl_conf_max_frag_len(&(client.conf), - (unsigned char) options->mfl) == 0); -#else - TEST_ASSERT(MBEDTLS_SSL_MAX_FRAG_LEN_NONE == options->mfl); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) - if (options->psk_str != NULL && options->psk_str->len > 0) { - TEST_ASSERT(mbedtls_ssl_conf_psk(&client.conf, options->psk_str->x, - options->psk_str->len, - (const unsigned char *) psk_identity, - strlen(psk_identity)) == 0); - - TEST_ASSERT(mbedtls_ssl_conf_psk(&server.conf, options->psk_str->x, - options->psk_str->len, - (const unsigned char *) psk_identity, - strlen(psk_identity)) == 0); - - mbedtls_ssl_conf_psk_cb(&server.conf, psk_dummy_callback, NULL); - } -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (options->renegotiate) { - mbedtls_ssl_conf_renegotiation(&(server.conf), - MBEDTLS_SSL_RENEGOTIATION_ENABLED); - mbedtls_ssl_conf_renegotiation(&(client.conf), - MBEDTLS_SSL_RENEGOTIATION_ENABLED); - - mbedtls_ssl_conf_legacy_renegotiation(&(server.conf), - options->legacy_renegotiation); - mbedtls_ssl_conf_legacy_renegotiation(&(client.conf), - options->legacy_renegotiation); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_DEBUG_C) - if (options->srv_log_fun) { - mbedtls_debug_set_threshold(4); - mbedtls_ssl_conf_dbg(&server.conf, options->srv_log_fun, - options->srv_log_obj); - } -#endif - - TEST_ASSERT(mbedtls_mock_socket_connect(&(client.socket), - &(server.socket), - BUFFSIZE) == 0); - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - if (options->resize_buffers != 0) { - /* Ensure that the buffer sizes are appropriate before resizes */ - TEST_ASSERT(client.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); - TEST_ASSERT(client.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); - TEST_ASSERT(server.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); - TEST_ASSERT(server.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); - } -#endif - - if (options->expected_negotiated_version == TEST_SSL_MINOR_VERSION_NONE) { - expected_handshake_result = MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION; - } - - TEST_ASSERT(mbedtls_move_handshake_to_state(&(client.ssl), - &(server.ssl), - MBEDTLS_SSL_HANDSHAKE_OVER) - == expected_handshake_result); - - if (expected_handshake_result != 0) { - /* Connection will have failed by this point, skip to cleanup */ - goto exit; - } - - TEST_ASSERT(client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER); - TEST_ASSERT(server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER); - - /* Check that we agree on the version... */ - TEST_ASSERT(client.ssl.minor_ver == server.ssl.minor_ver); - - /* And check that the version negotiated is the expected one. */ - TEST_EQUAL(client.ssl.minor_ver, options->expected_negotiated_version); - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - if (options->resize_buffers != 0) { - if (options->expected_negotiated_version != MBEDTLS_SSL_MINOR_VERSION_0 && - options->expected_negotiated_version != MBEDTLS_SSL_MINOR_VERSION_1) { - /* A server, when using DTLS, might delay a buffer resize to happen - * after it receives a message, so we force it. */ - TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); - - TEST_ASSERT(client.ssl.out_buf_len == - mbedtls_ssl_get_output_buflen(&client.ssl)); - TEST_ASSERT(client.ssl.in_buf_len == - mbedtls_ssl_get_input_buflen(&client.ssl)); - TEST_ASSERT(server.ssl.out_buf_len == - mbedtls_ssl_get_output_buflen(&server.ssl)); - TEST_ASSERT(server.ssl.in_buf_len == - mbedtls_ssl_get_input_buflen(&server.ssl)); - } - } -#endif - - if (options->cli_msg_len != 0 || options->srv_msg_len != 0) { - /* Start data exchanging test */ - TEST_ASSERT(mbedtls_exchange_data(&(client.ssl), options->cli_msg_len, - options->expected_cli_fragments, - &(server.ssl), options->srv_msg_len, - options->expected_srv_fragments) - == 0); - } -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - if (options->serialize == 1) { - TEST_ASSERT(options->dtls == 1); - - TEST_ASSERT(mbedtls_ssl_context_save(&(server.ssl), NULL, - 0, &context_buf_len) - == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); - - context_buf = mbedtls_calloc(1, context_buf_len); - TEST_ASSERT(context_buf != NULL); - - TEST_ASSERT(mbedtls_ssl_context_save(&(server.ssl), context_buf, - context_buf_len, - &context_buf_len) == 0); - - mbedtls_ssl_free(&(server.ssl)); - mbedtls_ssl_init(&(server.ssl)); - - TEST_ASSERT(mbedtls_ssl_setup(&(server.ssl), &(server.conf)) == 0); - - mbedtls_ssl_set_bio(&(server.ssl), &server_context, - mbedtls_mock_tcp_send_msg, - mbedtls_mock_tcp_recv_msg, - NULL); - -#if defined(MBEDTLS_TIMING_C) - mbedtls_ssl_set_timer_cb(&server.ssl, &timer_server, - mbedtls_timing_set_delay, - mbedtls_timing_get_delay); -#endif -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - if (options->resize_buffers != 0) { - /* Ensure that the buffer sizes are appropriate before resizes */ - TEST_ASSERT(server.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); - TEST_ASSERT(server.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); - } -#endif - TEST_ASSERT(mbedtls_ssl_context_load(&(server.ssl), context_buf, - context_buf_len) == 0); - -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* Validate buffer sizes after context deserialization */ - if (options->resize_buffers != 0) { - TEST_ASSERT(server.ssl.out_buf_len == - mbedtls_ssl_get_output_buflen(&server.ssl)); - TEST_ASSERT(server.ssl.in_buf_len == - mbedtls_ssl_get_input_buflen(&server.ssl)); - } -#endif - /* Retest writing/reading */ - if (options->cli_msg_len != 0 || options->srv_msg_len != 0) { - TEST_ASSERT(mbedtls_exchange_data(&(client.ssl), - options->cli_msg_len, - options->expected_cli_fragments, - &(server.ssl), - options->srv_msg_len, - options->expected_srv_fragments) - == 0); - } - } -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if (options->renegotiate) { - /* Start test with renegotiation */ - TEST_ASSERT(server.ssl.renego_status == - MBEDTLS_SSL_INITIAL_HANDSHAKE); - TEST_ASSERT(client.ssl.renego_status == - MBEDTLS_SSL_INITIAL_HANDSHAKE); - - /* After calling this function for the server, it only sends a handshake - * request. All renegotiation should happen during data exchanging */ - TEST_ASSERT(mbedtls_ssl_renegotiate(&(server.ssl)) == 0); - TEST_ASSERT(server.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_PENDING); - TEST_ASSERT(client.ssl.renego_status == - MBEDTLS_SSL_INITIAL_HANDSHAKE); - - TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); - TEST_ASSERT(server.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_DONE); - TEST_ASSERT(client.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_DONE); - - /* After calling mbedtls_ssl_renegotiate for the client all renegotiation - * should happen inside this function. However in this test, we cannot - * perform simultaneous communication between client and server so this - * function will return waiting error on the socket. All rest of - * renegotiation should happen during data exchanging */ - ret = mbedtls_ssl_renegotiate(&(client.ssl)); -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - if (options->resize_buffers != 0) { - /* Ensure that the buffer sizes are appropriate before resizes */ - TEST_ASSERT(client.ssl.out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); - TEST_ASSERT(client.ssl.in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); - } -#endif - TEST_ASSERT(ret == 0 || - ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - TEST_ASSERT(server.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_DONE); - TEST_ASSERT(client.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS); - - TEST_ASSERT(exchange_data(&(client.ssl), &(server.ssl)) == 0); - TEST_ASSERT(server.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_DONE); - TEST_ASSERT(client.ssl.renego_status == - MBEDTLS_SSL_RENEGOTIATION_DONE); -#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) - /* Validate buffer sizes after renegotiation */ - if (options->resize_buffers != 0) { - TEST_ASSERT(client.ssl.out_buf_len == - mbedtls_ssl_get_output_buflen(&client.ssl)); - TEST_ASSERT(client.ssl.in_buf_len == - mbedtls_ssl_get_input_buflen(&client.ssl)); - TEST_ASSERT(server.ssl.out_buf_len == - mbedtls_ssl_get_output_buflen(&server.ssl)); - TEST_ASSERT(server.ssl.in_buf_len == - mbedtls_ssl_get_input_buflen(&server.ssl)); - } -#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */ - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -exit: - mbedtls_endpoint_free(&client, options->dtls != 0 ? &client_context : NULL); - mbedtls_endpoint_free(&server, options->dtls != 0 ? &server_context : NULL); -#if defined(MBEDTLS_DEBUG_C) - if (options->cli_log_fun || options->srv_log_fun) { - mbedtls_debug_set_threshold(0); - } -#endif -#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) - if (context_buf != NULL) { - mbedtls_free(context_buf); - } -#endif -} -#endif \ - /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ - /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -2030,65 +16,69 @@ exit: void test_callback_buffer_sanity() { enum { MSGLEN = 10 }; - mbedtls_test_buffer buf; + mbedtls_test_ssl_buffer buf; unsigned char input[MSGLEN]; unsigned char output[MSGLEN]; memset(input, 0, sizeof(input)); /* Make sure calling put and get on NULL buffer results in error. */ - TEST_ASSERT(mbedtls_test_buffer_put(NULL, input, sizeof(input)) + TEST_ASSERT(mbedtls_test_ssl_buffer_put(NULL, input, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_get(NULL, output, sizeof(output)) + TEST_ASSERT(mbedtls_test_ssl_buffer_get(NULL, output, sizeof(output)) + == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(NULL, NULL, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_put(NULL, NULL, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_put(NULL, NULL, 0) == -1); - TEST_ASSERT(mbedtls_test_buffer_get(NULL, NULL, 0) == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(NULL, NULL, 0) == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(NULL, NULL, 0) == -1); /* Make sure calling put and get on a buffer that hasn't been set up results * in error. */ - mbedtls_test_buffer_init(&buf); + mbedtls_test_ssl_buffer_init(&buf); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, input, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_get(&buf, output, sizeof(output)) + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, input, sizeof(input)) + == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(&buf, output, sizeof(output)) + == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, NULL, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, NULL, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, NULL, 0) == -1); - TEST_ASSERT(mbedtls_test_buffer_get(&buf, NULL, 0) == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, NULL, 0) == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(&buf, NULL, 0) == -1); /* Make sure calling put and get on NULL input only results in * error if the length is not zero, and that a NULL output is valid for data * dropping. */ - TEST_ASSERT(mbedtls_test_buffer_setup(&buf, sizeof(input)) == 0); + TEST_ASSERT(mbedtls_test_ssl_buffer_setup(&buf, sizeof(input)) == 0); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, NULL, sizeof(input)) == -1); - TEST_ASSERT(mbedtls_test_buffer_get(&buf, NULL, sizeof(output)) + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, NULL, sizeof(input)) + == -1); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(&buf, NULL, sizeof(output)) == 0); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, NULL, 0) == 0); - TEST_ASSERT(mbedtls_test_buffer_get(&buf, NULL, 0) == 0); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, NULL, 0) == 0); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(&buf, NULL, 0) == 0); /* Make sure calling put several times in the row is safe */ - TEST_ASSERT(mbedtls_test_buffer_put(&buf, input, sizeof(input)) + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, input, sizeof(input)) == sizeof(input)); - TEST_ASSERT(mbedtls_test_buffer_get(&buf, output, 2) == 2); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, input, 1) == 1); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, input, 2) == 1); - TEST_ASSERT(mbedtls_test_buffer_put(&buf, input, 2) == 0); + TEST_ASSERT(mbedtls_test_ssl_buffer_get(&buf, output, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, input, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, input, 2) == 1); + TEST_ASSERT(mbedtls_test_ssl_buffer_put(&buf, input, 2) == 0); exit: - mbedtls_test_buffer_free(&buf); + mbedtls_test_ssl_buffer_free(&buf); } /* END_CASE */ /* - * Test if the implementation of `mbedtls_test_buffer` related functions is + * Test if the implementation of `mbedtls_test_ssl_buffer` related functions is * correct and works as expected. * * That is @@ -2110,15 +100,15 @@ void test_callback_buffer(int size, int put1, int put1_ret, int put_ret[ROUNDS]; size_t get[ROUNDS]; int get_ret[ROUNDS]; - mbedtls_test_buffer buf; + mbedtls_test_ssl_buffer buf; unsigned char *input = NULL; size_t input_len; unsigned char *output = NULL; size_t output_len; size_t i, j, written, read; - mbedtls_test_buffer_init(&buf); - TEST_ASSERT(mbedtls_test_buffer_setup(&buf, size) == 0); + mbedtls_test_ssl_buffer_init(&buf); + TEST_ASSERT(mbedtls_test_ssl_buffer_setup(&buf, size) == 0); /* Check the sanity of input parameters and initialise local variables. That * is, ensure that the amount of data is not negative and that we are not @@ -2177,11 +167,11 @@ void test_callback_buffer(int size, int put1, int put1_ret, written = read = 0; for (j = 0; j < ROUNDS; j++) { - TEST_ASSERT(put_ret[j] == mbedtls_test_buffer_put(&buf, - input + written, put[j])); + TEST_ASSERT(put_ret[j] == mbedtls_test_ssl_buffer_put(&buf, + input + written, put[j])); written += put_ret[j]; - TEST_ASSERT(get_ret[j] == mbedtls_test_buffer_get(&buf, - output + read, get[j])); + TEST_ASSERT(get_ret[j] == mbedtls_test_ssl_buffer_get(&buf, + output + read, get[j])); read += get_ret[j]; TEST_ASSERT(read <= written); if (get_ret[j] > 0) { @@ -2195,13 +185,13 @@ exit: mbedtls_free(input); mbedtls_free(output); - mbedtls_test_buffer_free(&buf); + mbedtls_test_ssl_buffer_free(&buf); } /* END_CASE */ /* - * Test if the implementation of `mbedtls_mock_socket` related I/O functions is - * correct and works as expected on unconnected sockets. + * Test if the implementation of `mbedtls_test_mock_socket` related + * I/O functions is correct and works as expected on unconnected sockets. */ /* BEGIN_CASE */ @@ -2210,31 +200,31 @@ void ssl_mock_sanity() enum { MSGLEN = 105 }; unsigned char message[MSGLEN] = { 0 }; unsigned char received[MSGLEN] = { 0 }; - mbedtls_mock_socket socket; + mbedtls_test_mock_socket socket; mbedtls_mock_socket_init(&socket); - TEST_ASSERT(mbedtls_mock_tcp_send_b(&socket, message, MSGLEN) < 0); - mbedtls_mock_socket_close(&socket); + TEST_ASSERT(mbedtls_test_mock_tcp_send_b(&socket, message, MSGLEN) < 0); + mbedtls_test_mock_socket_close(&socket); mbedtls_mock_socket_init(&socket); - TEST_ASSERT(mbedtls_mock_tcp_recv_b(&socket, received, MSGLEN) < 0); - mbedtls_mock_socket_close(&socket); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_b(&socket, received, MSGLEN) < 0); + mbedtls_test_mock_socket_close(&socket); mbedtls_mock_socket_init(&socket); - TEST_ASSERT(mbedtls_mock_tcp_send_nb(&socket, message, MSGLEN) < 0); - mbedtls_mock_socket_close(&socket); + TEST_ASSERT(mbedtls_test_mock_tcp_send_nb(&socket, message, MSGLEN) < 0); + mbedtls_test_mock_socket_close(&socket); mbedtls_mock_socket_init(&socket); - TEST_ASSERT(mbedtls_mock_tcp_recv_nb(&socket, received, MSGLEN) < 0); - mbedtls_mock_socket_close(&socket); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_nb(&socket, received, MSGLEN) < 0); + mbedtls_test_mock_socket_close(&socket); exit: - mbedtls_mock_socket_close(&socket); + mbedtls_test_mock_socket_close(&socket); } /* END_CASE */ /* - * Test if the implementation of `mbedtls_mock_socket` related functions can - * send a single message from the client to the server. + * Test if the implementation of `mbedtls_test_mock_socket` related functions + * can send a single message from the client to the server. */ /* BEGIN_CASE */ @@ -2244,8 +234,8 @@ void ssl_mock_tcp(int blocking) enum { BUFLEN = MSGLEN / 5 }; unsigned char message[MSGLEN]; unsigned char received[MSGLEN]; - mbedtls_mock_socket client; - mbedtls_mock_socket server; + mbedtls_test_mock_socket client; + mbedtls_test_mock_socket server; size_t written, read; int send_ret, recv_ret; mbedtls_ssl_send_t *send; @@ -2253,11 +243,11 @@ void ssl_mock_tcp(int blocking) unsigned i; if (blocking == 0) { - send = mbedtls_mock_tcp_send_nb; - recv = mbedtls_mock_tcp_recv_nb; + send = mbedtls_test_mock_tcp_send_nb; + recv = mbedtls_test_mock_tcp_recv_nb; } else { - send = mbedtls_mock_tcp_send_b; - recv = mbedtls_mock_tcp_recv_b; + send = mbedtls_test_mock_tcp_send_b; + recv = mbedtls_test_mock_tcp_recv_b; } mbedtls_mock_socket_init(&client); @@ -2270,7 +260,7 @@ void ssl_mock_tcp(int blocking) } /* Make sure that sending a message takes a few iterations. */ - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, BUFLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, BUFLEN)); /* Send the message to the server */ send_ret = recv_ret = 1; @@ -2320,14 +310,14 @@ void ssl_mock_tcp(int blocking) exit: - mbedtls_mock_socket_close(&client); - mbedtls_mock_socket_close(&server); + mbedtls_test_mock_socket_close(&client); + mbedtls_test_mock_socket_close(&server); } /* END_CASE */ /* - * Test if the implementation of `mbedtls_mock_socket` related functions can - * send messages in both direction at the same time (with the I/O calls + * Test if the implementation of `mbedtls_test_mock_socket` related functions + * can send messages in both direction at the same time (with the I/O calls * interleaving). */ @@ -2339,8 +329,8 @@ void ssl_mock_tcp_interleaving(int blocking) enum { BUFLEN = MSGLEN / 5 }; unsigned char message[ROUNDS][MSGLEN]; unsigned char received[ROUNDS][MSGLEN]; - mbedtls_mock_socket client; - mbedtls_mock_socket server; + mbedtls_test_mock_socket client; + mbedtls_test_mock_socket server; size_t written[ROUNDS]; size_t read[ROUNDS]; int send_ret[ROUNDS]; @@ -2350,11 +340,11 @@ void ssl_mock_tcp_interleaving(int blocking) mbedtls_ssl_recv_t *recv; if (blocking == 0) { - send = mbedtls_mock_tcp_send_nb; - recv = mbedtls_mock_tcp_recv_nb; + send = mbedtls_test_mock_tcp_send_nb; + recv = mbedtls_test_mock_tcp_recv_nb; } else { - send = mbedtls_mock_tcp_send_b; - recv = mbedtls_mock_tcp_recv_b; + send = mbedtls_test_mock_tcp_send_b; + recv = mbedtls_test_mock_tcp_recv_b; } mbedtls_mock_socket_init(&client); @@ -2369,7 +359,8 @@ void ssl_mock_tcp_interleaving(int blocking) } /* Make sure that sending a message takes a few iterations. */ - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, BUFLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + BUFLEN)); /* Send the message from both sides, interleaving. */ progress = 1; @@ -2380,7 +371,7 @@ void ssl_mock_tcp_interleaving(int blocking) /* This loop does not stop as long as there was a successful write or read * of at least one byte on either side. */ while (progress != 0) { - mbedtls_mock_socket *socket; + mbedtls_test_mock_socket *socket; for (i = 0; i < ROUNDS; i++) { /* First sending is from the client */ @@ -2447,134 +438,134 @@ void ssl_mock_tcp_interleaving(int blocking) exit: - mbedtls_mock_socket_close(&client); - mbedtls_mock_socket_close(&server); + mbedtls_test_mock_socket_close(&client); + mbedtls_test_mock_socket_close(&server); } /* END_CASE */ /* BEGIN_CASE */ void ssl_message_queue_sanity() { - mbedtls_test_message_queue queue; + mbedtls_test_ssl_message_queue queue; /* Trying to push/pull to an empty queue */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(NULL, 1) + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(NULL, 1) == MBEDTLS_TEST_ERROR_ARG_NULL); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(NULL, 1) + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(NULL, 1) == MBEDTLS_TEST_ERROR_ARG_NULL); - TEST_ASSERT(mbedtls_test_message_queue_setup(&queue, 3) == 0); + TEST_ASSERT(mbedtls_test_ssl_message_queue_setup(&queue, 3) == 0); TEST_ASSERT(queue.capacity == 3); TEST_ASSERT(queue.num == 0); exit: - mbedtls_test_message_queue_free(&queue); + mbedtls_test_ssl_message_queue_free(&queue); } /* END_CASE */ /* BEGIN_CASE */ void ssl_message_queue_basic() { - mbedtls_test_message_queue queue; + mbedtls_test_ssl_message_queue queue; - TEST_ASSERT(mbedtls_test_message_queue_setup(&queue, 3) == 0); + TEST_ASSERT(mbedtls_test_ssl_message_queue_setup(&queue, 3) == 0); /* Sanity test - 3 pushes and 3 pops with sufficient space */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); TEST_ASSERT(queue.capacity == 3); TEST_ASSERT(queue.num == 1); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); TEST_ASSERT(queue.capacity == 3); TEST_ASSERT(queue.num == 2); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 2) == 2); TEST_ASSERT(queue.capacity == 3); TEST_ASSERT(queue.num == 3); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 2) == 2); exit: - mbedtls_test_message_queue_free(&queue); + mbedtls_test_ssl_message_queue_free(&queue); } /* END_CASE */ /* BEGIN_CASE */ void ssl_message_queue_overflow_underflow() { - mbedtls_test_message_queue queue; + mbedtls_test_ssl_message_queue queue; - TEST_ASSERT(mbedtls_test_message_queue_setup(&queue, 3) == 0); + TEST_ASSERT(mbedtls_test_ssl_message_queue_setup(&queue, 3) == 0); /* 4 pushes (last one with an error), 4 pops (last one with an error) */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 2) == 2); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 3) + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 3) == MBEDTLS_ERR_SSL_WANT_WRITE); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 2) == 2); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == MBEDTLS_ERR_SSL_WANT_READ); exit: - mbedtls_test_message_queue_free(&queue); + mbedtls_test_ssl_message_queue_free(&queue); } /* END_CASE */ /* BEGIN_CASE */ void ssl_message_queue_interleaved() { - mbedtls_test_message_queue queue; + mbedtls_test_ssl_message_queue queue; - TEST_ASSERT(mbedtls_test_message_queue_setup(&queue, 3) == 0); + TEST_ASSERT(mbedtls_test_ssl_message_queue_setup(&queue, 3) == 0); /* Interleaved test - [2 pushes, 1 pop] twice, and then two pops * (to wrap around the buffer) */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 2) == 2); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 3) == 3); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 3) == 3); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 1) == 1); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 2) == 2); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 1) == 1); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 2) == 2); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 5) == 5); - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, 8) == 8); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 5) == 5); + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, 8) == 8); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 3) == 3); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 3) == 3); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 5) == 5); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 5) == 5); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, 8) == 8); + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, 8) == 8); exit: - mbedtls_test_message_queue_free(&queue); + mbedtls_test_ssl_message_queue_free(&queue); } /* END_CASE */ /* BEGIN_CASE */ void ssl_message_queue_insufficient_buffer() { - mbedtls_test_message_queue queue; + mbedtls_test_ssl_message_queue queue; size_t message_len = 10; size_t buffer_len = 5; - TEST_ASSERT(mbedtls_test_message_queue_setup(&queue, 1) == 0); + TEST_ASSERT(mbedtls_test_ssl_message_queue_setup(&queue, 1) == 0); /* Popping without a sufficient buffer */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(&queue, message_len) + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&queue, message_len) == (int) message_len); - TEST_ASSERT(mbedtls_test_message_queue_pop_info(&queue, buffer_len) + TEST_ASSERT(mbedtls_test_ssl_message_queue_pop_info(&queue, buffer_len) == (int) buffer_len); exit: - mbedtls_test_message_queue_free(&queue); + mbedtls_test_ssl_message_queue_free(&queue); } /* END_CASE */ @@ -2583,44 +574,50 @@ void ssl_message_mock_uninitialized() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN] = { 0 }, received[MSGLEN]; - mbedtls_mock_socket client, server; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_mock_socket client, server; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); /* Send with a NULL context */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(NULL, message, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(NULL, message, MSGLEN) == MBEDTLS_TEST_ERROR_CONTEXT_ERROR); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(NULL, message, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(NULL, message, MSGLEN) == MBEDTLS_TEST_ERROR_CONTEXT_ERROR); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 1, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 1, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 1, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 1, + &client, + &client_context) == 0); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MBEDTLS_TEST_ERROR_SEND_FAILED); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_READ); /* Push directly to a queue to later simulate a disconnected behavior */ - TEST_ASSERT(mbedtls_test_message_queue_push_info(&server_queue, MSGLEN) + TEST_ASSERT(mbedtls_test_ssl_message_queue_push_info(&server_queue, + MSGLEN) == MSGLEN); /* Test if there's an error when trying to read from a disconnected * socket */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_TEST_ERROR_RECV_FAILED); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2629,52 +626,57 @@ void ssl_message_mock_basic() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 1, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 1, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 1, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 1, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN)); /* Send the message to the server */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) + == MSGLEN); /* Read from the server */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); memset(received, 0, MSGLEN); /* Send the message to the client */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&server_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&server_context, message, + MSGLEN) == MSGLEN); /* Read from the client */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&client_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&client_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2683,55 +685,62 @@ void ssl_message_mock_queue_overflow_underflow() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 2, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 2, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 2, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 2, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN*2)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN*2)); /* Send three message to the server, last one with an error */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN - 1) == MSGLEN - 1); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN - 1) + == MSGLEN - 1); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) + == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_WRITE); /* Read three messages from the server, last one with an error */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, - MSGLEN - 1) == MSGLEN - 1); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN - 1) + == MSGLEN - 1); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_READ); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2740,46 +749,50 @@ void ssl_message_mock_socket_overflow() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 2, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 2, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 2, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 2, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN)); /* Send two message to the server, second one with an error */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) + == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MBEDTLS_TEST_ERROR_SEND_FAILED); /* Read the only message from the server */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2788,20 +801,22 @@ void ssl_message_mock_truncated() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 2, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 2, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 2, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 2, + &client, + &client_context) == 0); memset(received, 0, MSGLEN); /* Fill up the buffer with structured data so that unwanted changes @@ -2809,17 +824,20 @@ void ssl_message_mock_truncated() for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - 2 * MSGLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + 2 * MSGLEN)); /* Send two messages to the server, the second one small enough to fit in the * receiver's buffer. */ - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN / 2) == MSGLEN / 2); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) + == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN / 2) + == MSGLEN / 2); /* Read a truncated message from the server */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN/2) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN/2) == MSGLEN/2); /* Test that the first half of the message is valid, and second one isn't */ @@ -2829,15 +847,16 @@ void ssl_message_mock_truncated() memset(received, 0, MSGLEN); /* Read a full message from the server */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN/2) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN/2) == MSGLEN / 2); /* Test that the first half of the message is valid */ TEST_ASSERT(memcmp(message, received, MSGLEN/2) == 0); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2846,35 +865,39 @@ void ssl_message_mock_socket_read_error() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 1, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 1, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 1, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 1, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN)); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) + == MSGLEN); /* Force a read error by disconnecting the socket by hand */ server.status = 0; - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_TEST_ERROR_RECV_FAILED); /* Return to a valid state */ server.status = MBEDTLS_MOCK_SOCKET_CONNECTED; @@ -2883,14 +906,15 @@ void ssl_message_mock_socket_read_error() /* Test that even though the server tried to read once disconnected, the * continuity is preserved */ - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2899,55 +923,58 @@ void ssl_message_mock_interleaved_one_way() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 3, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 3, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 3, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 3, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN*3)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN*3)); /* Interleaved test - [2 sends, 1 read] twice, and then two reads * (to wrap around the buffer) */ for (i = 0; i < 2; i++) { - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); memset(received, 0, sizeof(received)); } for (i = 0; i < 2; i++) { - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); } - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_READ); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -2956,53 +983,55 @@ void ssl_message_mock_interleaved_two_ways() { enum { MSGLEN = 10 }; unsigned char message[MSGLEN], received[MSGLEN]; - mbedtls_mock_socket client, server; + mbedtls_test_mock_socket client, server; unsigned i; - mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_ssl_message_queue server_queue, client_queue; mbedtls_test_message_socket_context server_context, client_context; - mbedtls_message_socket_init(&server_context); - mbedtls_message_socket_init(&client_context); + mbedtls_test_message_socket_init(&server_context); + mbedtls_test_message_socket_init(&client_context); - TEST_ASSERT(mbedtls_message_socket_setup(&server_queue, &client_queue, 3, - &server, - &server_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&server_queue, + &client_queue, 3, + &server, + &server_context) == 0); - TEST_ASSERT(mbedtls_message_socket_setup(&client_queue, &server_queue, 3, - &client, - &client_context) == 0); + TEST_ASSERT(mbedtls_test_message_socket_setup(&client_queue, + &server_queue, 3, + &client, + &client_context) == 0); /* Fill up the buffer with structured data so that unwanted changes * can be detected */ for (i = 0; i < MSGLEN; i++) { message[i] = i & 0xFF; } - TEST_ASSERT(0 == mbedtls_mock_socket_connect(&client, &server, - MSGLEN*3)); + TEST_ASSERT(0 == mbedtls_test_mock_socket_connect(&client, &server, + MSGLEN*3)); /* Interleaved test - [2 sends, 1 read] twice, both ways, and then two reads * (to wrap around the buffer) both ways. */ for (i = 0; i < 2; i++) { - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&client_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&client_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&server_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&server_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_send_msg(&server_context, message, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_send_msg(&server_context, message, + MSGLEN) == MSGLEN); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); memset(received, 0, sizeof(received)); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&client_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&client_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); @@ -3010,27 +1039,29 @@ void ssl_message_mock_interleaved_two_ways() } for (i = 0; i < 2; i++) { - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); memset(received, 0, sizeof(received)); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&client_context, received, - MSGLEN) == MSGLEN); + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&client_context, received, + MSGLEN) == MSGLEN); TEST_ASSERT(memcmp(message, received, MSGLEN) == 0); memset(received, 0, sizeof(received)); } - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&server_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&server_context, received, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_READ); - TEST_ASSERT(mbedtls_mock_tcp_recv_msg(&client_context, received, MSGLEN) + TEST_ASSERT(mbedtls_test_mock_tcp_recv_msg(&client_context, received, + MSGLEN) == MBEDTLS_ERR_SSL_WANT_READ); exit: - mbedtls_message_socket_close(&server_context); - mbedtls_message_socket_close(&client_context); + mbedtls_test_message_socket_close(&server_context); + mbedtls_test_message_socket_close(&client_context); } /* END_CASE */ @@ -3101,10 +1132,10 @@ void ssl_crypt_record(int cipher_type, int hash_id, mbedtls_ssl_init(&ssl); mbedtls_ssl_transform_init(&t0); mbedtls_ssl_transform_init(&t1); - TEST_ASSERT(build_transforms(&t0, &t1, cipher_type, hash_id, - etm, tag_mode, ver, - (size_t) cid0_len, - (size_t) cid1_len) == 0); + TEST_ASSERT(mbedtls_test_ssl_build_transforms(&t0, &t1, cipher_type, hash_id, + etm, tag_mode, ver, + (size_t) cid0_len, + (size_t) cid1_len) == 0); TEST_ASSERT((buf = mbedtls_calloc(1, buflen)) != NULL); @@ -3250,10 +1281,10 @@ void ssl_crypt_record_small(int cipher_type, int hash_id, mbedtls_ssl_init(&ssl); mbedtls_ssl_transform_init(&t0); mbedtls_ssl_transform_init(&t1); - TEST_ASSERT(build_transforms(&t0, &t1, cipher_type, hash_id, - etm, tag_mode, ver, - (size_t) cid0_len, - (size_t) cid1_len) == 0); + TEST_ASSERT(mbedtls_test_ssl_build_transforms(&t0, &t1, cipher_type, hash_id, + etm, tag_mode, ver, + (size_t) cid0_len, + (size_t) cid1_len) == 0); TEST_ASSERT((buf = mbedtls_calloc(1, buflen)) != NULL); @@ -3402,10 +1433,10 @@ void ssl_decrypt_non_etm_cbc(int cipher_type, int hash_id, int trunc_hmac, mbedtls_ssl_transform_init(&t1); /* Set up transforms with dummy keys */ - TEST_ASSERT(build_transforms(&t0, &t1, cipher_type, hash_id, - 0, trunc_hmac, - MBEDTLS_SSL_MINOR_VERSION_3, - 0, 0) == 0); + TEST_ASSERT(mbedtls_test_ssl_build_transforms(&t0, &t1, cipher_type, hash_id, + 0, trunc_hmac, + MBEDTLS_SSL_MINOR_VERSION_3, + 0, 0) == 0); /* Determine padding/plaintext length */ TEST_ASSERT(length_selector >= -2 && length_selector <= 255); @@ -3626,10 +1657,12 @@ void ssl_tls1_3_traffic_key_generation(int hash_alg, /* Check sanity of test parameters. */ TEST_ASSERT(client_secret->len == server_secret->len); - TEST_ASSERT(expected_client_write_iv->len == expected_server_write_iv->len && - expected_client_write_iv->len == (size_t) desired_iv_len); - TEST_ASSERT(expected_client_write_key->len == expected_server_write_key->len && - expected_client_write_key->len == (size_t) desired_key_len); + TEST_ASSERT( + expected_client_write_iv->len == expected_server_write_iv->len && + expected_client_write_iv->len == (size_t) desired_iv_len); + TEST_ASSERT( + expected_client_write_key->len == expected_server_write_key->len && + expected_client_write_key->len == (size_t) desired_key_len); TEST_ASSERT(mbedtls_ssl_tls1_3_make_traffic_keys( (mbedtls_md_type_t) hash_alg, @@ -3760,7 +1793,8 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file) mbedtls_ssl_session_init(&restored); /* Prepare a dummy session to work on */ - TEST_ASSERT(ssl_populate_session(&original, ticket_len, crt_file) == 0); + TEST_ASSERT(mbedtls_test_ssl_populate_session( + &original, ticket_len, crt_file) == 0); /* Serialize it */ TEST_ASSERT(mbedtls_ssl_session_save(&original, NULL, 0, &len) @@ -3858,7 +1892,8 @@ void ssl_serialize_session_load_save(int ticket_len, char *crt_file) mbedtls_ssl_session_init(&session); /* Prepare a dummy session to work on */ - TEST_ASSERT(ssl_populate_session(&session, ticket_len, crt_file) == 0); + TEST_ASSERT(mbedtls_test_ssl_populate_session( + &session, ticket_len, crt_file) == 0); /* Get desired buffer size for serializing */ TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &len0) @@ -3908,7 +1943,8 @@ void ssl_serialize_session_save_buf_size(int ticket_len, char *crt_file) mbedtls_ssl_session_init(&session); /* Prepare dummy session and get serialized size */ - TEST_ASSERT(ssl_populate_session(&session, ticket_len, crt_file) == 0); + TEST_ASSERT(mbedtls_test_ssl_populate_session( + &session, ticket_len, crt_file) == 0); TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len) == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); @@ -3943,7 +1979,8 @@ void ssl_serialize_session_load_buf_size(int ticket_len, char *crt_file) mbedtls_ssl_session_init(&session); /* Prepare serialized session data */ - TEST_ASSERT(ssl_populate_session(&session, ticket_len, crt_file) == 0); + TEST_ASSERT(mbedtls_test_ssl_populate_session( + &session, ticket_len, crt_file) == 0); TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len) == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL); TEST_ASSERT((good_buf = mbedtls_calloc(1, good_len)) != NULL); @@ -4036,22 +2073,22 @@ void ssl_session_serialize_version_check(int corrupt_major, void mbedtls_endpoint_sanity(int endpoint_type) { enum { BUFFSIZE = 1024 }; - mbedtls_endpoint ep; + mbedtls_test_ssl_endpoint ep; int ret = -1; - ret = mbedtls_endpoint_init(NULL, endpoint_type, MBEDTLS_PK_RSA, - NULL, NULL, NULL, NULL); + ret = mbedtls_test_ssl_endpoint_init(NULL, endpoint_type, MBEDTLS_PK_RSA, + NULL, NULL, NULL, NULL); TEST_ASSERT(MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret); - ret = mbedtls_endpoint_certificate_init(NULL, MBEDTLS_PK_RSA); + ret = mbedtls_test_ssl_endpoint_certificate_init(NULL, MBEDTLS_PK_RSA); TEST_ASSERT(MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret); - ret = mbedtls_endpoint_init(&ep, endpoint_type, MBEDTLS_PK_RSA, - NULL, NULL, NULL, NULL); + ret = mbedtls_test_ssl_endpoint_init(&ep, endpoint_type, MBEDTLS_PK_RSA, + NULL, NULL, NULL, NULL); TEST_ASSERT(ret == 0); exit: - mbedtls_endpoint_free(&ep, NULL); + mbedtls_test_ssl_endpoint_free(&ep, NULL); } /* END_CASE */ @@ -4059,30 +2096,32 @@ exit: void move_handshake_to_state(int endpoint_type, int state, int need_pass) { enum { BUFFSIZE = 1024 }; - mbedtls_endpoint base_ep, second_ep; + mbedtls_test_ssl_endpoint base_ep, second_ep; int ret = -1; mbedtls_platform_zeroize(&base_ep, sizeof(base_ep)); mbedtls_platform_zeroize(&second_ep, sizeof(second_ep)); - ret = mbedtls_endpoint_init(&base_ep, endpoint_type, MBEDTLS_PK_RSA, - NULL, NULL, NULL, NULL); + ret = mbedtls_test_ssl_endpoint_init(&base_ep, endpoint_type, + MBEDTLS_PK_RSA, + NULL, NULL, NULL, NULL); TEST_ASSERT(ret == 0); - ret = mbedtls_endpoint_init(&second_ep, - (endpoint_type == MBEDTLS_SSL_IS_SERVER) ? - MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER, - MBEDTLS_PK_RSA, NULL, NULL, NULL, NULL); + ret = mbedtls_test_ssl_endpoint_init( + &second_ep, + (endpoint_type == MBEDTLS_SSL_IS_SERVER) ? + MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER, + MBEDTLS_PK_RSA, NULL, NULL, NULL, NULL); TEST_ASSERT(ret == 0); - ret = mbedtls_mock_socket_connect(&(base_ep.socket), - &(second_ep.socket), - BUFFSIZE); + ret = mbedtls_test_mock_socket_connect(&(base_ep.socket), + &(second_ep.socket), + BUFFSIZE); TEST_ASSERT(ret == 0); - ret = mbedtls_move_handshake_to_state(&(base_ep.ssl), - &(second_ep.ssl), - state); + ret = mbedtls_test_move_handshake_to_state(&(base_ep.ssl), + &(second_ep.ssl), + state); if (need_pass) { TEST_ASSERT(ret == 0); TEST_ASSERT(base_ep.ssl.state == state); @@ -4092,8 +2131,8 @@ void move_handshake_to_state(int endpoint_type, int state, int need_pass) } exit: - mbedtls_endpoint_free(&base_ep, NULL); - mbedtls_endpoint_free(&second_ep, NULL); + mbedtls_test_ssl_endpoint_free(&base_ep, NULL); + mbedtls_test_ssl_endpoint_free(&second_ep, NULL); } /* END_CASE */ @@ -4102,8 +2141,8 @@ void handshake_version(int dtls, int client_min_version, int client_max_version, int server_min_version, int server_max_version, int expected_negotiated_version) { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.client_min_version = client_min_version; options.client_max_version = client_max_version; @@ -4120,7 +2159,7 @@ void handshake_version(int dtls, int client_min_version, int client_max_version, options.expected_cli_fragments = 2; options.expected_srv_fragments = 2; } - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; @@ -4130,15 +2169,15 @@ void handshake_version(int dtls, int client_min_version, int client_max_version, /* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED:MBEDTLS_CERTS_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C:MBEDTLS_SHA256_C */ void handshake_psk_cipher(char *cipher, int pk_alg, data_t *psk_str, int dtls) { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.cipher = cipher; options.dtls = dtls; options.psk_str = psk_str; options.pk_alg = pk_alg; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; @@ -4160,8 +2199,8 @@ void app_data(int mfl, int cli_msg_len, int srv_msg_len, int expected_cli_fragments, int expected_srv_fragments, int dtls) { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.mfl = mfl; options.cli_msg_len = cli_msg_len; @@ -4170,7 +2209,7 @@ void app_data(int mfl, int cli_msg_len, int srv_msg_len, options.expected_srv_fragments = expected_srv_fragments; options.dtls = dtls; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; } @@ -4203,12 +2242,12 @@ void app_data_dtls(int mfl, int cli_msg_len, int srv_msg_len, /* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED:MBEDTLS_CERTS_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C:MBEDTLS_SHA256_C:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */ void handshake_serialization() { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.serialize = 1; options.dtls = 1; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; } @@ -4219,14 +2258,14 @@ void handshake_fragmentation(int mfl, int expected_srv_hs_fragmentation, int expected_cli_hs_fragmentation) { - handshake_test_options options; - log_pattern srv_pattern, cli_pattern; + mbedtls_test_handshake_test_options options; + mbedtls_test_ssl_log_pattern srv_pattern, cli_pattern; srv_pattern.pattern = cli_pattern.pattern = "found fragmented DTLS handshake"; srv_pattern.counter = 0; cli_pattern.counter = 0; - init_handshake_options(&options); + mbedtls_test_init_handshake_options(&options); options.dtls = 1; options.mfl = mfl; /* Set cipher to one using CBC so that record splitting can be tested */ @@ -4234,10 +2273,10 @@ void handshake_fragmentation(int mfl, options.srv_auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED; options.srv_log_obj = &srv_pattern; options.cli_log_obj = &cli_pattern; - options.srv_log_fun = log_analyzer; - options.cli_log_fun = log_analyzer; + options.srv_log_fun = mbedtls_test_ssl_log_analyzer; + options.cli_log_fun = mbedtls_test_ssl_log_analyzer; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* Test if the server received a fragmented handshake */ if (expected_srv_hs_fragmentation) { @@ -4253,14 +2292,14 @@ void handshake_fragmentation(int mfl, /* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED:MBEDTLS_CERTS_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C:MBEDTLS_SHA256_C:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */ void renegotiation(int legacy_renegotiation) { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.renegotiate = 1; options.legacy_renegotiation = legacy_renegotiation; options.dtls = 1; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; } @@ -4270,8 +2309,8 @@ void renegotiation(int legacy_renegotiation) void resize_buffers(int mfl, int renegotiation, int legacy_renegotiation, int serialize, int dtls, char *cipher) { - handshake_test_options options; - init_handshake_options(&options); + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); options.mfl = mfl; options.cipher = cipher; @@ -4281,7 +2320,7 @@ void resize_buffers(int mfl, int renegotiation, int legacy_renegotiation, options.dtls = dtls; options.resize_buffers = 1; - perform_handshake(&options); + mbedtls_test_ssl_perform_handshake(&options); /* The goto below is used to avoid an "unused label" warning.*/ goto exit; } @@ -4313,7 +2352,7 @@ void resize_buffers_renegotiate_mfl(int mfl, int legacy_renegotiation, void raw_key_agreement_fail(int bad_server_ecdhe_key) { enum { BUFFSIZE = 17000 }; - mbedtls_endpoint client, server; + mbedtls_test_ssl_endpoint client, server; mbedtls_psa_stats_t stats; size_t free_slots_before = -1; @@ -4326,22 +2365,22 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key) /* Client side, force SECP256R1 to make one key bitflip fail * the raw key agreement. Flipping the first byte makes the * required 0x04 identifier invalid. */ - TEST_EQUAL(mbedtls_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_PK_ECDSA, NULL, NULL, - NULL, curve_list), 0); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_PK_ECDSA, NULL, NULL, + NULL, curve_list), 0); /* Server side */ - TEST_EQUAL(mbedtls_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, - MBEDTLS_PK_ECDSA, NULL, NULL, - NULL, NULL), 0); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, + MBEDTLS_PK_ECDSA, NULL, NULL, + NULL, NULL), 0); - TEST_EQUAL(mbedtls_mock_socket_connect(&(client.socket), - &(server.socket), - BUFFSIZE), 0); + TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client.socket), + &(server.socket), + BUFFSIZE), 0); - TEST_EQUAL(mbedtls_move_handshake_to_state(&(client.ssl), - &(server.ssl), - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE) + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client.ssl), &(server.ssl), + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE) , 0); mbedtls_psa_get_stats(&stats); @@ -4355,9 +2394,8 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key) (client.ssl).handshake->ecdh_psa_peerkey[0] ^= 0x02; } - TEST_EQUAL(mbedtls_move_handshake_to_state(&(client.ssl), - &(server.ssl), - MBEDTLS_SSL_HANDSHAKE_OVER), + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client.ssl), &(server.ssl), MBEDTLS_SSL_HANDSHAKE_OVER), bad_server_ecdhe_key ? MBEDTLS_ERR_SSL_HW_ACCEL_FAILED : 0); mbedtls_psa_get_stats(&stats); @@ -4369,8 +2407,8 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key) } exit: - mbedtls_endpoint_free(&client, NULL); - mbedtls_endpoint_free(&server, NULL); + mbedtls_test_ssl_endpoint_free(&client, NULL); + mbedtls_test_ssl_endpoint_free(&server, NULL); USE_PSA_DONE(); } diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 88ffe1b2e..b6df742e8 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -246,6 +246,7 @@ +