diff --git a/src/internal.c b/src/internal.c index 77e0a33df..78b46ccb0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1706,6 +1706,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_GNRC) + ctx->CBIORecv = GNRC_ReceiveFrom; + ctx->CBIOSend = GNRC_SendTo; #endif #ifdef HAVE_NTRU @@ -5021,8 +5024,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) } ssl->IOCB_ReadCtx = ssl->mnCtx; /* default Mynewt IO ctx, same for read */ ssl->IOCB_WriteCtx = ssl->mnCtx; /* and write */ +#elif defined (WOLFSSL_GNRC) + ssl->IOCB_ReadCtx = ssl->gnrcCtx; + ssl->IOCB_WriteCtx = ssl->gnrcCtx; #endif - /* initialize states */ ssl->options.serverState = NULL_STATE; ssl->options.clientState = NULL_STATE; diff --git a/src/wolfio.c b/src/wolfio.c index 3462e2b3e..c53ac57ea 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2164,6 +2164,8 @@ int uIPSend(WOLFSSL* ssl, char* buf, int sz, void* _ctx) break; total_written += ret; } while(total_written < sz); + if (total_written == 0) + return WOLFSSL_CBIO_ERR_WANT_WRITE; return total_written; } @@ -2173,8 +2175,8 @@ int uIPSendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx) int ret = 0; (void)ssl; ret = udp_socket_sendto(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr, ctx->peer_port ); - if (ret <= 0) - return 0; + if (ret == 0) + return WOLFSSL_CBIO_ERR_WANT_WRITE; return ret; } @@ -2225,4 +2227,86 @@ int uIPGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx) #endif /* WOLFSSL_UIP */ +#ifdef WOLFSSL_GNRC + +#include +#include +#include + +/* GNRC TCP/IP port, using the native tcp/udp socket api. + * TCP and UDP are currently supported with the callbacks below. + * + */ +/* The GNRC tcp send callback + * return : bytes sent, or error + */ + +int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* _ctx) +{ + sock_tls_t *ctx = (sock_tls_t *)_ctx; + int ret = 0; + (void)ssl; + if (!ctx) + return WOLFSSL_CBIO_ERR_GENERAL; + ret = sock_udp_send(&ctx->conn.udp, (unsigned char *)buf, sz, &ctx->peer_addr); + if (ret == 0) + return WOLFSSL_CBIO_ERR_WANT_WRITE; + return ret; +} + +/* The GNRC TCP/IP receive callback + * return : nb bytes read, or error + */ +int GNRC_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *_ctx) +{ + sock_udp_ep_t ep; + int ret; + uint32_t timeout = wolfSSL_dtls_get_current_timeout(ssl) * 1000000; + sock_tls_t *ctx = (sock_tls_t *)_ctx; + if (!ctx) + return WOLFSSL_CBIO_ERR_GENERAL; + (void)ssl; + if (wolfSSL_get_using_nonblock(ctx->ssl)) { + timeout = 0; + } + ret = sock_udp_recv(&ctx->conn.udp, buf, sz, timeout, &ep); + if (ret > 0) { + if (ctx->peer_addr.port == 0) + XMEMCPY(&ctx->peer_addr, &ep, sizeof(sock_udp_ep_t)); + } + if (ret == -ETIMEDOUT) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } + return ret; +} + +/* GNRC DTLS Generate Cookie callback + * return : number of bytes copied into buf, or error + */ +#define GNRC_MAX_TOKEN_SIZE (32) +int GNRC_GenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *_ctx) +{ + sock_tls_t *ctx = (sock_tls_t *)_ctx; + if (!ctx) + return WOLFSSL_CBIO_ERR_GENERAL; + byte token[GNRC_MAX_TOKEN_SIZE]; + byte digest[WC_SHA_DIGEST_SIZE]; + int ret = 0; + size_t token_size = sizeof(sock_udp_ep_t); + (void)ssl; + if (token_size > GNRC_MAX_TOKEN_SIZE) + token_size = GNRC_MAX_TOKEN_SIZE; + XMEMSET(token, 0, GNRC_MAX_TOKEN_SIZE); + XMEMCPY(token, &ctx->peer_addr, token_size); + ret = wc_ShaHash(token, token_size, digest); + if (ret != 0) + return ret; + if (sz > WC_SHA_DIGEST_SIZE) + sz = WC_SHA_DIGEST_SIZE; + XMEMCPY(buf, digest, sz); + return sz; +} + +#endif /* WOLFSSL_GNRC */ + #endif /* WOLFCRYPT_ONLY */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 85d2ac1f8..9ee111a64 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3924,6 +3924,9 @@ struct WOLFSSL { #if defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) void* mnCtx; /* mynewt mn_socket IO Context */ #endif /* defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) */ +#ifdef WOLFSSL_GNRC + struct gnrc_wolfssl_ctx *gnrcCtx; /* Riot-OS GNRC UDP/IP context */ +#endif #ifdef SESSION_INDEX int sessionIndex; /* Session's location in the cache. */ #endif diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 6d7c283dc..897792d90 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -527,9 +527,11 @@ #ifdef WOLFSSL_RIOT_OS #define NO_WRITEV #define TFM_NO_ASM - #define USE_FAST_MATH #define NO_FILESYSTEM #define USE_CERT_BUFFERS_2048 + #if defined(WOLFSSL_GNRC) && !defined(WOLFSSL_DTLS) + #define WOLFSSL_DTLS + #endif #endif #ifdef WOLFSSL_CHIBIOS diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index cc54ada78..f192eef09 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -830,9 +830,7 @@ #endif - #ifdef WOLFSSL_RIOT_OS - #define EXIT_TEST(ret) exit(ret) - #elif defined(HAVE_STACK_SIZE) + #if defined(HAVE_STACK_SIZE) #define EXIT_TEST(ret) return (void*)((size_t)(ret)) #else #define EXIT_TEST(ret) return ret diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 27290d0dc..d1b97017a 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -133,7 +133,8 @@ #include "rtipapi.h" /* errno */ #include "socket.h" #elif !defined(DEVKITPRO) && !defined(WOLFSSL_PICOTCP) \ - && !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_WICED) + && !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_WICED) \ + && !defined(WOLFSSL_GNRC) && !defined(WOLFSSL_RIOT_OS) #include #include #include @@ -491,6 +492,37 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #endif +#ifdef WOLFSSL_GNRC + #include + #include + #include + #include + #include + #include + + struct gnrc_wolfssl_ctx { + union socket_connector { + #ifdef MODULE_SOCK_TCP + sock_tcp_t tcp; + #endif + sock_udp_t udp; + } conn; + WOLFSSL_CTX *ctx; + WOLFSSL *ssl; + + int closing; + struct _sock_tl_ep peer_addr; + }; + + typedef struct gnrc_wolfssl_ctx sock_tls_t; + + WOLFSSL_LOCAL int GNRC_ReceiveFrom(WOLFSSL* ssl, char* buf, int sz, + void* ctx); + WOLFSSL_LOCAL int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx); + +#endif + + #ifdef WOLFSSL_DTLS typedef int (*CallbackGenCookie)(WOLFSSL* ssl, unsigned char* buf, int sz, void* ctx);