diff --git a/src/internal.c b/src/internal.c index 70a940bec..0f0290688 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2120,6 +2120,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) ctx->CBIORecv = Mynewt_Receive; ctx->CBIOSend = Mynewt_Send; +#elif defined WOLFSSL_LWIP_NATIVE + ctx->CBIORecv = LwIPNativeReceive; + ctx->CBIOSend = LwIPNativeSend; #elif defined(WOLFSSL_GNRC) ctx->CBIORecv = GNRC_ReceiveFrom; ctx->CBIOSend = GNRC_SendTo; diff --git a/src/wolfio.c b/src/wolfio.c index 28da546a1..2b241a4d8 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2552,4 +2552,152 @@ int GNRC_GenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx) #endif /* WOLFSSL_GNRC */ +#ifdef WOLFSSL_LWIP_NATIVE +int LwIPNativeSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ + err_t ret; + WOLFSSL_LWIP_NATIVE_STATE* nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)ctx; + + ret = tcp_write(nlwip->pcb, buf, sz, TCP_WRITE_FLAG_COPY); + if (ret != ERR_OK) { + sz = -1; + } + + return sz; +} + + +int LwIPNativeReceive(WOLFSSL* ssl, char* buf, int sz, + void* ctx) +{ + struct pbuf *current, *head; + WOLFSSL_LWIP_NATIVE_STATE* nlwip; + int ret; + + if (nlwip == NULL || ctx == NULL) { + return WOLFSSL_CBIO_ERR_GENERAL; + } + nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)ctx; + + current = nlwip->pbuf; + if (current == NULL) { + WOLFSSL_MSG("LwIP native pbuf list is null, want read"); + ret = WOLFSSL_CBIO_ERR_WANT_READ; + } + else { + int read = 0; /* total amount read */ + head = nlwip->pbuf; /* save pointer to current head */ + + /* loop through buffers reading data */ + while (current != NULL) { + int len; /* current amount to be read */ + + len = (current->len - nlwip->pulled < sz) ? + (current->len - nlwip->pulled) : sz; + + if (read + len > sz) { + /* should never be hit but have sanity check before use */ + return WOLFSSL_CBIO_ERR_GENERAL; + } + + WOLFSSL_MSG("Reading from payload"); + /* check if is a partial read from before */ + XMEMCPY(&buf[read], + (const char *)&(((char *)(current->payload))[nlwip->pulled]), + + len); + nlwip->pulled = nlwip->pulled + len; + if (nlwip->pulled >= current->len) { + WOLFSSL_LEAVE("Read full pbuf, advancing. LEN was ", + current->len); + nlwip->pbuf = current->next; + current = nlwip->pbuf; + nlwip->pulled = 0; + } + read = read + len; + + /* read enough break out */ + if (read >= sz) { + /* if more pbuf's are left in the chain then increment the + * ref count for next in chain and free all from begining till + * next */ + if (current != NULL) { + WOLFSSL_MSG("Case where partial read or at next"); + pbuf_ref(current); + } + + /* ack and start free'ing from the current head of the chain */ + pbuf_free(head); + ret = read; + break; + } + } + } + WOLFSSL_LEAVE("LwIPNativeReceive", ret); + return ret; +} + + +static err_t LwIPNativeReceiveCB(void* cb, struct tcp_pcb* pcb, + struct pbuf* pbuf, err_t err) +{ + WOLFSSL_LWIP_NATIVE_STATE* nlwip; + + if (cb == NULL || pcb == NULL) { + WOLFSSL_MSG("Expected callback was null, abort"); + return ERR_ABRT; + } + + nlwip = (WOLFSSL_LWIP_NATIVE_STATE*)cb; + if (pbuf == NULL && err == ERR_OK) { + return ERR_OK; + } + + if (nlwip->pbuf == NULL) { + nlwip->pbuf = pbuf; + } + else { + if (nlwip->pbuf != pbuf) { + tcp_recved(nlwip->pcb, pbuf->tot_len); + pbuf_cat(nlwip->pbuf, pbuf); /* add chain to head */ + } + } + return ERR_OK; +} + + +static err_t LwIPNativeSentCB(void* cb, struct tcp_pcb* pcb, u16_t len) +{ + (void)cb; + (void)pcb; + (void)len; + return ERR_OK; +} + + +int wolfSSL_SetIO_LwIP(WOLFSSL* ssl, void* pcb, + tcp_recv_fn recv_fn, tcp_sent_fn sent_fn, void *arg) +{ + if (ssl == NULL || pcb == NULL) + return BAD_FUNC_ARG; + + ssl->lwipCtx.pcb = (struct tcp_pcb *)pcb; + ssl->lwipCtx.recv_fn = recv_fn; /* recv user callback */ + ssl->lwipCtx.sent_fn = sent_fn; /* sent user callback */ + ssl->lwipCtx.arg = arg; + ssl->lwipCtx.pbuf = 0; + ssl->lwipCtx.pulled = 0; + ssl->lwipCtx.wait = 0; + + /* wolfSSL_LwIP_recv/sent_cb invokes recv/sent user callback in them. */ + tcp_recv(pcb, LwIPNativeReceiveCB); + tcp_sent(pcb, LwIPNativeSentCB); + tcp_arg (pcb, (void *)&(ssl->lwipCtx)); + wolfSSL_SetIOReadCtx(ssl, &ssl->lwipCtx); + wolfSSL_SetIOWriteCtx(ssl, &ssl->lwipCtx); + + return ERR_OK; +} +#endif + #endif /* WOLFCRYPT_ONLY */ diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 30de50f63..8704416f5 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -2476,6 +2476,33 @@ time_t time(time_t * timer) } #endif /* WOLFSSL_LINUXKM */ +#ifdef HAL_RTC_MODULE_ENABLED +extern RTC_HandleTypeDef hrtc; +time_t stm32_hal_time(time_t *t1) +{ + struct tm tm_time; + time_t ret; + RTC_TimeTypeDef time; + RTC_DateTypeDef date; + + /* must get time and date here due to STM32 HW bug */ + HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN); + HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN); + + tm_time.tm_year = date.Year; + tm_time.tm_mon = date.Month - 1; /* gm starts at 0 */ + tm_time.tm_mday = date.Date; + tm_time.tm_hour = time.Hours; + tm_time.tm_min = time.Minutes; + tm_time.tm_sec = time.Seconds; + + ret = mktime(&tm_time); + if (t1 != NULL) + *t1 = ret; + return ret; +} +#endif /* HAL_RTC_MODULE_ENABLED */ + #endif /* !NO_ASN_TIME */ #if !defined(WOLFSSL_LEANPSK) && !defined(STRING_USER) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 82171d2af..13a670dbd 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4521,6 +4521,9 @@ struct WOLFSSL { #if defined(WOLFSSL_IOTSAFE) && defined(HAVE_PK_CALLBACKS) IOTSAFE iotsafe; #endif +#ifdef WOLFSSL_LWIP_NATIVE + WOLFSSL_LWIP_NATIVE_STATE lwipCtx; /* LwIP native socket IO Context */ +#endif }; /* diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 9252f7111..6034b3170 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2300,6 +2300,13 @@ extern void uITRON4_free(void *p) ; #define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 #endif +#ifdef WOLFSSL_LWIP_NATIVE + #include "lwip/tcp.h" + #include "lwip/sockets.h" + + #undef WOLFSSL_USER_IO + #define WOLFSSL_USER_IO +#endif /* both CURVE and ED small math should be enabled */ #ifdef CURVED25519_SMALL diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index b9c43f678..3ebbe65a8 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1388,6 +1388,11 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #endif /* BUILDING_WOLFSSL */ +#elif defined(HAL_RTC_MODULE_ENABLED) + #include + WOLFSSL_LOCAL time_t* stm32_hal_time(time_t* t1); + #define XTIME(t1) stm32_hal_time(t1) + #define WOLFSSL_GMTIME #else /* default */ /* uses complete facility */ diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 93d7d0371..5e3d981ce 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -277,6 +277,14 @@ #define SOCKET_EPIPE FCL_EPIPE #define SOCKET_ECONNREFUSED FCL_ECONNREFUSED #define SOCKET_ECONNABORTED FNS_ECONNABORTED +#elif defined(WOLFSSL_LWIP_NATIVE) + #define SOCKET_EWOULDBLOCK ERR_WOULDBLOCK + #define SOCKET_EAGAIN ERR_WOULDBLOCK + #define SOCKET_ECONNRESET ERR_RST + #define SOCKET_EINTR ERR_CLSD + #define SOCKET_EPIPE ERR_CLSD + #define SOCKET_ECONNREFUSED ERR_CONN + #define SOCKET_ECONNABORTED ERR_ABRT #else #define SOCKET_EWOULDBLOCK EWOULDBLOCK #define SOCKET_EAGAIN EAGAIN @@ -584,6 +592,24 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #endif +#ifdef WOLFSSL_LWIP_NATIVE + typedef struct WOLFSSL_LWIP_NATIVE_STATE { + struct tcp_pcb * pcb; + tcp_recv_fn recv_fn; + tcp_sent_fn sent_fn; + int pulled; + struct pbuf *pbuf; + int wait; + void * arg; /* arg for application */ + int idle_count; + } WOLFSSL_LWIP_NATIVE_STATE; + + WOLFSSL_LOCAL int LwIPNativeSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_LOCAL int LwIPNativeReceive(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_API int wolfSSL_SetIO_LwIP(WOLFSSL* ssl, void *pcb, + tcp_recv_fn recv, tcp_sent_fn sent, void *arg); +#endif #ifdef WOLFSSL_DTLS typedef int (*CallbackGenCookie)(WOLFSSL* ssl, unsigned char* buf, int sz,