From 247cbdeef7efcb6b72dc4343604b2e4dcac74c3c Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 4 Jan 2022 12:42:16 +0000 Subject: [PATCH] Cleanups for ISO-TP in wolfio * Add Doxygen comments * Make ISOTP_Send, ISOTP_Receive and wolfSSL_SetIO_ISOTP safer * Reorder isotp_wolfssl_ctx * Other minor cleanups --- doc/dox_comments/header_files/wolfio.h | 38 ++++++++++++++++++++++++ src/wolfio.c | 41 ++++++++++++++------------ wolfssl/wolfio.h | 19 ++++++------ 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index 0c1f94e8d..0c7f8300f 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -537,3 +537,41 @@ WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX*, CallbackGenCookie); \sa wolfSSL_CTX_SetGenCookie */ WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl); + + +/*! + \ingroup Setup + + \brief This function sets up the ISO-TP context if wolfSSL, for use when + wolfSSL is compiled with WOLFSSL_ISOTP + + \return 0 on success, WOLFSSL_CBIO_ERR_GENERAL on failure + + \param ssl the wolfSSL context + \param ctx a user created ISOTP context which this function initializes + \param recv_fn a user CAN bus receive callback + \param send_fn a user CAN bus send callback + \param delay_fn a user microsecond granularity delay function + \param receive_delay a set amount of microseconds to delay each CAN bus + packet + \param receive_buffer a user supplied buffer to receive data, recommended + that is allocated to ISOTP_DEFAULT_BUFFER_SIZE bytes + \param receive_buffer_size - The size of receive_buffer + \param arg an arbitrary pointer sent to recv_fn and send_fn + + _Example_ + \code + struct can_info can_con_info; + isotp_wolfssl_ctx isotp_ctx; + char *receive_buffer = malloc(ISOTP_DEFAULT_BUFFER_SIZE); + WOLFSSL_CTX* ctx = wolfSSL_CTX_new(method); + WOLFSSL* ssl = wolfSSL_new(ctx); + ... + wolfSSL_SetIO_ISOTP(ssl, &isotp_ctx, can_receive, can_send, can_delay, 0, + receive_buffer, ISOTP_DEFAULT_BUFFER_SIZE, &can_con_info); + \endcode + */ +WOLFSSL_API int wolfSSL_SetIO_ISOTP(WOLFSSL *ssl, isotp_wolfssl_ctx *ctx, + can_recv_fn recv_fn, can_send_fn send_fn, can_delay_fn delay_fn, + word32 receive_delay, char *receive_buffer, int receive_buffer_size, + void *arg); diff --git a/src/wolfio.c b/src/wolfio.c index 5a1ee67e8..97e6e7697 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2872,9 +2872,16 @@ static int isotp_send_first_frame(struct isotp_wolfssl_ctx *ctx, char *buf, int ISOTP_Send(WOLFSSL* ssl, char* buf, int sz, void* ctx) { - (void) ssl; int ret; - struct isotp_wolfssl_ctx *isotp_ctx = (struct isotp_wolfssl_ctx*) ctx; + struct isotp_wolfssl_ctx *isotp_ctx; + (void) ssl; + + if (!ctx) { + WOLFSSL_MSG("ISO-TP requires wolfSSL_SetIO_ISOTP to be called first"); + return WOLFSSL_CBIO_ERR_TIMEOUT; + } + isotp_ctx = (struct isotp_wolfssl_ctx*) ctx; + if (sz > ISOTP_MAX_DATA_SIZE) { WOLFSSL_MSG("ISO-TP packets can be at most 4095 bytes"); return WOLFSSL_CBIO_ERR_GENERAL; @@ -2984,14 +2991,20 @@ static int isotp_receive_multi_frame(struct isotp_wolfssl_ctx *ctx) * incoming data, even if wolfSSL doesn't want it all yet */ int ISOTP_Receive(WOLFSSL* ssl, char* buf, int sz, void* ctx) { - (void) ssl; enum isotp_frame_type type; int ret; - struct isotp_wolfssl_ctx *isotp_ctx = (struct isotp_wolfssl_ctx*)ctx; + struct isotp_wolfssl_ctx *isotp_ctx; + (void) ssl; + + if (!ctx) { + WOLFSSL_MSG("ISO-TP requires wolfSSL_SetIO_ISOTP to be called first"); + return WOLFSSL_CBIO_ERR_TIMEOUT; + } + isotp_ctx = (struct isotp_wolfssl_ctx*)ctx; /* Is buffer empty? If so, fill it */ if (!isotp_ctx->receive_buffer_len) { - /* Can't send whilst we are receiving */ + /* Can't send whilst we are receiving */ if (isotp_ctx->state != ISOTP_CONN_STATE_IDLE) { return WOLFSSL_ERROR_WANT_READ; } @@ -3047,25 +3060,15 @@ int ISOTP_Receive(WOLFSSL* ssl, char* buf, int sz, void* ctx) } } -/* Setup ISPTP - * - * Parameters: - * ssl - The wolfSSL context - * ctx - A user created ISOTP context which this function initializes - * recv_fn - A user CAN bus receive callback - * send_fn - A user CAN bus send callback - * delay_fn - A user microsecond granularity delay function - * receive_delay - A set amount of microseconds to delay each CAN bus packet - * receive_buffer - A user supplied buffer to receive data, recommended that is - * allocated to ISOTP_DEFAULT_BUFFER_SIZE bytes - * receive_buffer_size - The size of receive_buffer - * arg - An arbitrary pointer sent to recv_fn and send_fn - */ int wolfSSL_SetIO_ISOTP(WOLFSSL *ssl, isotp_wolfssl_ctx *ctx, can_recv_fn recv_fn, can_send_fn send_fn, can_delay_fn delay_fn, word32 receive_delay, char *receive_buffer, int receive_buffer_size, void *arg) { + if (!ctx || !recv_fn || !send_fn || !delay_fn || !receive_buffer) { + WOLFSSL_MSG("ISO-TP has missing required parameter"); + return WOLFSSL_CBIO_ERR_GENERAL; + } ctx->recv_fn = recv_fn; ctx->send_fn = send_fn; ctx->arg = arg; diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 3e763f63b..e60f4e6d0 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -649,7 +649,7 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); }; typedef struct isotp_can_data { - byte data[8]; + byte data[ISOTP_CAN_BUS_PAYLOAD_SIZE]; byte length; } isotp_can_data; @@ -662,25 +662,24 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); typedef void (*can_delay_fn)(int microseconds); typedef struct isotp_wolfssl_ctx { - int socket; struct isotp_can_data frame; + char *buf_ptr; + char *receive_buffer; + char *receive_buffer_ptr; can_recv_fn recv_fn; can_send_fn send_fn; can_delay_fn delay_fn; + void *arg; + int receive_buffer_len; + int receive_buffer_size; + enum isotp_connection_state state; + word16 buf_length; byte sequence; byte flow_packets; byte flow_counter; byte frame_delay; byte wait_counter; - char *buf_ptr; - word16 buf_length; byte receive_delay; - char *receive_buffer; - char *receive_buffer_ptr; - int receive_buffer_len; - int receive_buffer_size; - enum isotp_connection_state state; - void *arg; } isotp_wolfssl_ctx; WOLFSSL_LOCAL int ISOTP_Receive(WOLFSSL* ssl, char* buf, int sz, void* ctx);