From 6425ebb60ed7a7bc0f1b49969ef384ad284215bc Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 19 Nov 2015 13:36:21 -0800 Subject: [PATCH] Linux Kernel Module support using "--enable-linuxkm". --- .gitignore | 1 + configure.ac | 14 +++++++++++ src/internal.c | 12 ++++++++- src/wolfio.c | 48 ++++++++++++++++++++++++++++++------ wolfcrypt/src/logging.c | 5 +++- wolfcrypt/src/random.c | 11 +++++++++ wolfcrypt/src/wc_port.c | 17 +++++++++++++ wolfssl/internal.h | 7 +++++- wolfssl/wolfcrypt/integer.h | 6 ++++- wolfssl/wolfcrypt/memory.h | 2 +- wolfssl/wolfcrypt/settings.h | 16 ++++++++++++ wolfssl/wolfcrypt/types.h | 34 ++++++++++++++++++------- wolfssl/wolfcrypt/wc_port.h | 21 +++++++++++++--- wolfssl/wolfio.h | 5 ++++ 14 files changed, 175 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 91b6af694..2d534cda7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ config.* *.suo *.sdf *.opensdf +*.cmd ipch/ build-aux/ rpm/spec diff --git a/configure.ac b/configure.ac index 8a72025c1..bf9a5c8bc 100644 --- a/configure.ac +++ b/configure.ac @@ -3365,6 +3365,19 @@ then fi +# Linux Kernel Module +AC_ARG_ENABLE([linuxkm], + [ --enable-linuxkm Enable Linux Kernel Module (default: disabled)], + [ ENABLED_LINUXKM=$enableval ], + [ ENABLED_LINUXKM=no ] + ) + +if test "x$ENABLED_LINUXKM" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LINUXKM" +fi + + #valgrind AC_ARG_ENABLE([valgrind], [AS_HELP_STRING([--enable-valgrind],[Enable valgrind for unit tests (default: disabled)])], @@ -5630,6 +5643,7 @@ echo " * wolfSSH $ENABLED_WOLFSSH" echo " * wolfSCEP $ENABLED_WOLFSCEP" echo " * Secure Remote Password $ENABLED_SRP" echo " * Small Stack: $ENABLED_SMALL_STACK" +echo " * Linux Kernel Module: $ENABLED_LINUXKM" echo " * valgrind unit tests: $ENABLED_VALGRIND" echo " * LIBZ: $ENABLED_LIBZ" echo " * Examples: $ENABLED_EXAMPLES" diff --git a/src/internal.c b/src/internal.c index a666f63d4..b16ff32c5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -71,7 +71,7 @@ #if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || \ defined(CHACHA_AEAD_TEST) || defined(WOLFSSL_SESSION_EXPORT_DEBUG) - #ifndef NO_STDIO_FILESYSTEM + #if !defined(NO_STDIO_FILESYSTEM) && !defined(WOLFSSL_LINUXKM) #include #endif #endif @@ -7647,6 +7647,16 @@ ProtocolVersion MakeDTLSv1_2(void) return k_uptime_get() / 1000; } +#elif defined(WOLFSSL_LINUXKM) + #include + #include + word32 LowResTimer(void) + { + struct timespec ts; + getnstimeofday(&ts); + return ts.tv_sec * 1000000000LL + ts.tv_nsec; + } + #else /* Posix style time */ #if !defined(USER_TIME) && !defined(USE_WOLF_TM) diff --git a/src/wolfio.c b/src/wolfio.c index 86107f40b..e00c87ea5 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -88,12 +88,16 @@ static WC_INLINE int TranslateReturnCode(int old, int sd) return old; } -static WC_INLINE int wolfSSL_LastError(void) +static WC_INLINE int wolfSSL_LastError(int err) { + (void)err; /* Suppress unused arg */ + #ifdef USE_WINDOWS_API return WSAGetLastError(); #elif defined(EBSNET) return xn_getlasterror(); +#elif defined(WOLFSSL_LINUXKM) + return err; /* Return provided error value */ #else return errno; #endif @@ -214,12 +218,16 @@ int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) */ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) { - int sd = *(int*)ctx; int recvd; +#ifndef WOLFSSL_LINUXKM + int sd = *(int*)ctx; +#else + struct socket *sd = (struct socket*)ctx; +#endif recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags); if (recvd < 0) { - int err = wolfSSL_LastError(); + int err = wolfSSL_LastError(recvd); WOLFSSL_MSG("Embed Receive error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { @@ -256,8 +264,12 @@ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) */ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) { - int sd = *(int*)ctx; int sent; +#ifndef WOLFSSL_LINUXKM + int sd = *(int*)ctx; +#else + struct socket *sd = (struct socket*)ctx; +#endif #ifdef WOLFSSL_MAX_SEND_SZ if (sz > WOLFSSL_MAX_SEND_SZ) @@ -266,7 +278,7 @@ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) sent = wolfIO_Send(sd, buf, sz, ssl->wflags); if (sent < 0) { - int err = wolfSSL_LastError(); + int err = wolfSSL_LastError(sent); WOLFSSL_MSG("Embed Send error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { @@ -343,7 +355,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) recvd = TranslateReturnCode(recvd, sd); if (recvd < 0) { - err = wolfSSL_LastError(); + err = wolfSSL_LastError(recvd); WOLFSSL_MSG("Embed Receive From error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { @@ -405,7 +417,7 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) sent = TranslateReturnCode(sent, sd); if (sent < 0) { - err = wolfSSL_LastError(); + err = wolfSSL_LastError(sent); WOLFSSL_MSG("Embed Send To error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { @@ -638,6 +650,28 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) #endif /* WOLFSSL_SESSION_EXPORT */ #endif /* WOLFSSL_DTLS */ +#ifdef WOLFSSL_LINUXKM +static int linuxkm_send(struct socket *socket, void *buf, int size, + unsigned int flags) +{ + int ret; + struct kvec vec = { .iov_base = buf, .iov_len = size }; + struct msghdr msg = { .msg_flags = flags }; + ret = kernel_sendmsg(socket, &msg, &vec, 1, size); + return ret; +} + +static int linuxkm_recv(struct socket *socket, void *buf, int size, + unsigned int flags) +{ + int ret; + struct kvec vec = { .iov_base = buf, .iov_len = size }; + struct msghdr msg = { .msg_flags = flags }; + ret = kernel_recvmsg(socket, &msg, &vec, 1, size, msg.msg_flags); + return ret; +} +#endif /* WOLFSSL_LINUXKM */ + int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags) { diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index da4dea5bd..8b53f77da 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -232,6 +232,8 @@ void WOLFSSL_TIME(int count) #include #elif defined(WOLFSSL_XILINX) #include "xil_printf.h" +#elif defined(WOLFSSL_LINUXKM) + #include #else #include /* for default printf stuff */ #endif @@ -265,7 +267,6 @@ static void wolfssl_log(const int logLevel, const char *const logMessage) fnDebugMsg("\r\n"); #elif defined(MQX_USE_IO_OLD) fprintf(_mqxio_stderr, "%s\n", logMessage); - #elif defined(WOLFSSL_APACHE_MYNEWT) LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage); #elif defined(WOLFSSL_ESPIDF) @@ -278,6 +279,8 @@ static void wolfssl_log(const int logLevel, const char *const logMessage) __android_log_print(ANDROID_LOG_VERBOSE, "[wolfSSL]", "%s", logMessage); #elif defined(WOLFSSL_XILINX) xil_printf("%s\r\n", logMessage); +#elif defined(WOLFSSL_LINUXKM) + printk("%s\n", logMessage); #else fprintf(stderr, "%s\n", logMessage); #endif diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index c60906ce0..a473b887f 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2387,6 +2387,17 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } #endif /* end WOLFSSL_ESPWROOM32 */ + +#elif defined(WOLFSSL_LINUXKM) + #include + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + (void)os; + + get_random_bytes(output, sz); + + return 0; + } #elif defined(WOLFSSL_RENESAS_TSIP) #if defined(WOLFSSL_RENESA_TSIP_IAREWRX) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 12716806d..ff679f153 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -2260,6 +2260,23 @@ time_t wiced_pseudo_unix_epoch_time(time_t * timer) #endif /* !NO_CRYPT_BENCHMARK */ #endif /* WOLFSSL_TELIT_M2MB */ + +#if defined(WOLFSSL_LINUXKM) + +unsigned long long GetUNIXCompatibleTime(void) +{ + struct timespec ts; + getnstimeofday(&ts); + return ts.tv_sec * 1000000000LL + ts.tv_nsec; +} + +time_t XTIME(time_t * timer) +{ + return (time_t) (GetUNIXCompatibleTime() / 1000000000LL); +} + +#endif /* WOLFSSL_LINUXKM */ + #endif /* !NO_ASN_TIME */ #ifndef WOLFSSL_LEANPSK diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 14aa5991e..1fe6d4252 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -186,7 +186,12 @@ /* do nothing */ #else #ifndef SINGLE_THREADED - #ifndef WOLFSSL_USER_MUTEX + #if defined(WOLFSSL_LINUXKM) + #define WOLFSSL_KTHREADS + #include + #elif defined(WOLFSSL_USER_MUTEX) + /* do nothing */ + #else #define WOLFSSL_PTHREADS #include #endif diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 2bd06ae2e..b1895d6cc 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -42,7 +42,11 @@ #include #ifndef CHAR_BIT - #include + #if defined(WOLFSSL_LINUXKM) + #include + #else + #include + #endif #endif #include diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 688110b4e..d901b2f92 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -29,7 +29,7 @@ #ifndef WOLFSSL_MEMORY_H #define WOLFSSL_MEMORY_H -#ifndef STRING_USER +#if !defined(STRING_USER) && !defined(WOLFSSL_LINUXKM) #include #endif #include diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index f92b8d558..c373b89ec 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -215,6 +215,10 @@ /* Uncomment next line if using Solaris OS*/ /* #define WOLFSSL_SOLARIS */ +/* Uncomment next line if building for Linux Kernel Module */ +/* #define WOLFSSL_LINUXKM */ + + #include #ifdef WOLFSSL_USER_SETTINGS @@ -2081,6 +2085,18 @@ extern void uITRON4_free(void *p) ; #endif +#ifdef WOLFSSL_LINUXKM + #define NO_DEV_RANDOM + #define NO_WRITEV + #define NO_FILESYSTEM + #define SIZEOF_LONG 8 + #define SIZEOF_LONG_LONG 8 + #define CHAR_BIT 8 + #define WOLFSSL_HAVE_MIN + #define WOLFSSL_HAVE_MAX +#endif + + /* Place any other flags or defines here */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) && defined(_WIN32) \ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 5301e161e..577f3a54d 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -351,6 +351,13 @@ decouple library dependencies with standard string, memory and so on. #define XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} #define XREALLOC(p, n, h, t) realloc((p), (size_t)(n)) #endif + + #elif defined(WOLFSSL_LINUXKM) + #include + #define XMALLOC(s, h, t) ((void)h, (void)t, kmalloc((s), GFP_KERNEL)) + #define XFREE(p, h, t) {void* xp = (p); if((xp)) kfree((xp));} + #define XREALLOC(p, n, h, t) krealloc((p), (n), GFP_KERNEL) + #elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \ && !defined(WOLFSSL_SAFERTOS) && !defined(FREESCALE_MQX) \ && !defined(FREESCALE_KSDK_MQX) && !defined(FREESCALE_FREE_RTOS) \ @@ -442,12 +449,17 @@ decouple library dependencies with standard string, memory and so on. #define USE_WOLF_STRSEP #endif - #ifndef STRING_USER - #include - #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) - #define XMEMSET(b,c,l) memset((b),(c),(l)) - #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) - #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) + #ifndef STRING_USER + #if defined(WOLFSSL_LINUXKM) + #include + #else + #include + #endif + + #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) + #define XMEMSET(b,c,l) memset((b),(c),(l)) + #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) + #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) #define XSTRLEN(s1) strlen((s1)) #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) @@ -570,9 +582,13 @@ decouple library dependencies with standard string, memory and so on. #endif #endif /* OPENSSL_EXTRA */ - #ifndef CTYPE_USER - #include - #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ + #ifndef CTYPE_USER + #if defined(WOLFSSL_LINUXKM) + #include + #else + #include + #endif + #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \ defined(WOLFSSL_KEY_GEN) || !defined(NO_DSA) #define XTOUPPER(c) toupper((c)) #define XISALPHA(c) isalpha((c)) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 08a1d2f9e..fadae9503 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -156,9 +156,14 @@ #else #ifndef SINGLE_THREADED - #ifndef WOLFSSL_USER_MUTEX - #define WOLFSSL_PTHREADS - #include + #ifndef WOLFSSL_USER_MUTEX + #if defined(WOLFSSL_LINUXKM) + #define WOLFSSL_KTHREADS + #include + #else + #define WOLFSSL_PTHREADS + #include + #endif #endif #endif #if (defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)) && \ @@ -242,6 +247,8 @@ typedef M2MB_OS_MTX_HANDLE wolfSSL_Mutex; #elif defined(WOLFSSL_USER_MUTEX) /* typedef User_Mutex wolfSSL_Mutex; */ + #elif defined(WOLFSSL_LINUXKM) + typedef struct mutex wolfSSL_Mutex; #else #error Need a mutex type in multithreaded mode #endif /* USE_WINDOWS_API */ @@ -664,6 +671,14 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #define WOLFSSL_GMTIME #define USE_WOLF_TM + +#elif defined(WOLFSSL_LINUXKM) + #include + #include + + /* forward declaration */ + struct tm* gmtime(const time_t* timer); + #define XGMTIME(c, t) gmtime((c)) #else /* default */ /* uses complete facility */ diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index ccbe6a2ad..32940dd64 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -94,6 +94,8 @@ #elif defined(WOLFSSL_NUCLEUS_1_2) #include #include + #elif defined(WOLFSSL_LINUXKM) + #include #elif defined(WOLFSSL_ATMEL) #include "socket/include/socket.h" #elif defined(INTIME_RTOS) @@ -295,6 +297,9 @@ #define SEND_FUNCTION send #define RECV_FUNCTION recv +#elif defined(WOLFSSL_LINUXKM) + #define SEND_FUNCTION linuxkm_send + #define RECV_FUNCTION linuxkm_recv #else #define SEND_FUNCTION send #define RECV_FUNCTION recv