From 1a8825d7a3484d76ca16ea2aa9769cadca7758a4 Mon Sep 17 00:00:00 2001 From: "K.Takata" Date: Wed, 19 Jan 2022 13:32:57 +0000 Subject: patch 8.2.4144: cannot load libsodium dynamically Problem: Cannot load libsodium dynamically. Solution: Support dynamic loading on MS-Windows. (Ken Takata, closes #9554) --- src/crypt.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'src/crypt.c') diff --git a/src/crypt.c b/src/crypt.c index 85ff33a314..e5d0d9167b 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -159,6 +159,108 @@ typedef struct { crypto_secretstream_xchacha20poly1305_state state; } sodium_state_T; + + +# ifdef DYNAMIC_SODIUM +# define sodium_init load_sodium +# define sodium_free dll_sodium_free +# define sodium_malloc dll_sodium_malloc +# define sodium_memzero dll_sodium_memzero +# define sodium_mlock dll_sodium_mlock +# define sodium_munlock dll_sodium_munlock +# define crypto_secretstream_xchacha20poly1305_init_push \ + dll_crypto_secretstream_xchacha20poly1305_init_push +# define crypto_secretstream_xchacha20poly1305_push \ + dll_crypto_secretstream_xchacha20poly1305_push +# define crypto_secretstream_xchacha20poly1305_init_pull \ + dll_crypto_secretstream_xchacha20poly1305_init_pull +# define crypto_secretstream_xchacha20poly1305_pull \ + dll_crypto_secretstream_xchacha20poly1305_pull +# define crypto_pwhash dll_crypto_pwhash +# define randombytes_buf dll_randombytes_buf + +static int (*dll_sodium_init)(void) = NULL; +static void (*dll_sodium_free)(void *) = NULL; +static void *(*dll_sodium_malloc)(const size_t) = NULL; +static void (*dll_sodium_memzero)(void * const, const size_t) = NULL; +static int (*dll_sodium_mlock)(void * const, const size_t) = NULL; +static int (*dll_sodium_munlock)(void * const, const size_t) = NULL; +static int (*dll_crypto_secretstream_xchacha20poly1305_init_push) + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char [], + const unsigned char []) = NULL; +static int (*dll_crypto_secretstream_xchacha20poly1305_push) + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, unsigned char tag) + = NULL; +static int (*dll_crypto_secretstream_xchacha20poly1305_init_pull) + (crypto_secretstream_xchacha20poly1305_state *state, + const unsigned char [], + const unsigned char []) = NULL; +static int (*dll_crypto_secretstream_xchacha20poly1305_pull) + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen) = NULL; +static int (*dll_crypto_pwhash)(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) + = NULL; +static void (*dll_randombytes_buf)(void * const buf, const size_t size); + +static struct { + const char *name; + FARPROC *ptr; +} sodium_funcname_table[] = { + {"sodium_init", (FARPROC*)&dll_sodium_init}, + {"sodium_free", (FARPROC*)&dll_sodium_free}, + {"sodium_malloc", (FARPROC*)&dll_sodium_malloc}, + {"sodium_memzero", (FARPROC*)&dll_sodium_memzero}, + {"sodium_mlock", (FARPROC*)&dll_sodium_mlock}, + {"sodium_munlock", (FARPROC*)&dll_sodium_munlock}, + {"crypto_secretstream_xchacha20poly1305_init_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_push}, + {"crypto_secretstream_xchacha20poly1305_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_push}, + {"crypto_secretstream_xchacha20poly1305_init_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_pull}, + {"crypto_secretstream_xchacha20poly1305_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_pull}, + {"crypto_pwhash", (FARPROC*)&dll_crypto_pwhash}, + {"randombytes_buf", (FARPROC*)&dll_randombytes_buf}, + {NULL, NULL} +}; + + static int +load_sodium(void) +{ + static HANDLE hsodium = NULL; + int i; + + if (hsodium != NULL) + return 0; + + hsodium = vimLoadLib("libsodium.dll"); + if (hsodium == NULL) + { + // TODO: Show error message. + return -1; + } + + for (i = 0; sodium_funcname_table[i].ptr; ++i) + { + if ((*sodium_funcname_table[i].ptr = GetProcAddress(hsodium, + sodium_funcname_table[i].name)) == NULL) + { + FreeLibrary(hsodium); + hsodium = NULL; + // TODO: Show error message. + return -1; + } + } + return dll_sodium_init(); +} +# endif #endif #define CRYPT_MAGIC_LEN 12 // cannot change @@ -990,4 +1092,18 @@ crypt_sodium_buffer_decode( # endif } +# if defined(FEAT_SODIUM) || defined(PROTO) + int +crypt_sodium_munlock(void *const addr, const size_t len) +{ + return sodium_munlock(addr, len); +} + + void +crypt_sodium_randombytes_buf(void *const buf, const size_t size) +{ + randombytes_buf(buf, size); +} +# endif + #endif // FEAT_CRYPT -- cgit v1.2.3