Skip to content

Commit 226b28b

Browse files
chrisbrabrammool
authored andcommitted
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)
1 parent 22f17a2 commit 226b28b

7 files changed

Lines changed: 68 additions & 21 deletions

File tree

src/Make_mvc.mak

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@
4242
# Sound support: SOUND=yes (default is yes)
4343
#
4444
# Sodium support: SODIUM=[Path to Sodium directory]
45-
# You need to install the msvc package from https://download.libsodium.org/libsodium/releases/
45+
# Dynamic built with libsodium
46+
# You need to install the msvc package from
47+
# https://download.libsodium.org/libsodium/releases/
48+
# and package the libsodium.dll with Vim
49+
#
4650
#
4751
# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
4852
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
@@ -383,14 +387,14 @@ SODIUM = no
383387
! if "$(CPU)" == "AMD64"
384388
SOD_LIB = $(SODIUM)\x64\Release\v140\dynamic
385389
! elseif "$(CPU)" == "i386"
386-
SOD_LIB = $(SODIUM)\x86\Release\v140\dynamic
390+
SOD_LIB = $(SODIUM)\Win32\Release\v140\dynamic
387391
! else
388392
SODIUM = no
389393
! endif
390394
!endif
391395

392396
!if "$(SODIUM)" != "no"
393-
SOD_INC = -I $(SODIUM)\include
397+
SOD_INC = /I "$(SODIUM)\include"
394398
SOD_DEFS = -DFEAT_SODIUM
395399
SOD_LIB = $(SOD_LIB)\libsodium.lib
396400
!endif
@@ -514,7 +518,7 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
514518

515519
CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
516520
$(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
517-
$(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) \
521+
$(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) $(SOD_INC) \
518522
$(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
519523

520524
#>>>>> end of choices
@@ -726,7 +730,7 @@ CFLAGS = $(CFLAGS) $(CFLAGS_DEPR)
726730

727731
INCL = vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
728732
keymap.h macros.h option.h os_dos.h os_win32.h proto.h regexp.h \
729-
spell.h structs.h term.h beval.h $(NBDEBUG_INCL) $(SOD_INC)
733+
spell.h structs.h term.h beval.h $(NBDEBUG_INCL)
730734

731735
OBJ = \
732736
$(OUTDIR)\arabic.obj \

src/crypt.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
146146
FALSE,
147147
NULL,
148148
crypt_sodium_init,
149-
crypt_sodium_encode, crypt_sodium_decode,
149+
NULL, NULL,
150150
crypt_sodium_buffer_encode, crypt_sodium_buffer_decode,
151-
crypt_sodium_encode, crypt_sodium_decode,
151+
NULL, NULL,
152152
},
153153

154154
// 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)
250250
+ cryptmethods[method_nr].seed_len;
251251
}
252252

253+
254+
/*
255+
* Get maximum crypt method specific length of the file header in bytes.
256+
*/
257+
int
258+
crypt_get_max_header_len()
259+
{
260+
int i;
261+
int max = 0;
262+
int temp = 0;
263+
264+
for (i = 0; i < CRYPT_M_COUNT; ++i)
265+
{
266+
temp = crypt_get_header_len(i);
267+
if (temp > max)
268+
max = temp;
269+
}
270+
return max;
271+
}
272+
253273
/*
254274
* Set the crypt method for buffer "buf" to "method_nr" using the int value as
255275
* returned by crypt_method_nr_from_name().
@@ -403,8 +423,10 @@ crypt_create_for_writing(
403423
#ifdef FEAT_SODIUM
404424
if (sodium_init() >= 0)
405425
{
406-
randombytes_buf(salt, salt_len);
407-
randombytes_buf(seed, seed_len);
426+
if (salt_len > 0)
427+
randombytes_buf(salt, salt_len);
428+
if (seed_len > 0)
429+
randombytes_buf(seed, seed_len);
408430
}
409431
else
410432
#endif
@@ -581,6 +603,13 @@ crypt_check_method(int method)
581603
msg_scroll = TRUE;
582604
msg(_("Warning: Using a weak encryption method; see :help 'cm'"));
583605
}
606+
}
607+
608+
#ifdef FEAT_SODIUM
609+
static void
610+
crypt_check_swapfile_curbuf(void)
611+
{
612+
int method = crypt_get_method_nr(curbuf);
584613
if (method == CRYPT_M_SOD)
585614
{
586615
// encryption uses padding and MAC, that does not work very well with
@@ -590,11 +619,11 @@ crypt_check_method(int method)
590619
#ifdef FEAT_PERSISTENT_UNDO
591620
set_option_value((char_u *)"udf", 0, NULL, OPT_LOCAL);
592621
#endif
593-
594622
msg_scroll = TRUE;
595623
msg(_("Note: Encryption of swapfile not supported, disabling swap- and undofile"));
596624
}
597625
}
626+
#endif
598627

599628
void
600629
crypt_check_current_method(void)
@@ -647,17 +676,23 @@ crypt_get_key(
647676
set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
648677
crypt_free_key(p1);
649678
p1 = curbuf->b_p_key;
679+
#ifdef FEAT_SODIUM
680+
crypt_check_swapfile_curbuf();
681+
#endif
650682
}
651683
break;
652684
}
653685
p2 = p1;
654686
}
655687

656688
// since the user typed this, no need to wait for return
657-
if (msg_didout)
658-
msg_putchar('\n');
659-
need_wait_return = FALSE;
660-
msg_didout = FALSE;
689+
if (crypt_get_method_nr(curbuf) != CRYPT_M_SOD)
690+
{
691+
if (msg_didout)
692+
msg_putchar('\n');
693+
need_wait_return = FALSE;
694+
msg_didout = FALSE;
695+
}
661696

662697
crypt_free_key(p2);
663698
return p1;
@@ -726,6 +761,7 @@ crypt_sodium_init(
726761
* "from" and "to" can be equal to encrypt in place.
727762
* Call needs to ensure that there is enough space in to (for the header)
728763
*/
764+
#if 0 // Currently unused
729765
void
730766
crypt_sodium_encode(
731767
cryptstate_T *state UNUSED,
@@ -764,11 +800,13 @@ crypt_sodium_encode(
764800
sod_st->count++;
765801
# endif
766802
}
803+
#endif
767804

768-
/* TODO: Unused
805+
/*
769806
* Decrypt "from[len]" into "to[len]".
770807
* "from" and "to" can be equal to encrypt in place.
771808
*/
809+
#if 0 // Currently unused
772810
void
773811
crypt_sodium_decode(
774812
cryptstate_T *state UNUSED,
@@ -841,6 +879,7 @@ crypt_sodium_decode(
841879
vim_free(buf_out);
842880
# endif
843881
}
882+
#endif
844883

845884
/*
846885
* Encrypt "from[len]" into "to[len]".
@@ -864,7 +903,7 @@ crypt_sodium_buffer_encode(
864903
sodium_state_T *sod_st = state->method_state;
865904
int first = (sod_st->count == 0);
866905

867-
length = len + crypto_secretstream_xchacha20poly1305_ABYTES
906+
length = (int)len + crypto_secretstream_xchacha20poly1305_ABYTES
868907
+ (first ? crypto_secretstream_xchacha20poly1305_HEADERBYTES : 0);
869908
*buf_out = alloc_clear(length);
870909
if (*buf_out == NULL)

src/errors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,6 @@ EXTERN char e_libsodium_decryption_failed_header_incomplete[]
443443
EXTERN char e_libsodium_cannot_decrypt_buffer[]
444444
INIT(= N_("E1199: Cannot decrypt buffer, not enough space"));
445445
EXTERN char e_libsodium_decryption_failed[]
446-
INIT(= N_("E1200: Decryption failed: corrupted chunk!"));
446+
INIT(= N_("E1200: Decryption failed!"));
447447
EXTERN char e_libsodium_decryption_failed_premature[]
448448
INIT(= N_("E1201: Decryption failed: pre-mature end of file!"));

src/fileio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,7 @@ readfile(
12131213
* Read bytes from curbuf. Used for converting text read
12141214
* from stdin.
12151215
*/
1216+
eof = FALSE;
12161217
if (read_buf_lnum > from)
12171218
size = 0;
12181219
else
@@ -1261,6 +1262,7 @@ readfile(
12611262
if (!curbuf->b_p_eol)
12621263
--tlen;
12631264
size = tlen;
1265+
eof = TRUE;
12641266
break;
12651267
}
12661268
}
@@ -1276,7 +1278,7 @@ readfile(
12761278
// Let the crypt layer work with a buffer size of 8192
12771279
if (filesize == 0)
12781280
// set size to 8K + Sodium Crypt Metadata
1279-
size = WRITEBUFSIZE + 36
1281+
size = WRITEBUFSIZE + crypt_get_max_header_len()
12801282
+ crypto_secretstream_xchacha20poly1305_HEADERBYTES
12811283
+ crypto_secretstream_xchacha20poly1305_ABYTES;
12821284

src/memline.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,8 @@ ml_set_crypt_key(
497497
return; // no memfile yet, nothing to do
498498
old_method = crypt_method_nr_from_name(old_cm);
499499

500-
if (old_method == CRYPT_M_SOD || crypt_get_method_nr(buf) == CRYPT_M_SOD)
500+
// Swapfile encryption not supported by XChaCha20
501+
if (crypt_get_method_nr(buf) == CRYPT_M_SOD && *buf->b_p_key != NUL)
501502
{
502503
// close the swapfile
503504
mf_close_file(buf, TRUE);

src/proto/crypt.pro

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ int crypt_works_inplace(cryptstate_T *state);
55
int crypt_get_method_nr(buf_T *buf);
66
int crypt_whole_undofile(int method_nr);
77
int crypt_get_header_len(int method_nr);
8+
int crypt_get_max_header_len(void);
89
void crypt_set_cm_option(buf_T *buf, int method_nr);
910
int crypt_self_test(void);
1011
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);
2324
char_u *crypt_get_key(int store, int twice);
2425
void crypt_append_msg(buf_T *buf);
2526
int crypt_sodium_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
26-
void crypt_sodium_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
27-
void crypt_sodium_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
2827
long crypt_sodium_buffer_encode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
2928
long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
3029
/* vim: set ft=c : */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3032,
758760
/**/
759761
3031,
760762
/**/

0 commit comments

Comments
 (0)