diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make_bc5.mak | 2 | ||||
-rw-r--r-- | src/Make_ivc.mak | 2 | ||||
-rw-r--r-- | src/Make_manx.mak | 4 | ||||
-rw-r--r-- | src/Make_mvc.mak | 8 | ||||
-rw-r--r-- | src/Make_sas.mak | 6 | ||||
-rw-r--r-- | src/Makefile | 20 | ||||
-rw-r--r-- | src/blowfish.c | 581 | ||||
-rw-r--r-- | src/ex_docmd.c | 3 | ||||
-rw-r--r-- | src/feature.h | 2 | ||||
-rw-r--r-- | src/fileio.c | 107 | ||||
-rw-r--r-- | src/globals.h | 4 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/misc2.c | 52 | ||||
-rw-r--r-- | src/option.c | 22 | ||||
-rw-r--r-- | src/option.h | 1 | ||||
-rw-r--r-- | src/proto.h | 6 | ||||
-rw-r--r-- | src/proto/blowfish.pro | 7 | ||||
-rw-r--r-- | src/proto/misc2.pro | 3 | ||||
-rw-r--r-- | src/proto/sha256.pro | 5 | ||||
-rw-r--r-- | src/sha256.c | 429 | ||||
-rw-r--r-- | src/structs.h | 1 | ||||
-rw-r--r-- | src/testdir/Make_dos.mak | 2 | ||||
-rw-r--r-- | src/testdir/Make_ming.mak | 2 | ||||
-rw-r--r-- | src/testdir/Makefile | 4 | ||||
-rw-r--r-- | src/testdir/test71.in | 37 | ||||
-rw-r--r-- | src/testdir/test71.ok | 6 |
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 |