summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Make_bc5.mak2
-rw-r--r--src/Make_ivc.mak2
-rw-r--r--src/Make_manx.mak4
-rw-r--r--src/Make_mvc.mak8
-rw-r--r--src/Make_sas.mak6
-rw-r--r--src/Makefile20
-rw-r--r--src/blowfish.c581
-rw-r--r--src/ex_docmd.c3
-rw-r--r--src/feature.h2
-rw-r--r--src/fileio.c107
-rw-r--r--src/globals.h4
-rw-r--r--src/main.c1
-rw-r--r--src/misc2.c52
-rw-r--r--src/option.c22
-rw-r--r--src/option.h1
-rw-r--r--src/proto.h6
-rw-r--r--src/proto/blowfish.pro7
-rw-r--r--src/proto/misc2.pro3
-rw-r--r--src/proto/sha256.pro5
-rw-r--r--src/sha256.c429
-rw-r--r--src/structs.h1
-rw-r--r--src/testdir/Make_dos.mak2
-rw-r--r--src/testdir/Make_ming.mak2
-rw-r--r--src/testdir/Makefile4
-rw-r--r--src/testdir/test71.in37
-rw-r--r--src/testdir/test71.ok6
26 files changed, 1272 insertions, 45 deletions
diff --git a/src/Make_bc5.mak b/src/Make_bc5.mak
index a1d92bdd3..1373b4eb5 100644
--- a/src/Make_bc5.mak
+++ b/src/Make_bc5.mak
@@ -533,6 +533,7 @@ vimwinmain = \
!endif
vimobj = \
+ $(OBJDIR)\blowfish.obj \
$(OBJDIR)\buffer.obj \
$(OBJDIR)\charset.obj \
$(OBJDIR)\diff.obj \
@@ -567,6 +568,7 @@ vimobj = \
$(OBJDIR)\regexp.obj \
$(OBJDIR)\screen.obj \
$(OBJDIR)\search.obj \
+ $(OBJDIR)\sha256.obj \
$(OBJDIR)\spell.obj \
$(OBJDIR)\syntax.obj \
$(OBJDIR)\tag.obj \
diff --git a/src/Make_ivc.mak b/src/Make_ivc.mak
index 2d118d5a6..1b06affae 100644
--- a/src/Make_ivc.mak
+++ b/src/Make_ivc.mak
@@ -210,6 +210,7 @@ ALL : .\$(VIM).exe vimrun.exe install.exe uninstal.exe xxd/xxd.exe GvimExt/gvime
LINK32_OBJS= \
$(EXTRAS) \
+ "$(INTDIR)/blowfish.obj" \
"$(INTDIR)/buffer.obj" \
"$(INTDIR)/charset.obj" \
"$(INTDIR)/diff.obj" \
@@ -246,6 +247,7 @@ LINK32_OBJS= \
"$(INTDIR)/regexp.obj" \
"$(INTDIR)/screen.obj" \
"$(INTDIR)/search.obj" \
+ "$(INTDIR)/sha256.obj" \
"$(INTDIR)/spell.obj" \
"$(INTDIR)/syntax.obj" \
"$(INTDIR)/tag.obj" \
diff --git a/src/Make_manx.mak b/src/Make_manx.mak
index b8e7852de..c4b3bcb1d 100644
--- a/src/Make_manx.mak
+++ b/src/Make_manx.mak
@@ -124,7 +124,8 @@ OBJ = obj/buffer.o \
obj/window.o \
$(TERMLIB)
-PRO = proto/buffer.pro \
+PRO = proto/blowfish.pro \
+ proto/buffer.pro \
proto/charset.pro \
proto/diff.pro \
proto/digraph.pro \
@@ -159,6 +160,7 @@ PRO = proto/buffer.pro \
proto/regexp.pro \
proto/screen.pro \
proto/search.pro \
+ proto/sha256.pro \
proto/spell.pro \
proto/syntax.pro \
proto/tag.pro \
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 38ced6e5c..16afb4061 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -453,6 +453,8 @@ INCL = vim.h os_win32.h ascii.h feature.h globals.h keymap.h macros.h \
$(NBDEBUG_INCL)
OBJ = \
+ $(OUTDIR)\blowfish.obj \
+ $(OUTDIR)\sha256.obj \
$(OUTDIR)\buffer.obj \
$(OUTDIR)\charset.obj \
$(OUTDIR)\diff.obj \
@@ -912,6 +914,10 @@ testclean:
$(OUTDIR)/buffer.obj: $(OUTDIR) buffer.c $(INCL)
+$(OUTDIR)/blowfish.obj: $(OUTDIR) blowfish.c $(INCL)
+
+$(OUTDIR)/sha256.obj: $(OUTDIR) sha256.c $(INCL)
+
$(OUTDIR)/charset.obj: $(OUTDIR) charset.c $(INCL)
$(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL)
@@ -1080,6 +1086,7 @@ auto:
# End Custom Build
proto.h: \
+ proto/blowfish.pro \
proto/buffer.pro \
proto/charset.pro \
proto/diff.pro \
@@ -1115,6 +1122,7 @@ proto.h: \
proto/regexp.pro \
proto/screen.pro \
proto/search.pro \
+ proto/sha256.pro \
proto/spell.pro \
proto/syntax.pro \
proto/tag.pro \
diff --git a/src/Make_sas.mak b/src/Make_sas.mak
index 98ec528be..7cbb888bd 100644
--- a/src/Make_sas.mak
+++ b/src/Make_sas.mak
@@ -179,6 +179,7 @@ OBJ = \
$(TERMLIB)
PRO = \
+ proto/blowfish.pro \
proto/buffer.pro \
proto/charset.pro \
proto/diff.pro \
@@ -214,6 +215,7 @@ PRO = \
proto/regexp.pro \
proto/screen.pro \
proto/search.pro \
+ proto/sha256.pro \
proto/spell.pro \
proto/syntax.pro \
proto/tag.pro \
@@ -278,6 +280,8 @@ $(PRO): $(GST) vim.h
$(CC) $(CFLAGS) GPFILE=proto/$*.pro $(PROPT) $*.c
# dependancies
+blowfish.o: blowfish.c
+proto/blowfish.pro: blowfish.c
buffer.o: buffer.c
proto/buffer.pro: buffer.c
charset.o: charset.c
@@ -348,6 +352,8 @@ screen.o: screen.c
proto/screen.pro: screen.c
search.o: search.c
proto/search.pro: search.c
+sha256.o: sha256.c
+proto/sha256.pro: sha256.c
spell.o: spell.c
proto/spell.pro: spell.c
syntax.o: syntax.c
diff --git a/src/Makefile b/src/Makefile
index f6b6e6f1f..74d6e88c4 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -468,7 +468,7 @@ CClink = $(CC)
#CONF_OPT_FEAT = --with-features=small
#CONF_OPT_FEAT = --with-features=normal
#CONF_OPT_FEAT = --with-features=big
-#CONF_OPT_FEAT = --with-features=huge
+CONF_OPT_FEAT = --with-features=huge
# COMPILED BY - For including a specific e-mail address for ":version".
#CONF_OPT_COMPBY = "--with-compiledby=John Doe <JohnDoe@yahoo.com>"
@@ -536,9 +536,9 @@ CClink = $(CC)
#CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
# Use this with GCC to check for mistakes, unused arguments, etc.
-#CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -D_FORTIFY_SOURCE=1
-#PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
-#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
+CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -D_FORTIFY_SOURCE=1
+PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
+MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
# EFENCE - Electric-Fence malloc debugging: catches memory accesses beyond
# allocated memory (and makes every malloc()/free() very slow).
@@ -1377,6 +1377,7 @@ DEST_MAN_RU_U = $(DEST_MAN_TOP)/ru.UTF-8$(MAN1DIR)
TAGS_INCL = *.h
BASIC_SRC = \
+ blowfish.c \
buffer.c \
charset.c \
diff.c \
@@ -1415,6 +1416,7 @@ BASIC_SRC = \
regexp.c \
screen.c \
search.c \
+ sha256.c \
spell.c \
syntax.c \
tag.c \
@@ -1449,6 +1451,7 @@ LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \
OBJ = \
objects/buffer.o \
+ objects/blowfish.o \
objects/charset.o \
objects/diff.o \
objects/digraph.o \
@@ -1487,6 +1490,7 @@ OBJ = \
objects/regexp.o \
objects/screen.o \
objects/search.o \
+ objects/sha256.o \
objects/spell.o \
objects/syntax.o \
$(SNIFF_OBJ) \
@@ -1507,6 +1511,7 @@ OBJ = \
$(WSDEBUG_OBJ)
PRO_AUTO = \
+ blowfish.pro \
buffer.pro \
charset.pro \
diff.pro \
@@ -1547,6 +1552,7 @@ PRO_AUTO = \
regexp.pro \
screen.pro \
search.pro \
+ sha256.pro \
spell.pro \
syntax.pro \
tag.pro \
@@ -2337,6 +2343,9 @@ auto/pathdef.c: Makefile auto/config.mk
objects:
mkdir objects
+objects/blowfish.o: blowfish.c
+ $(CCC) -o $@ blowfish.c
+
objects/buffer.o: buffer.c
$(CCC) -o $@ buffer.c
@@ -2547,6 +2556,9 @@ objects/screen.o: screen.c
objects/search.o: search.c
$(CCC) -o $@ search.c
+objects/sha256.o: sha256.c
+ $(CCC) -o $@ sha256.c
+
objects/spell.o: spell.c
$(CCC) -o $@ spell.c
diff --git a/src/blowfish.c b/src/blowfish.c
new file mode 100644
index 000000000..f5b8e9070
--- /dev/null
+++ b/src/blowfish.c
@@ -0,0 +1,581 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * Blowfish encryption for vim; in Blowfish output feedback mode.
+ * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_CRYPT)
+
+#define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0]))
+
+#define BF_BLOCK 8
+#define BF_OFB_LEN (8*(BF_BLOCK))
+
+typedef union {
+ long_u ul[2];
+ char_u uc[8];
+} block8;
+
+#ifdef __BORLANDC__
+# define LITTLE_ENDIAN
+#else
+# if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+# if (('1234' >> 24) == '1')
+# define LITTLE_ENDIAN 1
+# else
+# if (('4321' >> 24) == '1')
+# define BIG_ENDIAN 1
+# endif
+# endif
+# endif
+#endif
+
+static void bf_e_block __ARGS((long_u *p_xl, long_u *p_xr));
+static void bf_e_cblock __ARGS((char_u *block));
+static int bf_check_tables __ARGS((long_u ipa[18], long_u sbi[4][256], long_u val));
+static int bf_self_test __ARGS((void));
+
+// Blowfish code
+static long_u pax[18];
+static long_u ipa[18] = {
+ 0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
+ 0x03707344u, 0xa4093822u, 0x299f31d0u,
+ 0x082efa98u, 0xec4e6c89u, 0x452821e6u,
+ 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu,
+ 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u,
+ 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
+};
+
+static long_u sbx[4][256];
+static long_u sbi[4][256] = {
+ {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
+ 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
+ 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
+ 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu,
+ 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu,
+ 0x7b54a41du, 0xc25a59b5u, 0x9c30d539u, 0x2af26013u,
+ 0xc5d1b023u, 0x286085f0u, 0xca417918u, 0xb8db38efu,
+ 0x8e79dcb0u, 0x603a180eu, 0x6c9e0e8bu, 0xb01e8a3eu,
+ 0xd71577c1u, 0xbd314b27u, 0x78af2fdau, 0x55605c60u,
+ 0xe65525f3u, 0xaa55ab94u, 0x57489862u, 0x63e81440u,
+ 0x55ca396au, 0x2aab10b6u, 0xb4cc5c34u, 0x1141e8ceu,
+ 0xa15486afu, 0x7c72e993u, 0xb3ee1411u, 0x636fbc2au,
+ 0x2ba9c55du, 0x741831f6u, 0xce5c3e16u, 0x9b87931eu,
+ 0xafd6ba33u, 0x6c24cf5cu, 0x7a325381u, 0x28958677u,
+ 0x3b8f4898u, 0x6b4bb9afu, 0xc4bfe81bu, 0x66282193u,
+ 0x61d809ccu, 0xfb21a991u, 0x487cac60u, 0x5dec8032u,
+ 0xef845d5du, 0xe98575b1u, 0xdc262302u, 0xeb651b88u,
+ 0x23893e81u, 0xd396acc5u, 0x0f6d6ff3u, 0x83f44239u,
+ 0x2e0b4482u, 0xa4842004u, 0x69c8f04au, 0x9e1f9b5eu,
+ 0x21c66842u, 0xf6e96c9au, 0x670c9c61u, 0xabd388f0u,
+ 0x6a51a0d2u, 0xd8542f68u, 0x960fa728u, 0xab5133a3u,
+ 0x6eef0b6cu, 0x137a3be4u, 0xba3bf050u, 0x7efb2a98u,
+ 0xa1f1651du, 0x39af0176u, 0x66ca593eu, 0x82430e88u,
+ 0x8cee8619u, 0x456f9fb4u, 0x7d84a5c3u, 0x3b8b5ebeu,
+ 0xe06f75d8u, 0x85c12073u, 0x401a449fu, 0x56c16aa6u,
+ 0x4ed3aa62u, 0x363f7706u, 0x1bfedf72u, 0x429b023du,
+ 0x37d0d724u, 0xd00a1248u, 0xdb0fead3u, 0x49f1c09bu,
+ 0x075372c9u, 0x80991b7bu, 0x25d479d8u, 0xf6e8def7u,
+ 0xe3fe501au, 0xb6794c3bu, 0x976ce0bdu, 0x04c006bau,
+ 0xc1a94fb6u, 0x409f60c4u, 0x5e5c9ec2u, 0x196a2463u,
+ 0x68fb6fafu, 0x3e6c53b5u, 0x1339b2ebu, 0x3b52ec6fu,
+ 0x6dfc511fu, 0x9b30952cu, 0xcc814544u, 0xaf5ebd09u,
+ 0xbee3d004u, 0xde334afdu, 0x660f2807u, 0x192e4bb3u,
+ 0xc0cba857u, 0x45c8740fu, 0xd20b5f39u, 0xb9d3fbdbu,
+ 0x5579c0bdu, 0x1a60320au, 0xd6a100c6u, 0x402c7279u,
+ 0x679f25feu, 0xfb1fa3ccu, 0x8ea5e9f8u, 0xdb3222f8u,
+ 0x3c7516dfu, 0xfd616b15u, 0x2f501ec8u, 0xad0552abu,
+ 0x323db5fau, 0xfd238760u, 0x53317b48u, 0x3e00df82u,
+ 0x9e5c57bbu, 0xca6f8ca0u, 0x1a87562eu, 0xdf1769dbu,
+ 0xd542a8f6u, 0x287effc3u, 0xac6732c6u, 0x8c4f5573u,
+ 0x695b27b0u, 0xbbca58c8u, 0xe1ffa35du, 0xb8f011a0u,
+ 0x10fa3d98u, 0xfd2183b8u, 0x4afcb56cu, 0x2dd1d35bu,
+ 0x9a53e479u, 0xb6f84565u, 0xd28e49bcu, 0x4bfb9790u,
+ 0xe1ddf2dau, 0xa4cb7e33u, 0x62fb1341u, 0xcee4c6e8u,
+ 0xef20cadau, 0x36774c01u, 0xd07e9efeu, 0x2bf11fb4u,
+ 0x95dbda4du, 0xae909198u, 0xeaad8e71u, 0x6b93d5a0u,
+ 0xd08ed1d0u, 0xafc725e0u, 0x8e3c5b2fu, 0x8e7594b7u,
+ 0x8ff6e2fbu, 0xf2122b64u, 0x8888b812u, 0x900df01cu,
+ 0x4fad5ea0u, 0x688fc31cu, 0xd1cff191u, 0xb3a8c1adu,
+ 0x2f2f2218u, 0xbe0e1777u, 0xea752dfeu, 0x8b021fa1u,
+ 0xe5a0cc0fu, 0xb56f74e8u, 0x18acf3d6u, 0xce89e299u,
+ 0xb4a84fe0u, 0xfd13e0b7u, 0x7cc43b81u, 0xd2ada8d9u,
+ 0x165fa266u, 0x80957705u, 0x93cc7314u, 0x211a1477u,
+ 0xe6ad2065u, 0x77b5fa86u, 0xc75442f5u, 0xfb9d35cfu,
+ 0xebcdaf0cu, 0x7b3e89a0u, 0xd6411bd3u, 0xae1e7e49u,
+ 0x00250e2du, 0x2071b35eu, 0x226800bbu, 0x57b8e0afu,
+ 0x2464369bu, 0xf009b91eu, 0x5563911du, 0x59dfa6aau,
+ 0x78c14389u, 0xd95a537fu, 0x207d5ba2u, 0x02e5b9c5u,
+ 0x83260376u, 0x6295cfa9u, 0x11c81968u, 0x4e734a41u,
+ 0xb3472dcau, 0x7b14a94au, 0x1b510052u, 0x9a532915u,
+ 0xd60f573fu, 0xbc9bc6e4u, 0x2b60a476u, 0x81e67400u,
+ 0x08ba6fb5u, 0x571be91fu, 0xf296ec6bu, 0x2a0dd915u,
+ 0xb6636521u, 0xe7b9f9b6u, 0xff34052eu, 0xc5855664u,
+ 0x53b02d5du, 0xa99f8fa1u, 0x08ba4799u, 0x6e85076au},
+ {0x4b7a70e9u, 0xb5b32944u, 0xdb75092eu, 0xc4192623u,
+ 0xad6ea6b0u, 0x49a7df7du, 0x9cee60b8u, 0x8fedb266u,
+ 0xecaa8c71u, 0x699a17ffu, 0x5664526cu, 0xc2b19ee1u,
+ 0x193602a5u, 0x75094c29u, 0xa0591340u, 0xe4183a3eu,
+ 0x3f54989au, 0x5b429d65u, 0x6b8fe4d6u, 0x99f73fd6u,
+ 0xa1d29c07u, 0xefe830f5u, 0x4d2d38e6u, 0xf0255dc1u,
+ 0x4cdd2086u, 0x8470eb26u, 0x6382e9c6u, 0x021ecc5eu,
+ 0x09686b3fu, 0x3ebaefc9u, 0x3c971814u, 0x6b6a70a1u,
+ 0x687f3584u, 0x52a0e286u, 0xb79c5305u, 0xaa500737u,
+ 0x3e07841cu, 0x7fdeae5cu, 0x8e7d44ecu, 0x5716f2b8u,
+ 0xb03ada37u, 0xf0500c0du, 0xf01c1f04u, 0x0200b3ffu,
+ 0xae0cf51au, 0x3cb574b2u, 0x25837a58u, 0xdc0921bdu,
+ 0xd19113f9u, 0x7ca92ff6u, 0x94324773u, 0x22f54701u,
+ 0x3ae5e581u, 0x37c2dadcu, 0xc8b57634u, 0x9af3dda7u,
+ 0xa9446146u, 0x0fd0030eu, 0xecc8c73eu, 0xa4751e41u,
+ 0xe238cd99u, 0x3bea0e2fu, 0x3280bba1u, 0x183eb331u,
+ 0x4e548b38u, 0x4f6db908u, 0x6f420d03u, 0xf60a04bfu,
+ 0x2cb81290u, 0x24977c79u, 0x5679b072u, 0xbcaf89afu,
+ 0xde9a771fu, 0xd9930810u, 0xb38bae12u, 0xdccf3f2eu,
+ 0x5512721fu, 0x2e6b7124u, 0x501adde6u, 0x9f84cd87u,
+ 0x7a584718u, 0x7408da17u, 0xbc9f9abcu, 0xe94b7d8cu,
+ 0xec7aec3au, 0xdb851dfau, 0x63094366u, 0xc464c3d2u,
+ 0xef1c1847u, 0x3215d908u, 0xdd433b37u, 0x24c2ba16u,
+ 0x12a14d43u, 0x2a65c451u, 0x50940002u, 0x133ae4ddu,
+ 0x71dff89eu, 0x10314e55u, 0x81ac77d6u, 0x5f11199bu,
+ 0x043556f1u, 0xd7a3c76bu, 0x3c11183bu, 0x5924a509u,
+ 0xf28fe6edu, 0x97f1fbfau, 0x9ebabf2cu, 0x1e153c6eu,
+ 0x86e34570u, 0xeae96fb1u, 0x860e5e0au, 0x5a3e2ab3u,
+ 0x771fe71cu, 0x4e3d06fau, 0x2965dcb9u, 0x99e71d0fu,
+ 0x803e89d6u, 0x5266c825u, 0x2e4cc978u, 0x9c10b36au,
+ 0xc6150ebau, 0x94e2ea78u, 0xa5fc3c53u, 0x1e0a2df4u,
+ 0xf2f74ea7u, 0x361d2b3du, 0x1939260fu, 0x19c27960u,
+ 0x5223a708u, 0xf71312b6u, 0xebadfe6eu, 0xeac31f66u,
+ 0xe3bc4595u, 0xa67bc883u, 0xb17f37d1u, 0x018cff28u,
+ 0xc332ddefu, 0xbe6c5aa5u, 0x65582185u, 0x68ab9802u,
+ 0xeecea50fu, 0xdb2f953bu, 0x2aef7dadu, 0x5b6e2f84u,
+ 0x1521b628u, 0x29076170u, 0xecdd4775u, 0x619f1510u,
+ 0x13cca830u, 0xeb61bd96u, 0x0334fe1eu, 0xaa0363cfu,
+ 0xb5735c90u, 0x4c70a239u, 0xd59e9e0bu, 0xcbaade14u,
+ 0xeecc86bcu, 0x60622ca7u, 0x9cab5cabu, 0xb2f3846eu,
+ 0x648b1eafu, 0x19bdf0cau, 0xa02369b9u, 0x655abb50u,
+ 0x40685a32u, 0x3c2ab4b3u, 0x319ee9d5u, 0xc021b8f7u,
+ 0x9b540b19u, 0x875fa099u, 0x95f7997eu, 0x623d7da8u,
+ 0xf837889au, 0x97e32d77u, 0x11ed935fu, 0x16681281u,
+ 0x0e358829u, 0xc7e61fd6u, 0x96dedfa1u, 0x7858ba99u,
+ 0x57f584a5u, 0x1b227263u, 0x9b83c3ffu, 0x1ac24696u,
+ 0xcdb30aebu, 0x532e3054u, 0x8fd948e4u, 0x6dbc3128u,
+ 0x58ebf2efu, 0x34c6ffeau, 0xfe28ed61u, 0xee7c3c73u,
+ 0x5d4a14d9u, 0xe864b7e3u, 0x42105d14u, 0x203e13e0u,
+ 0x45eee2b6u, 0xa3aaabeau, 0xdb6c4f15u, 0xfacb4fd0u,
+ 0xc742f442u, 0xef6abbb5u, 0x654f3b1du, 0x41cd2105u,
+ 0xd81e799eu, 0x86854dc7u, 0xe44b476au, 0x3d816250u,
+ 0xcf62a1f2u, 0x5b8d2646u, 0xfc8883a0u, 0xc1c7b6a3u,
+ 0x7f1524c3u, 0x69cb7492u, 0x47848a0bu, 0x5692b285u,
+ 0x095bbf00u, 0xad19489du, 0x1462b174u, 0x23820e00u,
+ 0x58428d2au, 0x0c55f5eau, 0x1dadf43eu, 0x233f7061u,
+ 0x3372f092u, 0x8d937e41u, 0xd65fecf1u, 0x6c223bdbu,
+ 0x7cde3759u, 0xcbee7460u, 0x4085f2a7u, 0xce77326eu,
+ 0xa6078084u, 0x19f8509eu, 0xe8efd855u, 0x61d99735u,
+ 0xa969a7aau, 0xc50c06c2u, 0x5a04abfcu, 0x800bcadcu,
+ 0x9e447a2eu, 0xc3453484u, 0xfdd56705u, 0x0e1e9ec9u,
+ 0xdb73dbd3u, 0x105588cdu, 0x675fda79u, 0xe3674340u,
+ 0xc5c43465u, 0x713e38d8u, 0x3d28f89eu, 0xf16dff20u,
+ 0x153e21e7u, 0x8fb03d4au, 0xe6e39f2bu, 0xdb83adf7u},
+ {0xe93d5a68u, 0x948140f7u, 0xf64c261cu, 0x94692934u,
+ 0x411520f7u, 0x7602d4f7u, 0xbcf46b2eu, 0xd4a20068u,
+ 0xd4082471u, 0x3320f46au, 0x43b7d4b7u, 0x500061afu,
+ 0x1e39f62eu, 0x97244546u, 0x14214f74u, 0xbf8b8840u,
+ 0x4d95fc1du, 0x96b591afu, 0x70f4ddd3u, 0x66a02f45u,
+ 0xbfbc09ecu, 0x03bd9785u, 0x7fac6dd0u, 0x31cb8504u,
+ 0x96eb27b3u, 0x55fd3941u, 0xda2547e6u, 0xabca0a9au,
+ 0x28507825u, 0x530429f4u, 0x0a2c86dau, 0xe9b66dfbu,
+ 0x68dc1462u, 0xd7486900u, 0x680ec0a4u, 0x27a18deeu,
+ 0x4f3ffea2u, 0xe887ad8cu, 0xb58ce006u, 0x7af4d6b6u,
+ 0xaace1e7cu, 0xd3375fecu, 0xce78a399u, 0x406b2a42u,
+ 0x20fe9e35u, 0xd9f385b9u, 0xee39d7abu, 0x3b124e8bu,
+ 0x1dc9faf7u, 0x4b6d1856u, 0x26a36631u, 0xeae397b2u,
+ 0x3a6efa74u, 0xdd5b4332u, 0x6841e7f7u, 0xca7820fbu,
+ 0xfb0af54eu, 0xd8feb397u, 0x454056acu, 0xba489527u,
+ 0x55533a3au, 0x20838d87u, 0xfe6ba9b7u, 0xd096954bu,
+ 0x55a867bcu, 0xa1159a58u, 0xcca92963u, 0x99e1db33u,
+ 0xa62a4a56u, 0x3f3125f9u, 0x5ef47e1cu, 0x9029317cu,
+ 0xfdf8e802u, 0x04272f70u, 0x80bb155cu, 0x05282ce3u,
+ 0x95c11548u, 0xe4c66d22u, 0x48c1133fu, 0xc70f86dcu,
+ 0x07f9c9eeu, 0x41041f0fu, 0x404779a4u, 0x5d886e17u,
+ 0x325f51ebu, 0xd59bc0d1u, 0xf2bcc18fu, 0x41113564u,
+ 0x257b7834u, 0x602a9c60u, 0xdff8e8a3u, 0x1f636c1bu,
+ 0x0e12b4c2u, 0x02e1329eu, 0xaf664fd1u, 0xcad18115u,
+ 0x6b2395e0u, 0x333e92e1u, 0x3b240b62u, 0xeebeb922u,
+ 0x85b2a20eu, 0xe6ba0d99u, 0xde720c8cu, 0x2da2f728u,
+ 0xd0127845u, 0x95b794fdu, 0x647d0862u, 0xe7ccf5f0u,
+ 0x5449a36fu, 0x877d48fau, 0xc39dfd27u, 0xf33e8d1eu,
+ 0x0a476341u, 0x992eff74u, 0x3a6f6eabu, 0xf4f8fd37u,
+ 0xa812dc60u, 0xa1ebddf8u, 0x991be14cu, 0xdb6e6b0du,
+ 0xc67b5510u, 0x6d672c37u, 0x2765d43bu, 0xdcd0e804u,
+ 0xf1290dc7u, 0xcc00ffa3u, 0xb5390f92u, 0x690fed0bu,
+ 0x667b9ffbu, 0xcedb7d9cu, 0xa091cf0bu, 0xd9155ea3u,
+ 0xbb132f88u, 0x515bad24u, 0x7b9479bfu, 0x763bd6ebu,
+ 0x37392eb3u, 0xcc115979u, 0x8026e297u, 0xf42e312du,
+ 0x6842ada7u, 0xc66a2b3bu, 0x12754cccu, 0x782ef11cu,
+ 0x6a124237u, 0xb79251e7u, 0x06a1bbe6u, 0x4bfb6350u,
+ 0x1a6b1018u, 0x11caedfau, 0x3d25bdd8u, 0xe2e1c3c9u,
+ 0x44421659u, 0x0a121386u, 0xd90cec6eu, 0xd5abea2au,
+ 0x64af674eu, 0xda86a85fu, 0xbebfe988u, 0x64e4c3feu,
+ 0x9dbc8057u, 0xf0f7c086u, 0x60787bf8u, 0x6003604du,
+ 0xd1fd8346u, 0xf6381fb0u, 0x7745ae04u, 0xd736fcccu,
+ 0x83426b33u, 0xf01eab71u, 0xb0804187u, 0x3c005e5fu,
+ 0x77a057beu, 0xbde8ae24u, 0x55464299u, 0xbf582e61u,
+ 0x4e58f48fu, 0xf2ddfda2u, 0xf474ef38u, 0x8789bdc2u,
+ 0x5366f9c3u, 0xc8b38e74u, 0xb475f255u, 0x46fcd9b9u,
+ 0x7aeb2661u, 0x8b1ddf84u, 0x846a0e79u, 0x915f95e2u,
+ 0x466e598eu, 0x20b45770u, 0x8cd55591u, 0xc902de4cu,
+ 0xb90bace1u, 0xbb8205d0u, 0x11a86248u, 0x7574a99eu,
+ 0xb77f19b6u, 0xe0a9dc09u, 0x662d09a1u, 0xc4324633u,
+ 0xe85a1f02u, 0x09f0be8cu, 0x4a99a025u, 0x1d6efe10u,
+ 0x1ab93d1du, 0x0ba5a4dfu, 0xa186f20fu, 0x2868f169u,
+ 0xdcb7da83u, 0x573906feu, 0xa1e2ce9bu, 0x4fcd7f52u,
+ 0x50115e01u, 0xa70683fau, 0xa002b5c4u, 0x0de6d027u,
+ 0x9af88c27u, 0x773f8641u, 0xc3604c06u, 0x61a806b5u,
+ 0xf0177a28u, 0xc0f586e0u, 0x006058aau, 0x30dc7d62u,
+ 0x11e69ed7u, 0x2338ea63u, 0x53c2dd94u, 0xc2c21634u,
+ 0xbbcbee56u, 0x90bcb6deu, 0xebfc7da1u, 0xce591d76u,
+ 0x6f05e409u, 0x4b7c0188u, 0x39720a3du, 0x7c927c24u,
+ 0x86e3725fu, 0x724d9db9u, 0x1ac15bb4u, 0xd39eb8fcu,
+ 0xed545578u, 0x08fca5b5u, 0xd83d7cd3u, 0x4dad0fc4u,
+ 0x1e50ef5eu, 0xb161e6f8u, 0xa28514d9u, 0x6c51133cu,
+ 0x6fd5c7e7u, 0x56e14ec4u, 0x362abfceu, 0xddc6c837u,
+ 0xd79a3234u, 0x92638212u, 0x670efa8eu, 0x406000e0u},
+ {0x3a39ce37u, 0xd3faf5cfu, 0xabc27737u, 0x5ac52d1bu,
+ 0x5cb0679eu, 0x4fa33742u, 0xd3822740u, 0x99bc9bbeu,
+ 0xd5118e9du, 0xbf0f7315u, 0xd62d1c7eu, 0xc700c47bu,
+ 0xb78c1b6bu, 0x21a19045u, 0xb26eb1beu, 0x6a366eb4u,
+ 0x5748ab2fu, 0xbc946e79u, 0xc6a376d2u, 0x6549c2c8u,
+ 0x530ff8eeu, 0x468dde7du, 0xd5730a1du, 0x4cd04dc6u,
+ 0x2939bbdbu, 0xa9ba4650u, 0xac9526e8u, 0xbe5ee304u,
+ 0xa1fad5f0u, 0x6a2d519au, 0x63ef8ce2u, 0x9a86ee22u,
+ 0xc089c2b8u, 0x43242ef6u, 0xa51e03aau, 0x9cf2d0a4u,
+ 0x83c061bau, 0x9be96a4du, 0x8fe51550u, 0xba645bd6u,
+ 0x2826a2f9u, 0xa73a3ae1u, 0x4ba99586u, 0xef5562e9u,
+ 0xc72fefd3u, 0xf752f7dau, 0x3f046f69u, 0x77fa0a59u,
+ 0x80e4a915u, 0x87b08601u, 0x9b09e6adu, 0x3b3ee593u,
+ 0xe990fd5au, 0x9e34d797u, 0x2cf0b7d9u, 0x022b8b51u,
+ 0x96d5ac3au, 0x017da67du, 0xd1cf3ed6u, 0x7c7d2d28u,
+ 0x1f9f25cfu, 0xadf2b89bu, 0x5ad6b472u, 0x5a88f54cu,
+ 0xe029ac71u, 0xe019a5e6u, 0x47b0acfdu, 0xed93fa9bu,
+ 0xe8d3c48du, 0x283b57ccu, 0xf8d56629u, 0x79132e28u,
+ 0x785f0191u, 0xed756055u, 0xf7960e44u, 0xe3d35e8cu,
+ 0x15056dd4u, 0x88f46dbau, 0x03a16125u, 0x0564f0bdu,
+ 0xc3eb9e15u, 0x3c9057a2u, 0x97271aecu, 0xa93a072au,
+ 0x1b3f6d9bu, 0x1e6321f5u, 0xf59c66fbu, 0x26dcf319u,
+ 0x7533d928u, 0xb155fdf5u, 0x03563482u, 0x8aba3cbbu,
+ 0x28517711u, 0xc20ad9f8u, 0xabcc5167u, 0xccad925fu,
+ 0x4de81751u, 0x3830dc8eu, 0x379d5862u, 0x9320f991u,
+ 0xea7a90c2u, 0xfb3e7bceu, 0x5121ce64u, 0x774fbe32u,
+ 0xa8b6e37eu, 0xc3293d46u, 0x48de5369u, 0x6413e680u,
+ 0xa2ae0810u, 0xdd6db224u, 0x69852dfdu, 0x09072166u,
+ 0xb39a460au, 0x6445c0ddu, 0x586cdecfu, 0x1c20c8aeu,
+ 0x5bbef7ddu, 0x1b588d40u, 0xccd2017fu, 0x6bb4e3bbu,
+ 0xdda26a7eu, 0x3a59ff45u, 0x3e350a44u, 0xbcb4cdd5u,
+ 0x72eacea8u, 0xfa6484bbu, 0x8d6612aeu, 0xbf3c6f47u,
+ 0xd29be463u, 0x542f5d9eu, 0xaec2771bu, 0xf64e6370u,
+ 0x740e0d8du, 0xe75b1357u, 0xf8721671u, 0xaf537d5du,
+ 0x4040cb08u, 0x4eb4e2ccu, 0x34d2466au, 0x0115af84u,
+ 0xe1b00428u, 0x95983a1du, 0x06b89fb4u, 0xce6ea048u,
+ 0x6f3f3b82u, 0x3520ab82u, 0x011a1d4bu, 0x277227f8u,
+ 0x611560b1u, 0xe7933fdcu, 0xbb3a792bu, 0x344525bdu,
+ 0xa08839e1u, 0x51ce794bu, 0x2f32c9b7u, 0xa01fbac9u,
+ 0xe01cc87eu, 0xbcc7d1f6u, 0xcf0111c3u, 0xa1e8aac7u,
+ 0x1a908749u, 0xd44fbd9au, 0xd0dadecbu, 0xd50ada38u,
+ 0x0339c32au, 0xc6913667u, 0x8df9317cu, 0xe0b12b4fu,
+ 0xf79e59b7u, 0x43f5bb3au, 0xf2d519ffu, 0x27d9459cu,
+ 0xbf97222cu, 0x15e6fc2au, 0x0f91fc71u, 0x9b941525u,
+ 0xfae59361u, 0xceb69cebu, 0xc2a86459u, 0x12baa8d1u,
+ 0xb6c1075eu, 0xe3056a0cu, 0x10d25065u, 0xcb03a442u,
+ 0xe0ec6e0eu, 0x1698db3bu, 0x4c98a0beu, 0x3278e964u,
+ 0x9f1f9532u, 0xe0d392dfu, 0xd3a0342bu, 0x8971f21eu,
+ 0x1b0a7441u, 0x4ba3348cu, 0xc5be7120u, 0xc37632d8u,
+ 0xdf359f8du, 0x9b992f2eu, 0xe60b6f47u, 0x0fe3f11du,
+ 0xe54cda54u, 0x1edad891u, 0xce6279cfu, 0xcd3e7e6fu,
+ 0x1618b166u, 0xfd2c1d05u, 0x848fd2c5u, 0xf6fb2299u,
+ 0xf523f357u, 0xa6327623u, 0x93a83531u, 0x56cccd02u,
+ 0xacf08162u, 0x5a75ebb5u, 0x6e163697u, 0x88d273ccu,
+ 0xde966292u, 0x81b949d0u, 0x4c50901bu, 0x71c65614u,
+ 0xe6c6c7bdu, 0x327a140au, 0x45e1d006u, 0xc3f27b9au,
+ 0xc9aa53fdu, 0x62a80f00u, 0xbb25bfe2u, 0x35bdd2f6u,
+ 0x71126905u, 0xb2040222u, 0xb6cbcf7cu, 0xcd769c2bu,
+ 0x53113ec0u, 0x1640e3d3u, 0x38abbd60u, 0x2547adf0u,
+ 0xba38209cu, 0xf746ce76u, 0x77afa1c5u, 0x20756060u,
+ 0x85cbfe4eu, 0x8ae88dd8u, 0x7aaaf9b0u, 0x4cf9aa7eu,
+ 0x1948c25cu, 0x02fb8a8cu, 0x01c36ae4u, 0xd6ebe1f9u,
+ 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu,
+ 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u
+ }
+};
+
+
+#define F1(i) \
+ xl ^= pax[i]; \
+ xr ^= ((sbx[0][xl>>24] + \
+ sbx[1][(xl&0xFF0000)>>16]) ^ \
+ sbx[2][(xl&0xFF00)>>8]) + \
+ sbx[3][xl&0xFF];
+
+#define F2(i) \
+ xr ^= pax[i]; \
+ xl ^= ((sbx[0][xr>>24] + \
+ sbx[1][(xr&0xFF0000)>>16]) ^ \
+ sbx[2][(xr&0xFF00)>>8]) + \
+ sbx[3][xr&0xFF];
+
+
+ static void
+bf_e_block(p_xl, p_xr)
+ long_u *p_xl;
+ long_u *p_xr;
+{
+ long_u temp, xl = *p_xl, xr = *p_xr;
+
+ F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7)
+ F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15)
+ xl ^= pax[16]; xr ^= pax[17];
+ temp = xl; xl = xr; xr = temp;
+ *p_xl = xl; *p_xr = xr;
+}
+
+#if 0 /* not used */
+ static void
+bf_d_block(p_xl, p_xr)
+ long_u *p_xl;
+ long_u *p_xr;
+{
+ long_u temp, xl = *p_xl, xr = *p_xr;
+ F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10)
+ F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2)
+ xl ^= pax[1];
+ xr ^= pax[0];
+ temp = xl; xl = xr; xr = temp;
+ *p_xl = xl; *p_xr = xr;
+}
+#endif
+
+
+#ifdef BIG_ENDIAN
+# define htonl2(x) \
+ x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \
+ (((x) & 0xff0000L) >> 8) | (((x) & 0xff000000L) >> 24))
+#else
+# define htonl2(x)
+#endif
+
+ static void
+bf_e_cblock(block)
+ char_u *block;
+{
+ block8 bk;
+ memcpy(bk.uc, block, 8);
+ htonl2(bk.ul[0]);
+ htonl2(bk.ul[1]);
+ bf_e_block(&bk.ul[0], &bk.ul[1]);
+ htonl2(bk.ul[0]);
+ htonl2(bk.ul[1]);
+ memcpy(block, bk.uc, 8);
+}
+
+#if 0 /* not used */
+ void
+bf_d_cblock(block)
+ char_u *block;
+{
+ block8 bk;
+ memcpy(bk.uc, block, 8);
+ htonl2(bk.ul[0]); htonl2(bk.ul[1]);
+ bf_d_block(&bk.ul[0], &bk.ul[1]);
+ htonl2(bk.ul[0]); htonl2(bk.ul[1]);
+ memcpy(block, bk.uc, 8);
+}
+#endif
+
+ void
+bf_key_init(password)
+ char_u *password;
+{
+ int i, j, keypos = 0;
+ long_u val, data_l, data_r;
+ char *key;
+ int keylen;
+
+ key = sha256_key((char *)password);
+ keylen = STRLEN(key);
+ for (i = 0; i < 256; ++i)
+ {
+ sbx[0][i] = sbi[0][i];
+ sbx[1][i] = sbi[1][i];
+ sbx[2][i] = sbi[2][i];
+ sbx[3][i] = sbi[3][i];
+ }
+
+ for (i = 0; i < 18; ++i)
+ {
+ val = 0;
+ for (j = 0; j < 4; ++j)
+ val = (val << 8) | (key[keypos++ % keylen] & 0xff);
+ pax[i] = ipa[i] ^ val;
+ }
+
+ data_l = data_r = 0;
+ for (i = 0; i < 18; i += 2)
+ {
+ bf_e_block(&data_l, &data_r);
+ pax[i + 0] = data_l;
+ pax[i + 1] = data_r;
+ }
+
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 256; j += 2)
+ {
+ bf_e_block(&data_l, &data_r);
+ sbx[i][j + 0] = data_l;
+ sbx[i][j + 1] = data_r;
+ }
+ }
+}
+
+/*
+ * BF Self test for corrupted tables or instructions
+ */
+ static int
+bf_check_tables(ipa, sbi, val)
+ long_u ipa[18];
+ long_u sbi[4][256];
+ long_u val;
+{
+ int i, j;
+ long_u c = 0;
+
+ for (i = 0; i < 18; i++)
+ c ^= ipa[i];
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 256; j++)
+ c ^= sbi[i][j];
+ return c == val;
+}
+
+typedef struct {
+ char_u password[64];
+ char_u plaintxt[8];
+ char_u cryptxt[8];
+ long_u keysum;
+} struct_bf_test_data;
+
+// Assert bf(password, plaintxt) is cryptxt.
+// Assert csum(pax sbx(password)) is keysum.
+static struct_bf_test_data bf_test_data[] = {
+ {
+ "password",
+ "plaintxt",
+#if 0 /* This value doesn't work, why??? */
+ "\x55\xca\x56\x3a\xef\xe1\x9c\x73", /* cryptxt */
+#else
+ "\x47\xd9\x67\x49\x91\xc5\x9a\x95", /* cryptxt */
+#endif
+ 0x5de01bdbu, /* keysum */
+ },
+};
+
+/*
+ * Return FAIL when there is something wrong with blowfish encryption.
+ */
+ static int
+bf_self_test()
+{
+ int i, bn;
+ int err = 0;
+ block8 bk;
+
+ if (!bf_check_tables(ipa, sbi, 0x6ffa520a))
+ err++;
+
+ bn = ARRAY_LENGTH(bf_test_data);
+ for (i = 0; i < bn; i++)
+ {
+ bf_key_init((char_u *)(bf_test_data[i].password));
+ if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum))
+ err++;
+
+ /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
+ memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
+ bf_e_cblock(bk.uc);
+ if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
+ err++;
+ }
+
+ return err > 0 ? FAIL : OK;
+}
+
+/* Output feedback mode. */
+static int randbyte_offset = 0;
+static int update_offset = 0;
+static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */
+
+/*
+ * Initialize with seed "iv[iv_len]".
+ */
+ void
+bf_ofb_init(iv, iv_len)
+ char_u *iv;
+ int iv_len;
+{
+ int i, mi;
+
+ randbyte_offset = update_offset = 0;
+ memset(ofb_buffer, 0, BF_OFB_LEN);
+ if (iv_len > 0)
+ {
+ mi = iv_len > BF_OFB_LEN ? iv_len : BF_OFB_LEN;
+ for (i = 0; i < mi; i++)
+ ofb_buffer[i % BF_OFB_LEN] ^= iv[i % iv_len];
+ }
+}
+
+ void
+bf_ofb_update(c)
+ int c;
+{
+ ofb_buffer[update_offset++] ^= (char_u)c;
+ if (update_offset == BF_OFB_LEN)
+ update_offset = 0;
+}
+
+ int
+bf_ranbyte()
+{
+ int current_byte = randbyte_offset++;
+ int current_block = (current_byte / BF_BLOCK) * BF_BLOCK;
+
+ if (randbyte_offset == BF_OFB_LEN)
+ randbyte_offset = 0;
+ if ((current_byte % BF_BLOCK) == 0)
+ bf_e_cblock(&ofb_buffer[current_block]);
+ return ofb_buffer[current_byte];
+}
+
+/*
+ * Run a test to check if the encryption works as expected.
+ * Give an error and return FAIL when not.
+ */
+ int
+blowfish_self_test()
+{
+ if (sha256_self_test() == FAIL)
+ {
+ EMSG2(_("E000: sha256 test failed"),"");
+ return FAIL;
+ }
+ if (bf_self_test() == FAIL)
+ {
+ EMSG2(_("E000: Blowfish test failed"),"");
+ return FAIL;
+ }
+ return OK;
+}
+
+#endif /* FEAT_CRYPT */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 13e26d514..fd7471d3d 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -11123,7 +11123,8 @@ ex_match(eap)
ex_X(eap)
exarg_T *eap UNUSED;
{
- (void)get_crypt_key(TRUE, TRUE);
+ if (curbuf->b_p_cm == 0 || blowfish_self_test() == OK)
+ (void)get_crypt_key(TRUE, TRUE);
}
#endif
diff --git a/src/feature.h b/src/feature.h
index ea2e5887d..4568ffc1d 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -592,7 +592,7 @@
/*
* +cryptv Encryption (by Mohsin Ahmed <mosh@sasi.com>).
*/
-#if defined(FEAT_NORMAL) || defined(PROTO)
+#if defined(FEAT_NORMAL) && !defined(FEAT_CRYPT) || defined(PROTO)
# define FEAT_CRYPT
#endif
diff --git a/src/fileio.c b/src/fileio.c
index c36796972..ad5fddde2 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -33,8 +33,14 @@
#define SMBUFSIZE 256 /* size of emergency write buffer */
#ifdef FEAT_CRYPT
-# define CRYPT_MAGIC "VimCrypt~01!" /* "01" is the version nr */
+char crypt_magic_01[] = "VimCrypt~01!";
+char crypt_magic_02[] = "VimCrypt~02!";
# define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */
+
+/* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
+static char *crypt_magic[] = {crypt_magic_01, crypt_magic_02};
+static int crypt_seed_len[] = {0, 8};
+#define CRYPT_SEED_LEN_MAX 8
#endif
/* Is there any system that doesn't have access()? */
@@ -54,6 +60,7 @@ static char_u *readfile_charconvert __ARGS((char_u *fname, char_u *fenc, int *fd
static void check_marks_read __ARGS((void));
#endif
#ifdef FEAT_CRYPT
+static int get_crypt_method __ARGS((char *ptr, int len));
static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile));
#endif
#ifdef UNIX
@@ -1425,7 +1432,9 @@ retry:
*/
if ((filesize == 0
# ifdef FEAT_CRYPT
- || (filesize == CRYPT_MAGIC_LEN && cryptkey != NULL)
+ || (filesize == (CRYPT_MAGIC_LEN
+ + crypt_seed_len[use_crypt_method])
+ && cryptkey != NULL)
# endif
)
&& (fio_flags == FIO_UCSBOM
@@ -2241,7 +2250,7 @@ failed:
#ifdef FEAT_CRYPT
if (cryptkey != curbuf->b_p_key)
- vim_free(cryptkey);
+ free_crypt_key(cryptkey);
#endif
#ifdef FEAT_MBYTE
@@ -2456,7 +2465,8 @@ failed:
c = TRUE;
#ifdef FEAT_CRYPT
if (cryptkey != NULL)
- msg_add_lines(c, (long)linecnt, filesize - CRYPT_MAGIC_LEN);
+ msg_add_lines(c, (long)linecnt, filesize
+ - CRYPT_MAGIC_LEN - crypt_seed_len[use_crypt_method]);
else
#endif
msg_add_lines(c, (long)linecnt, filesize);
@@ -2783,7 +2793,29 @@ check_marks_read()
#ifdef FEAT_CRYPT
/*
- * Check for magic number used for encryption.
+ * Get the crypt method used for a file from "ptr[len]", the magic text at the
+ * start of the file.
+ * Returns -1 when no encryption used.
+ */
+ static int
+get_crypt_method(ptr, len)
+ char *ptr;
+ int len;
+{
+ int i;
+
+ for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++)
+ {
+ if (len < (CRYPT_MAGIC_LEN + crypt_seed_len[i]))
+ continue;
+ if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Check for magic number used for encryption. Applies to the current buffer.
* If found, the magic number is removed from ptr[*sizep] and *sizep and
* *filesizep are updated.
* Return the (new) encryption key, NULL for no encryption.
@@ -2796,17 +2828,23 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
long *filesizep; /* nr of bytes used from file */
int newfile; /* editing a new buffer */
{
- if (*sizep >= CRYPT_MAGIC_LEN
- && STRNCMP(ptr, CRYPT_MAGIC, CRYPT_MAGIC_LEN) == 0)
+ int method = get_crypt_method((char *)ptr, *sizep);
+
+ if (method >= 0)
{
+ curbuf->b_p_cm = method;
+ use_crypt_method = method;
+ if (method > 0)
+ (void)blowfish_self_test();
if (cryptkey == NULL)
{
if (*curbuf->b_p_key)
cryptkey = curbuf->b_p_key;
else
{
- /* When newfile is TRUE, store the typed key
- * in the 'key' option and don't free it. */
+ /* When newfile is TRUE, store the typed key in the 'key'
+ * option and don't free it. bf needs hash of the key saved.
+ */
cryptkey = get_crypt_key(newfile, FALSE);
/* check if empty key entered */
if (cryptkey != NULL && *cryptkey == NUL)
@@ -2820,17 +2858,24 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
if (cryptkey != NULL)
{
- crypt_init_keys(cryptkey);
+ int seed_len = crypt_seed_len[method];
+
+ if (method == 0)
+ crypt_init_keys(cryptkey);
+ else
+ {
+ bf_key_init(cryptkey);
+ bf_ofb_init(ptr + CRYPT_MAGIC_LEN, seed_len);
+ }
/* Remove magic number from the text */
- *filesizep += CRYPT_MAGIC_LEN;
- *sizep -= CRYPT_MAGIC_LEN;
- mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN, (size_t)*sizep);
+ *filesizep += CRYPT_MAGIC_LEN + seed_len;
+ *sizep -= CRYPT_MAGIC_LEN + seed_len;
+ mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + seed_len, (size_t)*sizep);
}
}
- /* When starting to edit a new file which does not have
- * encryption, clear the 'key' option, except when
- * starting up (called with -x argument) */
+ /* When starting to edit a new file which does not have encryption, clear
+ * the 'key' option, except when starting up (called with -x argument) */
else if (newfile && *curbuf->b_p_key && !starting)
set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
@@ -4229,12 +4274,30 @@ restore_backup:
#ifdef FEAT_CRYPT
if (*buf->b_p_key && !filtering)
{
- crypt_init_keys(buf->b_p_key);
- /* Write magic number, so that Vim knows that this file is encrypted
- * when reading it again. This also undergoes utf-8 to ucs-2/4
- * conversion when needed. */
- write_info.bw_buf = (char_u *)CRYPT_MAGIC;
- write_info.bw_len = CRYPT_MAGIC_LEN;
+ char_u header[CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2];
+ int seed_len = crypt_seed_len[buf->b_p_cm];
+
+ use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */
+
+ memset(header, 0, sizeof(header));
+ vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
+ CRYPT_MAGIC_LEN);
+
+ if (buf->b_p_cm == 0)
+ crypt_init_keys(buf->b_p_key);
+ else
+ {
+ /* Using blowfish, add seed. */
+ sha2_seed(header + CRYPT_MAGIC_LEN, seed_len); /* create iv */
+ bf_ofb_init(header + CRYPT_MAGIC_LEN, seed_len);
+ bf_key_init(buf->b_p_key);
+ }
+
+ /* Write magic number, so that Vim knows that this file is
+ * encrypted when reading it again. This also undergoes utf-8 to
+ * ucs-2/4 conversion when needed. */
+ write_info.bw_buf = (char_u *)header;
+ write_info.bw_len = CRYPT_MAGIC_LEN + seed_len;
write_info.bw_flags = FIO_NOCONVERT;
if (buf_write_bytes(&write_info) == FAIL)
end = 0;
diff --git a/src/globals.h b/src/globals.h
index d2b898c8f..a65a2e3b5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -105,6 +105,10 @@ EXTERN int exec_from_reg INIT(= FALSE); /* executing register */
EXTERN int screen_cleared INIT(= FALSE); /* screen has been cleared */
+#ifdef FEAT_CRYPT
+EXTERN int use_crypt_method INIT(= 0);
+#endif
+
/*
* When '$' is included in 'cpoptions' option set:
* When a change command is given that deletes only part of a line, a dollar
diff --git a/src/main.c b/src/main.c
index 0330f6abc..7e741def2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -797,6 +797,7 @@ main
#ifdef FEAT_CRYPT
if (params.ask_for_key)
{
+ (void)blowfish_self_test();
(void)get_crypt_key(TRUE, TRUE);
TIME_MSG("getting crypt key");
}
diff --git a/src/misc2.c b/src/misc2.c
index 8cd568304..3abef1562 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -3685,6 +3685,11 @@ update_mouseshape(shape_idx)
* NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
* most countries. There are a few exceptions, but that still should not be a
* problem since this code was originally created in Europe and India.
+ *
+ * Blowfish addition originally made by Mohsin Ahmed,
+ * http://www.cs.albany.edu/~mosh 2010-03-14
+ * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
+ * and sha256 by Christophe Devine.
*/
/* from zip.h */
@@ -3730,6 +3735,8 @@ decrypt_byte()
{
ush temp;
+ if (use_crypt_method > 0)
+ return bf_ranbyte();
temp = (ush)keys[2] | 2;
return (int)(((unsigned)(temp * (temp ^ 1)) >> 8) & 0xff);
}
@@ -3737,15 +3744,19 @@ decrypt_byte()
/*
* Update the encryption keys with the next byte of plain text
*/
- int
+ void
update_keys(c)
int c; /* byte of plain text */
{
- keys[0] = CRC32(keys[0], c);
- keys[1] += keys[0] & 0xff;
- keys[1] = keys[1] * 134775813L + 1;
- keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
- return c;
+ if (use_crypt_method > 0)
+ bf_ofb_update( (unsigned char) c);
+ else
+ {
+ keys[0] = CRC32(keys[0], c);
+ keys[1] += keys[0] & 0xff;
+ keys[1] = keys[1] * 134775813L + 1;
+ keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
+ }
}
/*
@@ -3769,8 +3780,26 @@ crypt_init_keys(passwd)
}
/*
+ * Free an allocated crypt key. Clear the text to make sure it doesn't stay
+ * in memory anywhere.
+ */
+ void
+free_crypt_key(key)
+ char_u *key;
+{
+ char_u *p;
+
+ if (key != NULL)
+ {
+ for (p = key; *p != NUL; ++p)
+ *p++ = 0;
+ vim_free(key);
+ }
+}
+
+/*
* Ask the user for a crypt key.
- * When "store" is TRUE, the new key in stored in the 'key' option, and the
+ * When "store" is TRUE, the new key is stored in the 'key' option, and the
* 'key' option value is returned: Don't free it.
* When "store" is FALSE, the typed key is returned in allocated memory.
* Returns NULL on failure.
@@ -3801,16 +3830,17 @@ get_crypt_key(store, twice)
if (p2 != NULL && STRCMP(p1, p2) != 0)
{
MSG(_("Keys don't match!"));
- vim_free(p1);
- vim_free(p2);
+ free_crypt_key(p1);
+ free_crypt_key(p2);
p2 = NULL;
round = -1; /* do it again */
continue;
}
+
if (store)
{
set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
- vim_free(p1);
+ free_crypt_key(p1);
p1 = curbuf->b_p_key;
}
break;
@@ -3822,7 +3852,7 @@ get_crypt_key(store, twice)
need_wait_return = FALSE;
msg_didout = FALSE;
- vim_free(p2);
+ free_crypt_key(p2);
return p1;
}
diff --git a/src/option.c b/src/option.c
index c9cad3208..e7ec0c8b9 100644
--- a/src/option.c
+++ b/src/option.c
@@ -77,6 +77,7 @@
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
# define PV_CINW OPT_BUF(BV_CINW)
#endif
+#define PV_CM OPT_BUF(BV_CM)
#ifdef FEAT_FOLDING
# define PV_CMS OPT_BUF(BV_CMS)
#endif
@@ -277,6 +278,7 @@ static char_u *p_cino;
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
static char_u *p_cinw;
#endif
+static long p_cm;
#ifdef FEAT_COMMENTS
static char_u *p_com;
#endif
@@ -834,6 +836,9 @@ static struct vimoption
(char_u *)&p_cpo, PV_NONE,
{(char_u *)CPO_VI, (char_u *)CPO_VIM}
SCRIPTID_INIT},
+ {"cryptmethod", "cm", P_NUM|P_VI_DEF|P_VIM,
+ (char_u *)&p_cm, PV_CM,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
{"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
#ifdef FEAT_CSCOPE
(char_u *)&p_cspc, PV_NONE,
@@ -7870,6 +7875,22 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
#endif
+ else if (pp == &curbuf->b_p_cm)
+ {
+ if (curbuf->b_p_cm < 0)
+ {
+ errmsg = e_positive;
+ curbuf->b_p_cm = 0;
+ }
+ if (curbuf->b_p_cm > 1)
+ {
+ errmsg = e_invarg;
+ curbuf->b_p_cm = 1;
+ }
+ if (curbuf->b_p_cm > 0 && blowfish_self_test() == FAIL)
+ curbuf->b_p_cm = 0;
+ }
+
#ifdef FEAT_WINDOWS
/* (re)set last window status line */
else if (pp == &p_ls)
@@ -9286,6 +9307,7 @@ get_varp(p)
case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
#endif
+ case PV_CM: return (char_u *)&(curbuf->b_p_cm);
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
#endif
diff --git a/src/option.h b/src/option.h
index b635db175..b49c0c47f 100644
--- a/src/option.h
+++ b/src/option.h
@@ -908,6 +908,7 @@ enum
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
, BV_CINW
#endif
+ , BV_CM
#ifdef FEAT_FOLDING
, BV_CMS
#endif
diff --git a/src/proto.h b/src/proto.h
index 85f49378c..dd2e14654 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -69,6 +69,9 @@ extern int _stricoll __ARGS((char *a, char *b));
# include "os_qnx.pro"
# endif
+# ifdef FEAT_CRYPT
+# include "blowfish.pro"
+# endif
# include "buffer.pro"
# include "charset.pro"
# ifdef FEAT_CSCOPE
@@ -146,6 +149,9 @@ void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(con
# endif
# include "regexp.pro"
# include "screen.pro"
+# ifdef FEAT_CRYPT
+# include "sha256.pro"
+# endif
# include "search.pro"
# include "spell.pro"
# include "syntax.pro"
diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro
new file mode 100644
index 000000000..6b6628742
--- /dev/null
+++ b/src/proto/blowfish.pro
@@ -0,0 +1,7 @@
+/* blowfish.c */
+void bf_key_init __ARGS((char_u *password));
+void bf_ofb_init __ARGS((char_u *iv, int iv_len));
+void bf_ofb_update __ARGS((int c));
+int bf_ranbyte __ARGS((void));
+int blowfish_self_test __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 5c4cc4210..9b27b7e3d 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -81,8 +81,9 @@ char_u *parse_shape_opt __ARGS((int what));
int get_shape_idx __ARGS((int mouse));
void update_mouseshape __ARGS((int shape_idx));
int decrypt_byte __ARGS((void));
-int update_keys __ARGS((int c));
+void update_keys __ARGS((int c));
void crypt_init_keys __ARGS((char_u *passwd));
+void free_crypt_key __ARGS((char_u *key));
char_u *get_crypt_key __ARGS((int store, int twice));
void *vim_findfile_init __ARGS((char_u *path, char_u *filename, char_u *stopdirs, int level, int free_visited, int find_what, void *search_ctx_arg, int tagfile, char_u *rel_fname));
char_u *vim_findfile_stopdir __ARGS((char_u *buf));
diff --git a/src/proto/sha256.pro b/src/proto/sha256.pro
new file mode 100644
index 000000000..635721c8c
--- /dev/null
+++ b/src/proto/sha256.pro
@@ -0,0 +1,5 @@
+/* sha256.c */
+char *sha256_key __ARGS((char *buf));
+int sha256_self_test __ARGS((void));
+void sha2_seed __ARGS((char_u header[], int header_len));
+/* vim: set ft=c : */
diff --git a/src/sha256.c b/src/sha256.c
new file mode 100644
index 000000000..24e57b986
--- /dev/null
+++ b/src/sha256.c
@@ -0,0 +1,429 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * FIPS-180-2 compliant SHA-256 implementation
+ * GPL by Christophe Devine.
+ * Modified for md5deep, in public domain.
+ * Modified For Vim, GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ *
+ * Vim specific notes:
+ * Functions exported by this file:
+ * 1. sha256_key() hashes the password to 64 bytes char string.
+ * 2. sha2_seed() generates a random header.
+ * sha256_self_test() is implicitly called once.
+ */
+
+#include "vim.h"
+
+#ifdef FEAT_CRYPT
+
+typedef unsigned long uint32_t;
+
+typedef struct {
+ uint32_t total[2];
+ uint32_t state[8];
+ char_u buffer[64];
+} context_sha256_T;
+
+static void sha256_starts __ARGS((context_sha256_T *ctx));
+static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
+static void sha256_update __ARGS((context_sha256_T *ctx, char_u *input, uint32_t length));
+static void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32]));
+static char *sha256_bytes __ARGS((char *buf, int buflen));
+static unsigned int get_some_time __ARGS((void));
+
+
+#define GET_UINT32(n, b, i) \
+{ \
+ (n) = ( (uint32_t)(b)[(i) ] << 24) \
+ | ( (uint32_t)(b)[(i) + 1] << 16) \
+ | ( (uint32_t)(b)[(i) + 2] << 8) \
+ | ( (uint32_t)(b)[(i) + 3] ); \
+}
+
+#define PUT_UINT32(n,b,i) \
+{ \
+ (b)[(i) ] = (char_u)((n) >> 24); \
+ (b)[(i) + 1] = (char_u)((n) >> 16); \
+ (b)[(i) + 2] = (char_u)((n) >> 8); \
+ (b)[(i) + 3] = (char_u)((n) ); \
+}
+
+ static void
+sha256_starts(ctx)
+ context_sha256_T *ctx;
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->state[0] = 0x6A09E667;
+ ctx->state[1] = 0xBB67AE85;
+ ctx->state[2] = 0x3C6EF372;
+ ctx->state[3] = 0xA54FF53A;
+ ctx->state[4] = 0x510E527F;
+ ctx->state[5] = 0x9B05688C;
+ ctx->state[6] = 0x1F83D9AB;
+ ctx->state[7] = 0x5BE0CD19;
+}
+
+ static void
+sha256_process(ctx, data)
+ context_sha256_T *ctx;
+ char_u data[64];
+{
+ uint32_t temp1, temp2, W[64];
+ uint32_t A, B, C, D, E, F, G, H;
+
+ GET_UINT32(W[0], data, 0);
+ GET_UINT32(W[1], data, 4);
+ GET_UINT32(W[2], data, 8);
+ GET_UINT32(W[3], data, 12);
+ GET_UINT32(W[4], data, 16);
+ GET_UINT32(W[5], data, 20);
+ GET_UINT32(W[6], data, 24);
+ GET_UINT32(W[7], data, 28);
+ GET_UINT32(W[8], data, 32);
+ GET_UINT32(W[9], data, 36);
+ GET_UINT32(W[10], data, 40);
+ GET_UINT32(W[11], data, 44);
+ GET_UINT32(W[12], data, 48);
+ GET_UINT32(W[13], data, 52);
+ GET_UINT32(W[14], data, 56);
+ GET_UINT32(W[15], data, 60);
+
+#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+
+#define F0(x, y, z) ((x & y) | (z & (x | y)))
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+
+#define R(t) \
+( \
+ W[t] = S1(W[t - 2]) + W[t - 7] + \
+ S0(W[t - 15]) + W[t - 16] \
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K) \
+{ \
+ temp1 = h + S3(e) + F1(e, f, g) + K + x; \
+ temp2 = S2(a) + F0(a, b, c); \
+ d += temp1; h = temp1 + temp2; \
+}
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+ F = ctx->state[5];
+ G = ctx->state[6];
+ H = ctx->state[7];
+
+ P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
+ P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
+ P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
+ P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
+ P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
+ P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
+ P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
+ P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
+ P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
+ P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
+ P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+ P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+ P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+ P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+ P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+ P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+ P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+ P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+ P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+ P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+ P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+ P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+ P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+ P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+ P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+ P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+ P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+ P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+ P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+ P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+ P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+ P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
+ P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+ P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+ P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+ P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+ P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+ P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+ P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+ P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+ P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+ P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+ P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+ P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+ P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+ P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+ P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+ P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+ P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+ P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+ P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+ P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+ P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+ P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+ P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+ P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+ P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+ P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+ P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+ P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+ P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+ P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+ P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+ P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+ ctx->state[5] += F;
+ ctx->state[6] += G;
+ ctx->state[7] += H;
+}
+
+ static void
+sha256_update(ctx, input, length)
+ context_sha256_T *ctx;
+ char_u *input;
+ uint32_t length;
+{
+ uint32_t left, fill;
+
+ if (length == 0)
+ return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = 64 - left;
+
+ ctx->total[0] += length;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if (ctx->total[0] < length)
+ ctx->total[1]++;
+
+ if (left && length >= fill)
+ {
+ memcpy((void *)(ctx->buffer + left), (void *)input, fill);
+ sha256_process(ctx, ctx->buffer);
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while (length >= 64)
+ {
+ sha256_process(ctx, input);
+ length -= 64;
+ input += 64;
+ }
+
+ if (length)
+ memcpy((void *)(ctx->buffer + left), (void *)input, length);
+}
+
+static char_u sha256_padding[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+ static void
+sha256_finish(ctx, digest)
+ context_sha256_T *ctx;
+ char_u digest[32];
+{
+ uint32_t last, padn;
+ uint32_t high, low;
+ char_u msglen[8];
+
+ high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
+ low = (ctx->total[0] << 3);
+
+ PUT_UINT32(high, msglen, 0);
+ PUT_UINT32(low, msglen, 4);
+
+ last = ctx->total[0] & 0x3F;
+ padn = (last < 56) ? (56 - last) : (120 - last);
+
+ sha256_update(ctx, sha256_padding, padn);
+ sha256_update(ctx, msglen, 8);
+
+ PUT_UINT32(ctx->state[0], digest, 0);
+ PUT_UINT32(ctx->state[1], digest, 4);
+ PUT_UINT32(ctx->state[2], digest, 8);
+ PUT_UINT32(ctx->state[3], digest, 12);
+ PUT_UINT32(ctx->state[4], digest, 16);
+ PUT_UINT32(ctx->state[5], digest, 20);
+ PUT_UINT32(ctx->state[6], digest, 24);
+ PUT_UINT32(ctx->state[7], digest, 28);
+}
+
+ static char *
+sha256_bytes(buf, buflen)
+ char *buf;
+ int buflen;
+{
+ char_u sha256sum[32];
+ static char hexit[65];
+ int j;
+ context_sha256_T ctx;
+
+ sha256_self_test();
+
+ sha256_starts(&ctx);
+ sha256_update(&ctx, (char_u *)buf, buflen);
+ sha256_finish(&ctx, sha256sum);
+ for (j = 0; j < 32; j++)
+ sprintf(hexit + j * 2, "%02x", sha256sum[j]);
+ hexit[sizeof(hexit) - 1] = '\0';
+ return hexit;
+}
+
+/*
+ * Returns sha256(buf) as 64 hex chars.
+ */
+ char *
+sha256_key(buf)
+ char *buf;
+{
+ static char *hexit = 0;
+ int buflen;
+
+ /* No passwd means don't encrypt */
+ if (buf == NULL || *buf == NUL)
+ return "";
+
+ /* if password is "0", reuse previous hash, for user convienience. */
+ if (!strcmp(buf, "0") && hexit)
+ return hexit;
+
+ buflen = strlen(buf);
+ hexit = sha256_bytes(buf, buflen);
+ return hexit;
+}
+
+/*
+ * These are the standard FIPS-180-2 test vectors
+ */
+
+static char *sha_self_test_msg[] = {
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ NULL
+};
+
+static char *sha_self_test_vector[] = {
+ "ba7816bf8f01cfea414140de5dae2223" \
+ "b00361a396177a9cb410ff61f20015ad",
+ "248d6a61d20638b8e5c026930c3e6039" \
+ "a33ce45964ff2167f6ecedd419db06c1",
+ "cdc76e5c9914fb9281a1c7e284d73e67" \
+ "f1809a48a497200e046d39ccc7112cd0"
+};
+
+/*
+ * Perform a test on the SHA256 algorithm.
+ * Return FAIL or OK.
+ */
+ int
+sha256_self_test()
+{
+ int i, j;
+ char output[65];
+ context_sha256_T ctx;
+ char_u buf[1000];
+ char_u sha256sum[32];
+ static int failures = 0;
+ char *hexit;
+ static int sha256_self_tested = 0;
+
+ if (sha256_self_tested > 0)
+ return failures > 0 ? FAIL : OK;
+ sha256_self_tested = 1;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (i < 2)
+ {
+ hexit = sha256_bytes(sha_self_test_msg[i],
+ strlen(sha_self_test_msg[i]));
+ strcpy(output, hexit);
+ }
+ else
+ {
+ sha256_starts(&ctx);
+ memset(buf, 'a', 1000);
+ for (j = 0; j < 1000; j++)
+ sha256_update(&ctx, (char_u *)buf, 1000);
+ sha256_finish(&ctx, sha256sum);
+ for (j = 0; j < 32; j++)
+ sprintf(output + j * 2, "%02x", sha256sum[j]);
+ }
+ if (memcmp(output, sha_self_test_vector[i], 64))
+ {
+ failures++;
+ output[sizeof(output) - 1] = '\0';
+ /* printf("sha256_self_test %d failed %s\n", i, output); */
+ }
+ }
+ return failures > 0 ? FAIL : OK;
+}
+
+ static unsigned int
+get_some_time()
+{
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+
+ /* Using usec makes it less predictable. */
+ gettimeofday(&tv, NULL);
+ return (unsigned int)(tv.tv_sec + tv.tv_usec);
+#else
+ return (unsigned int)time(NULL);
+#endif
+}
+
+/*
+ * set header = sha2_seed(random_data);
+ */
+ void
+sha2_seed(header, header_len)
+ char_u header[];
+ int header_len;
+{
+ int i;
+ static char_u random_data[1000];
+ char_u sha256sum[32];
+ context_sha256_T ctx;
+ srand(get_some_time());
+
+ for (i = 0; i < (int)sizeof(random_data) - 1; i++)
+ random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
+ sha256_starts(&ctx);
+ sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
+ sha256_finish(&ctx, sha256sum);
+
+ for (i = 0; i < header_len; i++)
+ header[i] = sha256sum[i % sizeof(sha256sum)];
+}
+
+#endif /* FEAT_CRYPT */
diff --git a/src/structs.h b/src/structs.h
index 72bd96cd4..5aceb59a8 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1358,6 +1358,7 @@ struct file_buffer
#ifdef FEAT_INS_EXPAND
char_u *b_p_cpt; /* 'complete' */
#endif
+ long b_p_cm; /* 'cryptmethod' */
#ifdef FEAT_COMPL_FUNC
char_u *b_p_cfu; /* 'completefunc' */
char_u *b_p_ofu; /* 'omnifunc' */
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
index 8f35c7bd1..4b1af5f86 100644
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -27,7 +27,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out test66.out test67.out \
- test68.out test69.out
+ test68.out test69.out test71.out
SCRIPTS32 = test50.out test70.out
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
index 760bb21dd..960f5b209 100644
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -46,7 +46,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out test66.out test67.out \
- test68.out test69.out
+ test68.out test69.out test71.out
SCRIPTS32 = test50.out test70.out
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index 073a2841d..6a8e85f6b 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -23,7 +23,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
test54.out test55.out test56.out test57.out test58.out \
test59.out test60.out test61.out test62.out test63.out \
test64.out test65.out test66.out test67.out test68.out \
- test69.out test70.out
+ test69.out test70.out test71.out
SCRIPTS_GUI = test16.out
@@ -69,7 +69,7 @@ test1.out: test1.in
fi \
else echo $* NO OUTPUT >>test.log; \
fi"
- -rm -rf X* test.ok viminfo
+ #-rm -rf X* test.ok viminfo
test49.out: test49.vim
diff --git a/src/testdir/test71.in b/src/testdir/test71.in
new file mode 100644
index 000000000..a2eadd3c1
--- /dev/null
+++ b/src/testdir/test71.in
@@ -0,0 +1,37 @@
+Test for encryption.
+
+STARTTEST
+:so small.vim
+:/^start of testfile/+1
+:let lines = getline('.', '$')
+:new
+:call append(0, lines)
+:$d
+:X
+foobar
+foobar
+:w! Xtestfile
+:bwipe!
+:e Xtestfile
+foobar
+:let dec1_lines = getline('.', '$')
+:%s/^/2/
+:set key=
+:set cryptmethod=1
+:X
+barfoo
+barfoo
+:w! Xtestfile
+:bwipe!
+:e Xtestfile
+barfoo
+:call append(0, dec1_lines)
+:set key=
+:w! test.out
+:qa!
+ENDTEST
+
+start of testfile
+01234567890123456789012345678901234567
+line 2 foo bar blah
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
diff --git a/src/testdir/test71.ok b/src/testdir/test71.ok
new file mode 100644
index 000000000..5820892b6
--- /dev/null
+++ b/src/testdir/test71.ok
@@ -0,0 +1,6 @@
+01234567890123456789012345678901234567
+line 2 foo bar blah
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+201234567890123456789012345678901234567
+2line 2 foo bar blah
+2line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx