]> granicus.if.org Git - vim/commitdiff
patch 8.2.3032: build problems with MSVC, other crypt issues with libsodium v8.2.3032
authorChristian Brabandt <cb@256bit.org>
Mon, 21 Jun 2021 19:08:08 +0000 (21:08 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 21 Jun 2021 19:08:08 +0000 (21:08 +0200)
Problem:    Build problems with MSVC, other crypt issues with libsodium.
Solution:   Adjust MSVC makefile. Disable swap file only when 'key' is set.
            Adjust error message used when key is wrong.  Fix Coverity issues.
            (Christian Brabandt, closes #8420, closes #8411)

src/Make_mvc.mak
src/crypt.c
src/errors.h
src/fileio.c
src/memline.c
src/proto/crypt.pro
src/version.c

index c61bb27ab7232285c633e3bd305db118b8849a25..4d6e49b37703a57d03d9853ae40714e4e5573394 100644 (file)
 #      Sound support: SOUND=yes (default is yes)
 #
 #      Sodium support: SODIUM=[Path to Sodium directory]
-#       You need to install the msvc package from https://download.libsodium.org/libsodium/releases/
+#       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
+#
 #
 #      DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
 #        Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
@@ -383,14 +387,14 @@ SODIUM = no
 ! if "$(CPU)" == "AMD64"
 SOD_LIB                = $(SODIUM)\x64\Release\v140\dynamic
 ! elseif "$(CPU)" == "i386"
-SOD_LIB                = $(SODIUM)\x86\Release\v140\dynamic
+SOD_LIB                = $(SODIUM)\Win32\Release\v140\dynamic
 ! else
 SODIUM = no
 ! endif
 !endif
 
 !if "$(SODIUM)" != "no"
-SOD_INC                = -I $(SODIUM)\include
+SOD_INC                = /I "$(SODIUM)\include"
 SOD_DEFS       = -DFEAT_SODIUM
 SOD_LIB                = $(SOD_LIB)\libsodium.lib
 !endif
@@ -514,7 +518,7 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
 
 CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
                $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
-               $(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) \
+               $(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) $(SOD_INC) \
                $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
 
 #>>>>> end of choices
@@ -726,7 +730,7 @@ CFLAGS = $(CFLAGS) $(CFLAGS_DEPR)
 
 INCL = vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
        keymap.h macros.h option.h os_dos.h os_win32.h proto.h regexp.h \
-       spell.h structs.h term.h beval.h $(NBDEBUG_INCL) $(SOD_INC)
+       spell.h structs.h term.h beval.h $(NBDEBUG_INCL)
 
 OBJ = \
        $(OUTDIR)\arabic.obj \
index f844e4209d520c08264187e759cf446ba911f081..1b2ece5db4f243a79b54fcac368ef8a42028ae62 100644 (file)
@@ -146,9 +146,9 @@ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
        FALSE,
        NULL,
        crypt_sodium_init,
-       crypt_sodium_encode, crypt_sodium_decode,
+       NULL, NULL,
        crypt_sodium_buffer_encode, crypt_sodium_buffer_decode,
-       crypt_sodium_encode, crypt_sodium_decode,
+       NULL, NULL,
     },
 
     // NOTE: when adding a new method, use some random bytes for the magic key,
@@ -250,6 +250,26 @@ crypt_get_header_len(int method_nr)
        + cryptmethods[method_nr].seed_len;
 }
 
+
+/*
+ * Get maximum crypt method specific length of the file header in bytes.
+ */
+    int
+crypt_get_max_header_len()
+{
+    int i;
+    int max = 0;
+    int temp = 0;
+
+    for (i = 0; i < CRYPT_M_COUNT; ++i)
+    {
+       temp = crypt_get_header_len(i);
+       if (temp > max)
+           max = temp;
+    }
+    return max;
+}
+
 /*
  * Set the crypt method for buffer "buf" to "method_nr" using the int value as
  * returned by crypt_method_nr_from_name().
@@ -403,8 +423,10 @@ crypt_create_for_writing(
 #ifdef FEAT_SODIUM
        if (sodium_init() >= 0)
        {
-           randombytes_buf(salt, salt_len);
-           randombytes_buf(seed, seed_len);
+           if (salt_len > 0)
+               randombytes_buf(salt, salt_len);
+           if (seed_len > 0)
+               randombytes_buf(seed, seed_len);
        }
        else
 #endif
@@ -581,6 +603,13 @@ crypt_check_method(int method)
        msg_scroll = TRUE;
        msg(_("Warning: Using a weak encryption method; see :help 'cm'"));
     }
+}
+
+#ifdef FEAT_SODIUM
+    static void
+crypt_check_swapfile_curbuf(void)
+{
+    int method = crypt_get_method_nr(curbuf);
     if (method == CRYPT_M_SOD)
     {
        // encryption uses padding and MAC, that does not work very well with
@@ -590,11 +619,11 @@ crypt_check_method(int method)
 #ifdef FEAT_PERSISTENT_UNDO
        set_option_value((char_u *)"udf", 0, NULL, OPT_LOCAL);
 #endif
-
        msg_scroll = TRUE;
        msg(_("Note: Encryption of swapfile not supported, disabling swap- and undofile"));
     }
 }
+#endif
 
     void
 crypt_check_current_method(void)
@@ -647,6 +676,9 @@ crypt_get_key(
                set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
                crypt_free_key(p1);
                p1 = curbuf->b_p_key;
+#ifdef FEAT_SODIUM
+               crypt_check_swapfile_curbuf();
+#endif
            }
            break;
        }
@@ -654,10 +686,13 @@ crypt_get_key(
     }
 
     // since the user typed this, no need to wait for return
-    if (msg_didout)
-       msg_putchar('\n');
-    need_wait_return = FALSE;
-    msg_didout = FALSE;
+    if (crypt_get_method_nr(curbuf) != CRYPT_M_SOD)
+    {
+       if (msg_didout)
+           msg_putchar('\n');
+       need_wait_return = FALSE;
+       msg_didout = FALSE;
+    }
 
     crypt_free_key(p2);
     return p1;
@@ -726,6 +761,7 @@ crypt_sodium_init(
  * "from" and "to" can be equal to encrypt in place.
  * Call needs to ensure that there is enough space in to (for the header)
  */
+#if 0  // Currently unused
     void
 crypt_sodium_encode(
     cryptstate_T *state UNUSED,
@@ -764,11 +800,13 @@ crypt_sodium_encode(
     sod_st->count++;
 # endif
 }
+#endif
 
-/* TODO: Unused
+/*
  * Decrypt "from[len]" into "to[len]".
  * "from" and "to" can be equal to encrypt in place.
  */
+#if 0  // Currently unused
     void
 crypt_sodium_decode(
     cryptstate_T *state UNUSED,
@@ -841,6 +879,7 @@ fail:
     vim_free(buf_out);
 # endif
 }
+#endif
 
 /*
  * Encrypt "from[len]" into "to[len]".
@@ -864,7 +903,7 @@ crypt_sodium_buffer_encode(
     sodium_state_T     *sod_st = state->method_state;
     int                        first = (sod_st->count == 0);
 
-    length = len + crypto_secretstream_xchacha20poly1305_ABYTES
+    length = (int)len + crypto_secretstream_xchacha20poly1305_ABYTES
             + (first ? crypto_secretstream_xchacha20poly1305_HEADERBYTES : 0);
     *buf_out = alloc_clear(length);
     if (*buf_out == NULL)
index 9663ecdd699e8221ab4945c23ef9feb78f963616..8a2461b31eb8cb9f681e69ff43f69e2da48d3a78 100644 (file)
@@ -443,6 +443,6 @@ EXTERN char e_libsodium_decryption_failed_header_incomplete[]
 EXTERN char e_libsodium_cannot_decrypt_buffer[]
        INIT(= N_("E1199: Cannot decrypt buffer, not enough space"));
 EXTERN char e_libsodium_decryption_failed[]
-       INIT(= N_("E1200: Decryption failed: corrupted chunk!"));
+       INIT(= N_("E1200: Decryption failed!"));
 EXTERN char e_libsodium_decryption_failed_premature[]
        INIT(= N_("E1201: Decryption failed: pre-mature end of file!"));
index e05dfa3a5ddc88936934adcf3a43beec3b925013..7c8f00de3aff697ef9d81877fa7ccab50c60f574 100644 (file)
@@ -1213,6 +1213,7 @@ retry:
                     * Read bytes from curbuf.  Used for converting text read
                     * from stdin.
                     */
+                   eof = FALSE;
                    if (read_buf_lnum > from)
                        size = 0;
                    else
@@ -1261,6 +1262,7 @@ retry:
                                    if (!curbuf->b_p_eol)
                                        --tlen;
                                    size = tlen;
+                                   eof = TRUE;
                                    break;
                                }
                            }
@@ -1276,7 +1278,7 @@ retry:
                    // Let the crypt layer work with a buffer size of 8192
                    if (filesize == 0)
                        // set size to 8K + Sodium Crypt Metadata
-                       size = WRITEBUFSIZE + 36
+                       size = WRITEBUFSIZE + crypt_get_max_header_len()
                     + crypto_secretstream_xchacha20poly1305_HEADERBYTES
                     + crypto_secretstream_xchacha20poly1305_ABYTES;
 
index 3b09a7dd4975a0f05ed97252daa0f919b04e0a70..f1c2a8a524452014f6313651f185ff929c3ab151 100644 (file)
@@ -497,7 +497,8 @@ ml_set_crypt_key(
        return;  // no memfile yet, nothing to do
     old_method = crypt_method_nr_from_name(old_cm);
 
-    if (old_method == CRYPT_M_SOD || crypt_get_method_nr(buf) == CRYPT_M_SOD)
+    // Swapfile encryption not supported by XChaCha20
+    if (crypt_get_method_nr(buf) == CRYPT_M_SOD && *buf->b_p_key != NUL)
     {
        // close the swapfile
        mf_close_file(buf, TRUE);
index 2e580392091e0ee4714b8080c175098073a9c568..18382a7f3ed9b7cc8754a712a90c1ce215a3cd2a 100644 (file)
@@ -5,6 +5,7 @@ int crypt_works_inplace(cryptstate_T *state);
 int crypt_get_method_nr(buf_T *buf);
 int crypt_whole_undofile(int method_nr);
 int crypt_get_header_len(int method_nr);
+int crypt_get_max_header_len(void);
 void crypt_set_cm_option(buf_T *buf, int method_nr);
 int crypt_self_test(void);
 cryptstate_T *crypt_create(int method_nr, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
@@ -23,8 +24,6 @@ void crypt_check_current_method(void);
 char_u *crypt_get_key(int store, int twice);
 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);
-void crypt_sodium_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
-void crypt_sodium_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
 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);
 /* vim: set ft=c : */
index 77456bbbb9bb4a4900cca50e8aa151c3f57fb094..a6e483e05c7142abdad6dc4d3be55187d10f56b1 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3032,
 /**/
     3031,
 /**/