0
0
mirror of https://github.com/vim/vim.git synced 2025-07-04 23:07:33 -04:00

Add the blowfish encryption patch from Mohsin Ahmed. Needs more work.

This commit is contained in:
Bram Moolenaar 2010-05-16 22:32:54 +02:00
parent 64486671c3
commit 40e6a71c67
30 changed files with 1306 additions and 48 deletions

View File

@ -7,6 +7,7 @@ SRC_ALL = \
src/arabic.c \ src/arabic.c \
src/arabic.h \ src/arabic.h \
src/ascii.h \ src/ascii.h \
src/blowfish.c \
src/buffer.c \ src/buffer.c \
src/charset.c \ src/charset.c \
src/diff.c \ src/diff.c \
@ -58,6 +59,7 @@ SRC_ALL = \
src/regexp.h \ src/regexp.h \
src/screen.c \ src/screen.c \
src/search.c \ src/search.c \
src/sha256.c \
src/structs.h \ src/structs.h \
src/spell.c \ src/spell.c \
src/syntax.c \ src/syntax.c \
@ -79,6 +81,7 @@ SRC_ALL = \
src/testdir/test49.vim \ src/testdir/test49.vim \
src/testdir/test60.vim \ src/testdir/test60.vim \
src/proto.h \ src/proto.h \
src/proto/blowfish.pro \
src/proto/buffer.pro \ src/proto/buffer.pro \
src/proto/charset.pro \ src/proto/charset.pro \
src/proto/diff.pro \ src/proto/diff.pro \
@ -116,6 +119,7 @@ SRC_ALL = \
src/proto/regexp.pro \ src/proto/regexp.pro \
src/proto/screen.pro \ src/proto/screen.pro \
src/proto/search.pro \ src/proto/search.pro \
src/proto/sha256.pro \
src/proto/spell.pro \ src/proto/spell.pro \
src/proto/syntax.pro \ src/proto/syntax.pro \
src/proto/tag.pro \ src/proto/tag.pro \

View File

@ -1361,6 +1361,11 @@ the file is encrypted.
To disable the encryption, reset the 'key' option to an empty value: > To disable the encryption, reset the 'key' option to an empty value: >
:set key= :set key=
You can use the 'cryptmethod' option to select the type of encryption. Do
this before writing the file. When reading an encrypted file it will be set
automatically to the method used when that file was written. You can change
'cryptmethod' before writing that file to change the method.
When reading a file that has been encrypted and this option is not empty, it When reading a file that has been encrypted and this option is not empty, it
will be used for decryption. If the value is empty, you will be prompted to will be used for decryption. If the value is empty, you will be prompted to
enter the key. If you don't enter a key, the file is edited without being enter the key. If you don't enter a key, the file is edited without being

View File

@ -2049,6 +2049,19 @@ A jump table for the options with a short description can be found at |Q_op|.
with system specific functions. with system specific functions.
*'cryptmethod'* *'cm'*
'cryptmethod' number (default 0)
local to buffer
{not in Vi}
Method used for encryption when the buffer is written to a file:
0 PkZip compatible method. A weak kind of encryption.
backwards compatible with Vim 7.2 and older.
1 Blowfish method. Strong encryption. Not compatible
with Vim 7.2 and older.
When reading an encrypted file 'cryptmethod' will be set automatically
to detected method for the file being read.
*'cscopepathcomp'* *'cspc'* *'cscopepathcomp'* *'cspc'*
'cscopepathcomp' 'cspc' number (default 0) 'cscopepathcomp' 'cspc' number (default 0)
global global
@ -4141,7 +4154,7 @@ A jump table for the options with a short description can be found at |Q_op|.
local to buffer local to buffer
{not in Vi} {not in Vi}
The key that is used for encrypting and decrypting the current buffer. The key that is used for encrypting and decrypting the current buffer.
See |encryption|. See |encryption| and 'cryptmethod'.
Careful: Do not set the key value by hand, someone might see the typed Careful: Do not set the key value by hand, someone might see the typed
key. Use the |:X| command. But you can make 'key' empty: > key. Use the |:X| command. But you can make 'key' empty: >
:set key= :set key=

View File

@ -30,6 +30,17 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
*known-bugs* *known-bugs*
-------------------- Known bugs and current work ----------------------- -------------------- Known bugs and current work -----------------------
check blowfish.c
check sha256.c
Use 'cm' option only when FEAT_CRYPT is defined.
When not full match with magic, check for head and give warning about
unsupported crypt method.
if 'enc' is ucs-2, does utf-8 to ucs-2 encoding always work for seed?
Crypt update:
- move bf_self_test() and sha256_self_test() elsewhere
- Update E000 to error number.
Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6) Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6)
E315 when trying to change a file in FileChangedRO autocommand event. E315 when trying to change a file in FileChangedRO autocommand event.
@ -1082,8 +1093,6 @@ restored. (Luc St-Louis)
Vim 7.3: Vim 7.3:
Patches to include: Patches to include:
- Add patch for 'relativenumber' option? Markus Heidelberg, 2008 Jun 27.
Update 2010 May 2.
- Add blowfish encryption. Openssl has an implementation. Also by Paul - Add blowfish encryption. Openssl has an implementation. Also by Paul
Kocher (LGPL), close to original. Mohsin also has some ideas. Kocher (LGPL), close to original. Mohsin also has some ideas.
Take four bytes and turn them into unsigned to avoid byte-order problems. Take four bytes and turn them into unsigned to avoid byte-order problems.

View File

@ -533,6 +533,7 @@ vimwinmain = \
!endif !endif
vimobj = \ vimobj = \
$(OBJDIR)\blowfish.obj \
$(OBJDIR)\buffer.obj \ $(OBJDIR)\buffer.obj \
$(OBJDIR)\charset.obj \ $(OBJDIR)\charset.obj \
$(OBJDIR)\diff.obj \ $(OBJDIR)\diff.obj \
@ -567,6 +568,7 @@ vimobj = \
$(OBJDIR)\regexp.obj \ $(OBJDIR)\regexp.obj \
$(OBJDIR)\screen.obj \ $(OBJDIR)\screen.obj \
$(OBJDIR)\search.obj \ $(OBJDIR)\search.obj \
$(OBJDIR)\sha256.obj \
$(OBJDIR)\spell.obj \ $(OBJDIR)\spell.obj \
$(OBJDIR)\syntax.obj \ $(OBJDIR)\syntax.obj \
$(OBJDIR)\tag.obj \ $(OBJDIR)\tag.obj \

View File

@ -210,6 +210,7 @@ ALL : .\$(VIM).exe vimrun.exe install.exe uninstal.exe xxd/xxd.exe GvimExt/gvime
LINK32_OBJS= \ LINK32_OBJS= \
$(EXTRAS) \ $(EXTRAS) \
"$(INTDIR)/blowfish.obj" \
"$(INTDIR)/buffer.obj" \ "$(INTDIR)/buffer.obj" \
"$(INTDIR)/charset.obj" \ "$(INTDIR)/charset.obj" \
"$(INTDIR)/diff.obj" \ "$(INTDIR)/diff.obj" \
@ -246,6 +247,7 @@ LINK32_OBJS= \
"$(INTDIR)/regexp.obj" \ "$(INTDIR)/regexp.obj" \
"$(INTDIR)/screen.obj" \ "$(INTDIR)/screen.obj" \
"$(INTDIR)/search.obj" \ "$(INTDIR)/search.obj" \
"$(INTDIR)/sha256.obj" \
"$(INTDIR)/spell.obj" \ "$(INTDIR)/spell.obj" \
"$(INTDIR)/syntax.obj" \ "$(INTDIR)/syntax.obj" \
"$(INTDIR)/tag.obj" \ "$(INTDIR)/tag.obj" \

View File

@ -124,7 +124,8 @@ OBJ = obj/buffer.o \
obj/window.o \ obj/window.o \
$(TERMLIB) $(TERMLIB)
PRO = proto/buffer.pro \ PRO = proto/blowfish.pro \
proto/buffer.pro \
proto/charset.pro \ proto/charset.pro \
proto/diff.pro \ proto/diff.pro \
proto/digraph.pro \ proto/digraph.pro \
@ -159,6 +160,7 @@ PRO = proto/buffer.pro \
proto/regexp.pro \ proto/regexp.pro \
proto/screen.pro \ proto/screen.pro \
proto/search.pro \ proto/search.pro \
proto/sha256.pro \
proto/spell.pro \ proto/spell.pro \
proto/syntax.pro \ proto/syntax.pro \
proto/tag.pro \ proto/tag.pro \

View File

@ -453,6 +453,8 @@ INCL = vim.h os_win32.h ascii.h feature.h globals.h keymap.h macros.h \
$(NBDEBUG_INCL) $(NBDEBUG_INCL)
OBJ = \ OBJ = \
$(OUTDIR)\blowfish.obj \
$(OUTDIR)\sha256.obj \
$(OUTDIR)\buffer.obj \ $(OUTDIR)\buffer.obj \
$(OUTDIR)\charset.obj \ $(OUTDIR)\charset.obj \
$(OUTDIR)\diff.obj \ $(OUTDIR)\diff.obj \
@ -912,6 +914,10 @@ testclean:
$(OUTDIR)/buffer.obj: $(OUTDIR) buffer.c $(INCL) $(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)/charset.obj: $(OUTDIR) charset.c $(INCL)
$(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL) $(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL)
@ -1080,6 +1086,7 @@ auto:
# End Custom Build # End Custom Build
proto.h: \ proto.h: \
proto/blowfish.pro \
proto/buffer.pro \ proto/buffer.pro \
proto/charset.pro \ proto/charset.pro \
proto/diff.pro \ proto/diff.pro \
@ -1115,6 +1122,7 @@ proto.h: \
proto/regexp.pro \ proto/regexp.pro \
proto/screen.pro \ proto/screen.pro \
proto/search.pro \ proto/search.pro \
proto/sha256.pro \
proto/spell.pro \ proto/spell.pro \
proto/syntax.pro \ proto/syntax.pro \
proto/tag.pro \ proto/tag.pro \

View File

@ -179,6 +179,7 @@ OBJ = \
$(TERMLIB) $(TERMLIB)
PRO = \ PRO = \
proto/blowfish.pro \
proto/buffer.pro \ proto/buffer.pro \
proto/charset.pro \ proto/charset.pro \
proto/diff.pro \ proto/diff.pro \
@ -214,6 +215,7 @@ PRO = \
proto/regexp.pro \ proto/regexp.pro \
proto/screen.pro \ proto/screen.pro \
proto/search.pro \ proto/search.pro \
proto/sha256.pro \
proto/spell.pro \ proto/spell.pro \
proto/syntax.pro \ proto/syntax.pro \
proto/tag.pro \ proto/tag.pro \
@ -278,6 +280,8 @@ $(PRO): $(GST) vim.h
$(CC) $(CFLAGS) GPFILE=proto/$*.pro $(PROPT) $*.c $(CC) $(CFLAGS) GPFILE=proto/$*.pro $(PROPT) $*.c
# dependancies # dependancies
blowfish.o: blowfish.c
proto/blowfish.pro: blowfish.c
buffer.o: buffer.c buffer.o: buffer.c
proto/buffer.pro: buffer.c proto/buffer.pro: buffer.c
charset.o: charset.c charset.o: charset.c
@ -348,6 +352,8 @@ screen.o: screen.c
proto/screen.pro: screen.c proto/screen.pro: screen.c
search.o: search.c search.o: search.c
proto/search.pro: search.c proto/search.pro: search.c
sha256.o: sha256.c
proto/sha256.pro: sha256.c
spell.o: spell.c spell.o: spell.c
proto/spell.pro: spell.c proto/spell.pro: spell.c
syntax.o: syntax.c syntax.o: syntax.c

View File

@ -468,7 +468,7 @@ CClink = $(CC)
#CONF_OPT_FEAT = --with-features=small #CONF_OPT_FEAT = --with-features=small
#CONF_OPT_FEAT = --with-features=normal #CONF_OPT_FEAT = --with-features=normal
#CONF_OPT_FEAT = --with-features=big #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". # COMPILED BY - For including a specific e-mail address for ":version".
#CONF_OPT_COMPBY = "--with-compiledby=John Doe <JohnDoe@yahoo.com>" #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 #CFLAGS = -g -O2 '-DSTARTUPTIME="vimstartup"' -fno-strength-reduce -Wall -Wmissing-prototypes
# Use this with GCC to check for mistakes, unused arguments, etc. # Use this with GCC to check for mistakes, unused arguments, etc.
#CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -D_FORTIFY_SOURCE=1 CFLAGS = -g -Wall -Wextra -Wmissing-prototypes -Wunreachable-code -D_FORTIFY_SOURCE=1
#PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
# EFENCE - Electric-Fence malloc debugging: catches memory accesses beyond # EFENCE - Electric-Fence malloc debugging: catches memory accesses beyond
# allocated memory (and makes every malloc()/free() very slow). # 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 TAGS_INCL = *.h
BASIC_SRC = \ BASIC_SRC = \
blowfish.c \
buffer.c \ buffer.c \
charset.c \ charset.c \
diff.c \ diff.c \
@ -1415,6 +1416,7 @@ BASIC_SRC = \
regexp.c \ regexp.c \
screen.c \ screen.c \
search.c \ search.c \
sha256.c \
spell.c \ spell.c \
syntax.c \ syntax.c \
tag.c \ tag.c \
@ -1449,6 +1451,7 @@ LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \
OBJ = \ OBJ = \
objects/buffer.o \ objects/buffer.o \
objects/blowfish.o \
objects/charset.o \ objects/charset.o \
objects/diff.o \ objects/diff.o \
objects/digraph.o \ objects/digraph.o \
@ -1487,6 +1490,7 @@ OBJ = \
objects/regexp.o \ objects/regexp.o \
objects/screen.o \ objects/screen.o \
objects/search.o \ objects/search.o \
objects/sha256.o \
objects/spell.o \ objects/spell.o \
objects/syntax.o \ objects/syntax.o \
$(SNIFF_OBJ) \ $(SNIFF_OBJ) \
@ -1507,6 +1511,7 @@ OBJ = \
$(WSDEBUG_OBJ) $(WSDEBUG_OBJ)
PRO_AUTO = \ PRO_AUTO = \
blowfish.pro \
buffer.pro \ buffer.pro \
charset.pro \ charset.pro \
diff.pro \ diff.pro \
@ -1547,6 +1552,7 @@ PRO_AUTO = \
regexp.pro \ regexp.pro \
screen.pro \ screen.pro \
search.pro \ search.pro \
sha256.pro \
spell.pro \ spell.pro \
syntax.pro \ syntax.pro \
tag.pro \ tag.pro \
@ -2337,6 +2343,9 @@ auto/pathdef.c: Makefile auto/config.mk
objects: objects:
mkdir objects mkdir objects
objects/blowfish.o: blowfish.c
$(CCC) -o $@ blowfish.c
objects/buffer.o: buffer.c objects/buffer.o: buffer.c
$(CCC) -o $@ buffer.c $(CCC) -o $@ buffer.c
@ -2547,6 +2556,9 @@ objects/screen.o: screen.c
objects/search.o: search.c objects/search.o: search.c
$(CCC) -o $@ search.c $(CCC) -o $@ search.c
objects/sha256.o: sha256.c
$(CCC) -o $@ sha256.c
objects/spell.o: spell.c objects/spell.o: spell.c
$(CCC) -o $@ spell.c $(CCC) -o $@ spell.c

581
src/blowfish.c Normal file
View File

@ -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 */

View File

@ -11123,7 +11123,8 @@ ex_match(eap)
ex_X(eap) ex_X(eap)
exarg_T *eap UNUSED; 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 #endif

View File

@ -592,7 +592,7 @@
/* /*
* +cryptv Encryption (by Mohsin Ahmed <mosh@sasi.com>). * +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 # define FEAT_CRYPT
#endif #endif

View File

@ -33,8 +33,14 @@
#define SMBUFSIZE 256 /* size of emergency write buffer */ #define SMBUFSIZE 256 /* size of emergency write buffer */
#ifdef FEAT_CRYPT #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! */ # 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 #endif
/* Is there any system that doesn't have access()? */ /* 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)); static void check_marks_read __ARGS((void));
#endif #endif
#ifdef FEAT_CRYPT #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)); static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, long *filesizep, int newfile));
#endif #endif
#ifdef UNIX #ifdef UNIX
@ -1425,7 +1432,9 @@ retry:
*/ */
if ((filesize == 0 if ((filesize == 0
# ifdef FEAT_CRYPT # ifdef FEAT_CRYPT
|| (filesize == CRYPT_MAGIC_LEN && cryptkey != NULL) || (filesize == (CRYPT_MAGIC_LEN
+ crypt_seed_len[use_crypt_method])
&& cryptkey != NULL)
# endif # endif
) )
&& (fio_flags == FIO_UCSBOM && (fio_flags == FIO_UCSBOM
@ -2241,7 +2250,7 @@ failed:
#ifdef FEAT_CRYPT #ifdef FEAT_CRYPT
if (cryptkey != curbuf->b_p_key) if (cryptkey != curbuf->b_p_key)
vim_free(cryptkey); free_crypt_key(cryptkey);
#endif #endif
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@ -2456,7 +2465,8 @@ failed:
c = TRUE; c = TRUE;
#ifdef FEAT_CRYPT #ifdef FEAT_CRYPT
if (cryptkey != NULL) 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 else
#endif #endif
msg_add_lines(c, (long)linecnt, filesize); msg_add_lines(c, (long)linecnt, filesize);
@ -2783,7 +2793,29 @@ check_marks_read()
#ifdef FEAT_CRYPT #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 * If found, the magic number is removed from ptr[*sizep] and *sizep and
* *filesizep are updated. * *filesizep are updated.
* Return the (new) encryption key, NULL for no encryption. * 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 */ long *filesizep; /* nr of bytes used from file */
int newfile; /* editing a new buffer */ int newfile; /* editing a new buffer */
{ {
if (*sizep >= CRYPT_MAGIC_LEN int method = get_crypt_method((char *)ptr, *sizep);
&& STRNCMP(ptr, CRYPT_MAGIC, CRYPT_MAGIC_LEN) == 0)
if (method >= 0)
{ {
curbuf->b_p_cm = method;
use_crypt_method = method;
if (method > 0)
(void)blowfish_self_test();
if (cryptkey == NULL) if (cryptkey == NULL)
{ {
if (*curbuf->b_p_key) if (*curbuf->b_p_key)
cryptkey = curbuf->b_p_key; cryptkey = curbuf->b_p_key;
else else
{ {
/* When newfile is TRUE, store the typed key /* When newfile is TRUE, store the typed key in the 'key'
* in the 'key' option and don't free it. */ * option and don't free it. bf needs hash of the key saved.
*/
cryptkey = get_crypt_key(newfile, FALSE); cryptkey = get_crypt_key(newfile, FALSE);
/* check if empty key entered */ /* check if empty key entered */
if (cryptkey != NULL && *cryptkey == NUL) if (cryptkey != NULL && *cryptkey == NUL)
@ -2820,17 +2858,24 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
if (cryptkey != NULL) 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 */ /* Remove magic number from the text */
*filesizep += CRYPT_MAGIC_LEN; *filesizep += CRYPT_MAGIC_LEN + seed_len;
*sizep -= CRYPT_MAGIC_LEN; *sizep -= CRYPT_MAGIC_LEN + seed_len;
mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN, (size_t)*sizep); mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + seed_len, (size_t)*sizep);
} }
} }
/* When starting to edit a new file which does not have /* When starting to edit a new file which does not have encryption, clear
* encryption, clear the 'key' option, except when * the 'key' option, except when starting up (called with -x argument) */
* starting up (called with -x argument) */
else if (newfile && *curbuf->b_p_key && !starting) else if (newfile && *curbuf->b_p_key && !starting)
set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL); set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
@ -4229,12 +4274,30 @@ restore_backup:
#ifdef FEAT_CRYPT #ifdef FEAT_CRYPT
if (*buf->b_p_key && !filtering) if (*buf->b_p_key && !filtering)
{ {
crypt_init_keys(buf->b_p_key); char_u header[CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2];
/* Write magic number, so that Vim knows that this file is encrypted int seed_len = crypt_seed_len[buf->b_p_cm];
* when reading it again. This also undergoes utf-8 to ucs-2/4
* conversion when needed. */ use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */
write_info.bw_buf = (char_u *)CRYPT_MAGIC;
write_info.bw_len = CRYPT_MAGIC_LEN; 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; write_info.bw_flags = FIO_NOCONVERT;
if (buf_write_bytes(&write_info) == FAIL) if (buf_write_bytes(&write_info) == FAIL)
end = 0; end = 0;

View File

@ -105,6 +105,10 @@ EXTERN int exec_from_reg INIT(= FALSE); /* executing register */
EXTERN int screen_cleared INIT(= FALSE); /* screen has been cleared */ 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 '$' is included in 'cpoptions' option set:
* When a change command is given that deletes only part of a line, a dollar * When a change command is given that deletes only part of a line, a dollar

View File

@ -797,6 +797,7 @@ main
#ifdef FEAT_CRYPT #ifdef FEAT_CRYPT
if (params.ask_for_key) if (params.ask_for_key)
{ {
(void)blowfish_self_test();
(void)get_crypt_key(TRUE, TRUE); (void)get_crypt_key(TRUE, TRUE);
TIME_MSG("getting crypt key"); TIME_MSG("getting crypt key");
} }

View File

@ -3685,6 +3685,11 @@ update_mouseshape(shape_idx)
* NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to * 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 * 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. * 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 */ /* from zip.h */
@ -3730,6 +3735,8 @@ decrypt_byte()
{ {
ush temp; ush temp;
if (use_crypt_method > 0)
return bf_ranbyte();
temp = (ush)keys[2] | 2; temp = (ush)keys[2] | 2;
return (int)(((unsigned)(temp * (temp ^ 1)) >> 8) & 0xff); 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 * Update the encryption keys with the next byte of plain text
*/ */
int void
update_keys(c) update_keys(c)
int c; /* byte of plain text */ int c; /* byte of plain text */
{ {
keys[0] = CRC32(keys[0], c); if (use_crypt_method > 0)
keys[1] += keys[0] & 0xff; bf_ofb_update( (unsigned char) c);
keys[1] = keys[1] * 134775813L + 1; else
keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); {
return c; 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));
}
} }
/* /*
@ -3768,9 +3779,27 @@ 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. * 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. * 'key' option value is returned: Don't free it.
* When "store" is FALSE, the typed key is returned in allocated memory. * When "store" is FALSE, the typed key is returned in allocated memory.
* Returns NULL on failure. * Returns NULL on failure.
@ -3801,16 +3830,17 @@ get_crypt_key(store, twice)
if (p2 != NULL && STRCMP(p1, p2) != 0) if (p2 != NULL && STRCMP(p1, p2) != 0)
{ {
MSG(_("Keys don't match!")); MSG(_("Keys don't match!"));
vim_free(p1); free_crypt_key(p1);
vim_free(p2); free_crypt_key(p2);
p2 = NULL; p2 = NULL;
round = -1; /* do it again */ round = -1; /* do it again */
continue; continue;
} }
if (store) if (store)
{ {
set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL); set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
vim_free(p1); free_crypt_key(p1);
p1 = curbuf->b_p_key; p1 = curbuf->b_p_key;
} }
break; break;
@ -3822,7 +3852,7 @@ get_crypt_key(store, twice)
need_wait_return = FALSE; need_wait_return = FALSE;
msg_didout = FALSE; msg_didout = FALSE;
vim_free(p2); free_crypt_key(p2);
return p1; return p1;
} }

View File

@ -77,6 +77,7 @@
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
# define PV_CINW OPT_BUF(BV_CINW) # define PV_CINW OPT_BUF(BV_CINW)
#endif #endif
#define PV_CM OPT_BUF(BV_CM)
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
# define PV_CMS OPT_BUF(BV_CMS) # define PV_CMS OPT_BUF(BV_CMS)
#endif #endif
@ -277,6 +278,7 @@ static char_u *p_cino;
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
static char_u *p_cinw; static char_u *p_cinw;
#endif #endif
static long p_cm;
#ifdef FEAT_COMMENTS #ifdef FEAT_COMMENTS
static char_u *p_com; static char_u *p_com;
#endif #endif
@ -834,6 +836,9 @@ static struct vimoption
(char_u *)&p_cpo, PV_NONE, (char_u *)&p_cpo, PV_NONE,
{(char_u *)CPO_VI, (char_u *)CPO_VIM} {(char_u *)CPO_VI, (char_u *)CPO_VIM}
SCRIPTID_INIT}, 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, {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
#ifdef FEAT_CSCOPE #ifdef FEAT_CSCOPE
(char_u *)&p_cspc, PV_NONE, (char_u *)&p_cspc, PV_NONE,
@ -7870,6 +7875,22 @@ set_num_option(opt_idx, varp, value, errbuf, errbuflen, opt_flags)
#endif #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 #ifdef FEAT_WINDOWS
/* (re)set last window status line */ /* (re)set last window status line */
else if (pp == &p_ls) else if (pp == &p_ls)
@ -9286,6 +9307,7 @@ get_varp(p)
case PV_CINK: return (char_u *)&(curbuf->b_p_cink); case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
case PV_CINO: return (char_u *)&(curbuf->b_p_cino); case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
#endif #endif
case PV_CM: return (char_u *)&(curbuf->b_p_cm);
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
case PV_CINW: return (char_u *)&(curbuf->b_p_cinw); case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
#endif #endif

View File

@ -908,6 +908,7 @@ enum
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT) #if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
, BV_CINW , BV_CINW
#endif #endif
, BV_CM
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
, BV_CMS , BV_CMS
#endif #endif

View File

@ -69,6 +69,9 @@ extern int _stricoll __ARGS((char *a, char *b));
# include "os_qnx.pro" # include "os_qnx.pro"
# endif # endif
# ifdef FEAT_CRYPT
# include "blowfish.pro"
# endif
# include "buffer.pro" # include "buffer.pro"
# include "charset.pro" # include "charset.pro"
# ifdef FEAT_CSCOPE # ifdef FEAT_CSCOPE
@ -146,6 +149,9 @@ void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(con
# endif # endif
# include "regexp.pro" # include "regexp.pro"
# include "screen.pro" # include "screen.pro"
# ifdef FEAT_CRYPT
# include "sha256.pro"
# endif
# include "search.pro" # include "search.pro"
# include "spell.pro" # include "spell.pro"
# include "syntax.pro" # include "syntax.pro"

7
src/proto/blowfish.pro Normal file
View File

@ -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 : */

View File

@ -81,8 +81,9 @@ char_u *parse_shape_opt __ARGS((int what));
int get_shape_idx __ARGS((int mouse)); int get_shape_idx __ARGS((int mouse));
void update_mouseshape __ARGS((int shape_idx)); void update_mouseshape __ARGS((int shape_idx));
int decrypt_byte __ARGS((void)); 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 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)); 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)); 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)); char_u *vim_findfile_stopdir __ARGS((char_u *buf));

5
src/proto/sha256.pro Normal file
View File

@ -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 : */

429
src/sha256.c Normal file
View File

@ -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 */

View File

@ -1358,6 +1358,7 @@ struct file_buffer
#ifdef FEAT_INS_EXPAND #ifdef FEAT_INS_EXPAND
char_u *b_p_cpt; /* 'complete' */ char_u *b_p_cpt; /* 'complete' */
#endif #endif
long b_p_cm; /* 'cryptmethod' */
#ifdef FEAT_COMPL_FUNC #ifdef FEAT_COMPL_FUNC
char_u *b_p_cfu; /* 'completefunc' */ char_u *b_p_cfu; /* 'completefunc' */
char_u *b_p_ofu; /* 'omnifunc' */ char_u *b_p_ofu; /* 'omnifunc' */

View File

@ -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 \ test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \ test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out test66.out test67.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 SCRIPTS32 = test50.out test70.out

View File

@ -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 \ test30.out test31.out test32.out test33.out test34.out \
test37.out test38.out test39.out test40.out test41.out \ test37.out test38.out test39.out test40.out test41.out \
test42.out test52.out test65.out test66.out test67.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 SCRIPTS32 = test50.out test70.out

View File

@ -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 \ test54.out test55.out test56.out test57.out test58.out \
test59.out test60.out test61.out test62.out test63.out \ test59.out test60.out test61.out test62.out test63.out \
test64.out test65.out test66.out test67.out test68.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 SCRIPTS_GUI = test16.out
@ -69,7 +69,7 @@ test1.out: test1.in
fi \ fi \
else echo $* NO OUTPUT >>test.log; \ else echo $* NO OUTPUT >>test.log; \
fi" fi"
-rm -rf X* test.ok viminfo #-rm -rf X* test.ok viminfo
test49.out: test49.vim test49.out: test49.vim

37
src/testdir/test71.in Normal file
View File

@ -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

6
src/testdir/test71.ok Normal file
View File

@ -0,0 +1,6 @@
01234567890123456789012345678901234567
line 2 foo bar blah
line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
201234567890123456789012345678901234567
2line 2 foo bar blah
2line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx