]> granicus.if.org Git - vim/commitdiff
patch 8.2.4144: cannot load libsodium dynamically v8.2.4144
authorK.Takata <kentkt@csc.jp>
Wed, 19 Jan 2022 13:32:57 +0000 (13:32 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 19 Jan 2022 13:32:57 +0000 (13:32 +0000)
Problem:    Cannot load libsodium dynamically.
Solution:   Support dynamic loading on MS-Windows. (Ken Takata, closes #9554)

src/Make_cyg_ming.mak
src/Make_mvc.mak
src/buffer.c
src/crypt.c
src/memline.c
src/proto/crypt.pro
src/version.c

index 451110975e4f51b0d7e123f75eb0b9862fc9fc3a..a415631aba913f0204a302d2384ab0f666daa2b4 100644 (file)
@@ -668,7 +668,14 @@ DEFINES += -DFEAT_DIRECTX_COLOR_EMOJI
 endif
 
 ifeq ($(SODIUM),yes)
+ ifndef DYNAMIC_SODIUM
+DYNAMIC_SODIUM=yes
+ endif
+ ifeq ($(DYNAMIC_SODIUM),yes)
+DEFINES += -DDYNAMIC_SODIUM
+ else
 SODIUMLIB = -lsodium
+ endif
 endif
 
 # Only allow XPM for a GUI build.
index b33d24b1ab6f66825e6bd16be29e5c4891d442a3..6889a91d8c44dcba3a056d26bc93476eaa71cdb6 100644 (file)
 #      Sound support: SOUND=yes (default is yes)
 #
 #      Sodium support: SODIUM=[Path to Sodium directory]
-#       Dynamic built with libsodium
-#       You need to install the msvc package from
-#       https://download.libsodium.org/libsodium/releases/
-#       and package the libsodium.dll with Vim
+#        DYNAMIC_SODIUM=yes (to load the Sodium DLL dynamically)
+#        You need to install the msvc package from
+#        https://download.libsodium.org/libsodium/releases/
+#        and package the libsodium.dll with Vim
 #
 #
 #      DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
@@ -384,6 +384,9 @@ SOUND = no
 !ifndef SODIUM
 SODIUM = no
 !endif
+!ifndef DYNAMIC_SODIUM
+DYNAMIC_SODIUM = yes
+!endif
 
 !if "$(SODIUM)" != "no"
 ! if "$(CPU)" == "AMD64"
@@ -397,8 +400,13 @@ SODIUM = no
 
 !if "$(SODIUM)" != "no"
 SOD_INC                = /I "$(SODIUM)\include"
+! if "$(DYNAMIC_SODIUM)" == "yes"
+SOD_DEFS       = -DHAVE_SODIUM -DDYNAMIC_SODIUM
+SOD_LIB                =
+! else
 SOD_DEFS       = -DHAVE_SODIUM
 SOD_LIB                = $(SOD_LIB)\libsodium.lib
+! endif
 !endif
 
 !ifndef NETBEANS
index 08db0fc28e5f435fbb040894613197f449607c67..18aa2a09e78eeb19b9cbdde28993fb8e9e76556c 100644 (file)
@@ -2269,8 +2269,9 @@ free_buf_options(
 #endif
 #ifdef FEAT_CRYPT
 # ifdef FEAT_SODIUM
-    if (buf->b_p_key != NULL && (crypt_get_method_nr(buf) == CRYPT_M_SOD))
-       sodium_munlock(buf->b_p_key, STRLEN(buf->b_p_key));
+    if ((buf->b_p_key != NULL) && (*buf->b_p_key != NUL) &&
+                               (crypt_get_method_nr(buf) == CRYPT_M_SOD))
+       crypt_sodium_munlock(buf->b_p_key, STRLEN(buf->b_p_key));
 # endif
     clear_string_option(&buf->b_p_key);
 #endif
index 85ff33a314a386a38ca36ced054fcedebf52b45c..e5d0d9167b1a1af879652b16b3da6e3cf7c93ce6 100644 (file)
@@ -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
index a42c5f1562483f50762443b3979923acd84481f3..56f6958dea1b6d4d06f39ee5459c1b8f3d2c1fd6 100644 (file)
@@ -436,7 +436,8 @@ ml_set_mfp_crypt(buf_T *buf)
        }
 #ifdef FEAT_SODIUM
        else if (method_nr == CRYPT_M_SOD)
-           randombytes_buf(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN);
+           crypt_sodium_randombytes_buf(buf->b_ml.ml_mfp->mf_seed,
+                                                           MF_SEED_LEN);
  #endif
     }
 }
index 18382a7f3ed9b7cc8754a712a90c1ce215a3cd2a..682fe4533bfcc90f783bf9137cb4c95afcfdf063 100644 (file)
@@ -26,4 +26,6 @@ void crypt_append_msg(buf_T *buf);
 int crypt_sodium_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
 long crypt_sodium_buffer_encode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
 long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
+int crypt_sodium_munlock(void *const addr, const size_t len);
+void crypt_sodium_randombytes_buf(void *const buf, const size_t size);
 /* vim: set ft=c : */
index 20a26d5d6e7989f1eb0660c4fb0763f26e569f28..86a727f8bda5fd2edbfa0508ec671c85c1ed40b4 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4144,
 /**/
     4143,
 /**/