0
0
mirror of https://github.com/vim/vim.git synced 2025-10-13 06:54:15 -04:00

patch 8.2.3032: build problems with MSVC, other crypt issues with libsodium

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)
This commit is contained in:
Christian Brabandt
2021-06-21 21:08:08 +02:00
committed by Bram Moolenaar
parent 22f17a29cd
commit 226b28b961
7 changed files with 68 additions and 21 deletions

View File

@@ -42,7 +42,11 @@
# Sound support: SOUND=yes (default is yes) # Sound support: SOUND=yes (default is yes)
# #
# Sodium support: SODIUM=[Path to Sodium directory] # 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) # DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe. # Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
@@ -383,14 +387,14 @@ SODIUM = no
! if "$(CPU)" == "AMD64" ! if "$(CPU)" == "AMD64"
SOD_LIB = $(SODIUM)\x64\Release\v140\dynamic SOD_LIB = $(SODIUM)\x64\Release\v140\dynamic
! elseif "$(CPU)" == "i386" ! elseif "$(CPU)" == "i386"
SOD_LIB = $(SODIUM)\x86\Release\v140\dynamic SOD_LIB = $(SODIUM)\Win32\Release\v140\dynamic
! else ! else
SODIUM = no SODIUM = no
! endif ! endif
!endif !endif
!if "$(SODIUM)" != "no" !if "$(SODIUM)" != "no"
SOD_INC = -I $(SODIUM)\include SOD_INC = /I "$(SODIUM)\include"
SOD_DEFS = -DFEAT_SODIUM SOD_DEFS = -DFEAT_SODIUM
SOD_LIB = $(SOD_LIB)\libsodium.lib SOD_LIB = $(SOD_LIB)\libsodium.lib
!endif !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 \ CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
$(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \ $(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) $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
#>>>>> end of choices #>>>>> 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 \ 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 \ 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 = \ OBJ = \
$(OUTDIR)\arabic.obj \ $(OUTDIR)\arabic.obj \

View File

@@ -146,9 +146,9 @@ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
FALSE, FALSE,
NULL, NULL,
crypt_sodium_init, crypt_sodium_init,
crypt_sodium_encode, crypt_sodium_decode, NULL, NULL,
crypt_sodium_buffer_encode, crypt_sodium_buffer_decode, 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, // 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; + 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 * Set the crypt method for buffer "buf" to "method_nr" using the int value as
* returned by crypt_method_nr_from_name(). * returned by crypt_method_nr_from_name().
@@ -403,7 +423,9 @@ crypt_create_for_writing(
#ifdef FEAT_SODIUM #ifdef FEAT_SODIUM
if (sodium_init() >= 0) if (sodium_init() >= 0)
{ {
if (salt_len > 0)
randombytes_buf(salt, salt_len); randombytes_buf(salt, salt_len);
if (seed_len > 0)
randombytes_buf(seed, seed_len); randombytes_buf(seed, seed_len);
} }
else else
@@ -581,6 +603,13 @@ crypt_check_method(int method)
msg_scroll = TRUE; msg_scroll = TRUE;
msg(_("Warning: Using a weak encryption method; see :help 'cm'")); 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) if (method == CRYPT_M_SOD)
{ {
// encryption uses padding and MAC, that does not work very well with // 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 #ifdef FEAT_PERSISTENT_UNDO
set_option_value((char_u *)"udf", 0, NULL, OPT_LOCAL); set_option_value((char_u *)"udf", 0, NULL, OPT_LOCAL);
#endif #endif
msg_scroll = TRUE; msg_scroll = TRUE;
msg(_("Note: Encryption of swapfile not supported, disabling swap- and undofile")); msg(_("Note: Encryption of swapfile not supported, disabling swap- and undofile"));
} }
} }
#endif
void void
crypt_check_current_method(void) crypt_check_current_method(void)
@@ -647,6 +676,9 @@ crypt_get_key(
set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL); set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
crypt_free_key(p1); crypt_free_key(p1);
p1 = curbuf->b_p_key; p1 = curbuf->b_p_key;
#ifdef FEAT_SODIUM
crypt_check_swapfile_curbuf();
#endif
} }
break; break;
} }
@@ -654,10 +686,13 @@ crypt_get_key(
} }
// since the user typed this, no need to wait for return // since the user typed this, no need to wait for return
if (crypt_get_method_nr(curbuf) != CRYPT_M_SOD)
{
if (msg_didout) if (msg_didout)
msg_putchar('\n'); msg_putchar('\n');
need_wait_return = FALSE; need_wait_return = FALSE;
msg_didout = FALSE; msg_didout = FALSE;
}
crypt_free_key(p2); crypt_free_key(p2);
return p1; return p1;
@@ -726,6 +761,7 @@ crypt_sodium_init(
* "from" and "to" can be equal to encrypt in place. * "from" and "to" can be equal to encrypt in place.
* Call needs to ensure that there is enough space in to (for the header) * Call needs to ensure that there is enough space in to (for the header)
*/ */
#if 0 // Currently unused
void void
crypt_sodium_encode( crypt_sodium_encode(
cryptstate_T *state UNUSED, cryptstate_T *state UNUSED,
@@ -764,11 +800,13 @@ crypt_sodium_encode(
sod_st->count++; sod_st->count++;
# endif # endif
} }
#endif
/* TODO: Unused /*
* Decrypt "from[len]" into "to[len]". * Decrypt "from[len]" into "to[len]".
* "from" and "to" can be equal to encrypt in place. * "from" and "to" can be equal to encrypt in place.
*/ */
#if 0 // Currently unused
void void
crypt_sodium_decode( crypt_sodium_decode(
cryptstate_T *state UNUSED, cryptstate_T *state UNUSED,
@@ -841,6 +879,7 @@ fail:
vim_free(buf_out); vim_free(buf_out);
# endif # endif
} }
#endif
/* /*
* Encrypt "from[len]" into "to[len]". * Encrypt "from[len]" into "to[len]".
@@ -864,7 +903,7 @@ crypt_sodium_buffer_encode(
sodium_state_T *sod_st = state->method_state; sodium_state_T *sod_st = state->method_state;
int first = (sod_st->count == 0); 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); + (first ? crypto_secretstream_xchacha20poly1305_HEADERBYTES : 0);
*buf_out = alloc_clear(length); *buf_out = alloc_clear(length);
if (*buf_out == NULL) if (*buf_out == NULL)

View File

@@ -443,6 +443,6 @@ EXTERN char e_libsodium_decryption_failed_header_incomplete[]
EXTERN char e_libsodium_cannot_decrypt_buffer[] EXTERN char e_libsodium_cannot_decrypt_buffer[]
INIT(= N_("E1199: Cannot decrypt buffer, not enough space")); INIT(= N_("E1199: Cannot decrypt buffer, not enough space"));
EXTERN char e_libsodium_decryption_failed[] 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[] EXTERN char e_libsodium_decryption_failed_premature[]
INIT(= N_("E1201: Decryption failed: pre-mature end of file!")); INIT(= N_("E1201: Decryption failed: pre-mature end of file!"));

View File

@@ -1213,6 +1213,7 @@ retry:
* Read bytes from curbuf. Used for converting text read * Read bytes from curbuf. Used for converting text read
* from stdin. * from stdin.
*/ */
eof = FALSE;
if (read_buf_lnum > from) if (read_buf_lnum > from)
size = 0; size = 0;
else else
@@ -1261,6 +1262,7 @@ retry:
if (!curbuf->b_p_eol) if (!curbuf->b_p_eol)
--tlen; --tlen;
size = tlen; size = tlen;
eof = TRUE;
break; break;
} }
} }
@@ -1276,7 +1278,7 @@ retry:
// Let the crypt layer work with a buffer size of 8192 // Let the crypt layer work with a buffer size of 8192
if (filesize == 0) if (filesize == 0)
// set size to 8K + Sodium Crypt Metadata // set size to 8K + Sodium Crypt Metadata
size = WRITEBUFSIZE + 36 size = WRITEBUFSIZE + crypt_get_max_header_len()
+ crypto_secretstream_xchacha20poly1305_HEADERBYTES + crypto_secretstream_xchacha20poly1305_HEADERBYTES
+ crypto_secretstream_xchacha20poly1305_ABYTES; + crypto_secretstream_xchacha20poly1305_ABYTES;

View File

@@ -497,7 +497,8 @@ ml_set_crypt_key(
return; // no memfile yet, nothing to do return; // no memfile yet, nothing to do
old_method = crypt_method_nr_from_name(old_cm); 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 // close the swapfile
mf_close_file(buf, TRUE); mf_close_file(buf, TRUE);

View File

@@ -5,6 +5,7 @@ int crypt_works_inplace(cryptstate_T *state);
int crypt_get_method_nr(buf_T *buf); int crypt_get_method_nr(buf_T *buf);
int crypt_whole_undofile(int method_nr); int crypt_whole_undofile(int method_nr);
int crypt_get_header_len(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); void crypt_set_cm_option(buf_T *buf, int method_nr);
int crypt_self_test(void); 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); 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); char_u *crypt_get_key(int store, int twice);
void crypt_append_msg(buf_T *buf); 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); 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_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); long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3032,
/**/ /**/
3031, 3031,
/**/ /**/