1edf3f97aSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
240e6a71cSBram Moolenaar *
30bbabe80SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar
40bbabe80SBram Moolenaar *
50bbabe80SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions.
60bbabe80SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed.
70bbabe80SBram Moolenaar * See README.txt for an overview of the Vim source code.
80bbabe80SBram Moolenaar *
94d504a3eSBram Moolenaar * Blowfish encryption for Vim; in Blowfish cipher feedback mode.
100bbabe80SBram Moolenaar * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
1140e6a71cSBram Moolenaar * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
128f4ac015SBram Moolenaar *
138f4ac015SBram Moolenaar * There are two variants:
148f4ac015SBram Moolenaar * - The old one "blowfish" has a flaw which makes it much easier to crack the
158f4ac015SBram Moolenaar * key. To see this, make a text file with one line of 1000 "x" characters
168f4ac015SBram Moolenaar * and write it encrypted. Use "xxd" to inspect the bytes in the file. You
178f4ac015SBram Moolenaar * will see that a block of 8 bytes repeats 8 times.
188f4ac015SBram Moolenaar * - The new one "blowfish2" is better. It uses an 8 byte CFB to avoid the
198f4ac015SBram Moolenaar * repeats.
2040e6a71cSBram Moolenaar */
2140e6a71cSBram Moolenaar
2240e6a71cSBram Moolenaar #include "vim.h"
2340e6a71cSBram Moolenaar
248f4ac015SBram Moolenaar #if defined(FEAT_CRYPT) || defined(PROTO)
2540e6a71cSBram Moolenaar
2640e6a71cSBram Moolenaar #define BF_BLOCK 8
2704c9bafaSBram Moolenaar #define BF_BLOCK_MASK 7
288f4ac015SBram Moolenaar #define BF_MAX_CFB_LEN (8 * BF_BLOCK)
2940e6a71cSBram Moolenaar
3040e6a71cSBram Moolenaar typedef union {
31fa7584cbSBram Moolenaar UINT32_T ul[2];
3240e6a71cSBram Moolenaar char_u uc[8];
3340e6a71cSBram Moolenaar } block8;
3440e6a71cSBram Moolenaar
354f97475dSBram Moolenaar #if defined(MSWIN)
36c667da51SBram Moolenaar // MS-Windows is always little endian
3740e6a71cSBram Moolenaar #else
380bbabe80SBram Moolenaar # ifdef HAVE_CONFIG_H
39c667da51SBram Moolenaar // in configure.ac AC_C_BIGENDIAN() defines WORDS_BIGENDIAN when needed
4040e6a71cSBram Moolenaar # else
412c02d384SBram Moolenaar # error Please change this code to define WORDS_BIGENDIAN for big-endian machines.
4240e6a71cSBram Moolenaar # endif
4340e6a71cSBram Moolenaar #endif
4440e6a71cSBram Moolenaar
45c667da51SBram Moolenaar // The state of encryption, referenced by cryptstate_T.
468f4ac015SBram Moolenaar typedef struct {
47c667da51SBram Moolenaar UINT32_T pax[18]; // P-array
48c667da51SBram Moolenaar UINT32_T sbx[4][256]; // S-boxes
498f4ac015SBram Moolenaar int randbyte_offset;
508f4ac015SBram Moolenaar int update_offset;
51c667da51SBram Moolenaar char_u cfb_buffer[BF_MAX_CFB_LEN]; // up to 64 bytes used
52c667da51SBram Moolenaar int cfb_len; // size of cfb_buffer actually used
538f4ac015SBram Moolenaar } bf_state_T;
548f4ac015SBram Moolenaar
558f4ac015SBram Moolenaar
56c667da51SBram Moolenaar // Blowfish code
578f4ac015SBram Moolenaar static UINT32_T pax_init[18] = {
5840e6a71cSBram Moolenaar 0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
5940e6a71cSBram Moolenaar 0x03707344u, 0xa4093822u, 0x299f31d0u,
6040e6a71cSBram Moolenaar 0x082efa98u, 0xec4e6c89u, 0x452821e6u,
6140e6a71cSBram Moolenaar 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu,
6240e6a71cSBram Moolenaar 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u,
6340e6a71cSBram Moolenaar 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
6440e6a71cSBram Moolenaar };
6540e6a71cSBram Moolenaar
668f4ac015SBram Moolenaar static UINT32_T sbx_init[4][256] = {
6740e6a71cSBram Moolenaar {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
6840e6a71cSBram Moolenaar 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
6940e6a71cSBram Moolenaar 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
7040e6a71cSBram Moolenaar 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu,
7140e6a71cSBram Moolenaar 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu,
7240e6a71cSBram Moolenaar 0x7b54a41du, 0xc25a59b5u, 0x9c30d539u, 0x2af26013u,
7340e6a71cSBram Moolenaar 0xc5d1b023u, 0x286085f0u, 0xca417918u, 0xb8db38efu,
7440e6a71cSBram Moolenaar 0x8e79dcb0u, 0x603a180eu, 0x6c9e0e8bu, 0xb01e8a3eu,
7540e6a71cSBram Moolenaar 0xd71577c1u, 0xbd314b27u, 0x78af2fdau, 0x55605c60u,
7640e6a71cSBram Moolenaar 0xe65525f3u, 0xaa55ab94u, 0x57489862u, 0x63e81440u,
7740e6a71cSBram Moolenaar 0x55ca396au, 0x2aab10b6u, 0xb4cc5c34u, 0x1141e8ceu,
7840e6a71cSBram Moolenaar 0xa15486afu, 0x7c72e993u, 0xb3ee1411u, 0x636fbc2au,
7940e6a71cSBram Moolenaar 0x2ba9c55du, 0x741831f6u, 0xce5c3e16u, 0x9b87931eu,
8040e6a71cSBram Moolenaar 0xafd6ba33u, 0x6c24cf5cu, 0x7a325381u, 0x28958677u,
8140e6a71cSBram Moolenaar 0x3b8f4898u, 0x6b4bb9afu, 0xc4bfe81bu, 0x66282193u,
8240e6a71cSBram Moolenaar 0x61d809ccu, 0xfb21a991u, 0x487cac60u, 0x5dec8032u,
8340e6a71cSBram Moolenaar 0xef845d5du, 0xe98575b1u, 0xdc262302u, 0xeb651b88u,
8440e6a71cSBram Moolenaar 0x23893e81u, 0xd396acc5u, 0x0f6d6ff3u, 0x83f44239u,
8540e6a71cSBram Moolenaar 0x2e0b4482u, 0xa4842004u, 0x69c8f04au, 0x9e1f9b5eu,
8640e6a71cSBram Moolenaar 0x21c66842u, 0xf6e96c9au, 0x670c9c61u, 0xabd388f0u,
8740e6a71cSBram Moolenaar 0x6a51a0d2u, 0xd8542f68u, 0x960fa728u, 0xab5133a3u,
8840e6a71cSBram Moolenaar 0x6eef0b6cu, 0x137a3be4u, 0xba3bf050u, 0x7efb2a98u,
8940e6a71cSBram Moolenaar 0xa1f1651du, 0x39af0176u, 0x66ca593eu, 0x82430e88u,
9040e6a71cSBram Moolenaar 0x8cee8619u, 0x456f9fb4u, 0x7d84a5c3u, 0x3b8b5ebeu,
9140e6a71cSBram Moolenaar 0xe06f75d8u, 0x85c12073u, 0x401a449fu, 0x56c16aa6u,
9240e6a71cSBram Moolenaar 0x4ed3aa62u, 0x363f7706u, 0x1bfedf72u, 0x429b023du,
9340e6a71cSBram Moolenaar 0x37d0d724u, 0xd00a1248u, 0xdb0fead3u, 0x49f1c09bu,
9440e6a71cSBram Moolenaar 0x075372c9u, 0x80991b7bu, 0x25d479d8u, 0xf6e8def7u,
9540e6a71cSBram Moolenaar 0xe3fe501au, 0xb6794c3bu, 0x976ce0bdu, 0x04c006bau,
9640e6a71cSBram Moolenaar 0xc1a94fb6u, 0x409f60c4u, 0x5e5c9ec2u, 0x196a2463u,
9740e6a71cSBram Moolenaar 0x68fb6fafu, 0x3e6c53b5u, 0x1339b2ebu, 0x3b52ec6fu,
9840e6a71cSBram Moolenaar 0x6dfc511fu, 0x9b30952cu, 0xcc814544u, 0xaf5ebd09u,
9940e6a71cSBram Moolenaar 0xbee3d004u, 0xde334afdu, 0x660f2807u, 0x192e4bb3u,
10040e6a71cSBram Moolenaar 0xc0cba857u, 0x45c8740fu, 0xd20b5f39u, 0xb9d3fbdbu,
10140e6a71cSBram Moolenaar 0x5579c0bdu, 0x1a60320au, 0xd6a100c6u, 0x402c7279u,
10240e6a71cSBram Moolenaar 0x679f25feu, 0xfb1fa3ccu, 0x8ea5e9f8u, 0xdb3222f8u,
10340e6a71cSBram Moolenaar 0x3c7516dfu, 0xfd616b15u, 0x2f501ec8u, 0xad0552abu,
10440e6a71cSBram Moolenaar 0x323db5fau, 0xfd238760u, 0x53317b48u, 0x3e00df82u,
10540e6a71cSBram Moolenaar 0x9e5c57bbu, 0xca6f8ca0u, 0x1a87562eu, 0xdf1769dbu,
10640e6a71cSBram Moolenaar 0xd542a8f6u, 0x287effc3u, 0xac6732c6u, 0x8c4f5573u,
10740e6a71cSBram Moolenaar 0x695b27b0u, 0xbbca58c8u, 0xe1ffa35du, 0xb8f011a0u,
10840e6a71cSBram Moolenaar 0x10fa3d98u, 0xfd2183b8u, 0x4afcb56cu, 0x2dd1d35bu,
10940e6a71cSBram Moolenaar 0x9a53e479u, 0xb6f84565u, 0xd28e49bcu, 0x4bfb9790u,
11040e6a71cSBram Moolenaar 0xe1ddf2dau, 0xa4cb7e33u, 0x62fb1341u, 0xcee4c6e8u,
11140e6a71cSBram Moolenaar 0xef20cadau, 0x36774c01u, 0xd07e9efeu, 0x2bf11fb4u,
11240e6a71cSBram Moolenaar 0x95dbda4du, 0xae909198u, 0xeaad8e71u, 0x6b93d5a0u,
11340e6a71cSBram Moolenaar 0xd08ed1d0u, 0xafc725e0u, 0x8e3c5b2fu, 0x8e7594b7u,
11440e6a71cSBram Moolenaar 0x8ff6e2fbu, 0xf2122b64u, 0x8888b812u, 0x900df01cu,
11540e6a71cSBram Moolenaar 0x4fad5ea0u, 0x688fc31cu, 0xd1cff191u, 0xb3a8c1adu,
11640e6a71cSBram Moolenaar 0x2f2f2218u, 0xbe0e1777u, 0xea752dfeu, 0x8b021fa1u,
11740e6a71cSBram Moolenaar 0xe5a0cc0fu, 0xb56f74e8u, 0x18acf3d6u, 0xce89e299u,
11840e6a71cSBram Moolenaar 0xb4a84fe0u, 0xfd13e0b7u, 0x7cc43b81u, 0xd2ada8d9u,
11940e6a71cSBram Moolenaar 0x165fa266u, 0x80957705u, 0x93cc7314u, 0x211a1477u,
12040e6a71cSBram Moolenaar 0xe6ad2065u, 0x77b5fa86u, 0xc75442f5u, 0xfb9d35cfu,
12140e6a71cSBram Moolenaar 0xebcdaf0cu, 0x7b3e89a0u, 0xd6411bd3u, 0xae1e7e49u,
12240e6a71cSBram Moolenaar 0x00250e2du, 0x2071b35eu, 0x226800bbu, 0x57b8e0afu,
12340e6a71cSBram Moolenaar 0x2464369bu, 0xf009b91eu, 0x5563911du, 0x59dfa6aau,
12440e6a71cSBram Moolenaar 0x78c14389u, 0xd95a537fu, 0x207d5ba2u, 0x02e5b9c5u,
12540e6a71cSBram Moolenaar 0x83260376u, 0x6295cfa9u, 0x11c81968u, 0x4e734a41u,
12640e6a71cSBram Moolenaar 0xb3472dcau, 0x7b14a94au, 0x1b510052u, 0x9a532915u,
12740e6a71cSBram Moolenaar 0xd60f573fu, 0xbc9bc6e4u, 0x2b60a476u, 0x81e67400u,
12840e6a71cSBram Moolenaar 0x08ba6fb5u, 0x571be91fu, 0xf296ec6bu, 0x2a0dd915u,
12940e6a71cSBram Moolenaar 0xb6636521u, 0xe7b9f9b6u, 0xff34052eu, 0xc5855664u,
13040e6a71cSBram Moolenaar 0x53b02d5du, 0xa99f8fa1u, 0x08ba4799u, 0x6e85076au},
13140e6a71cSBram Moolenaar {0x4b7a70e9u, 0xb5b32944u, 0xdb75092eu, 0xc4192623u,
13240e6a71cSBram Moolenaar 0xad6ea6b0u, 0x49a7df7du, 0x9cee60b8u, 0x8fedb266u,
13340e6a71cSBram Moolenaar 0xecaa8c71u, 0x699a17ffu, 0x5664526cu, 0xc2b19ee1u,
13440e6a71cSBram Moolenaar 0x193602a5u, 0x75094c29u, 0xa0591340u, 0xe4183a3eu,
13540e6a71cSBram Moolenaar 0x3f54989au, 0x5b429d65u, 0x6b8fe4d6u, 0x99f73fd6u,
13640e6a71cSBram Moolenaar 0xa1d29c07u, 0xefe830f5u, 0x4d2d38e6u, 0xf0255dc1u,
13740e6a71cSBram Moolenaar 0x4cdd2086u, 0x8470eb26u, 0x6382e9c6u, 0x021ecc5eu,
13840e6a71cSBram Moolenaar 0x09686b3fu, 0x3ebaefc9u, 0x3c971814u, 0x6b6a70a1u,
13940e6a71cSBram Moolenaar 0x687f3584u, 0x52a0e286u, 0xb79c5305u, 0xaa500737u,
14040e6a71cSBram Moolenaar 0x3e07841cu, 0x7fdeae5cu, 0x8e7d44ecu, 0x5716f2b8u,
14140e6a71cSBram Moolenaar 0xb03ada37u, 0xf0500c0du, 0xf01c1f04u, 0x0200b3ffu,
14240e6a71cSBram Moolenaar 0xae0cf51au, 0x3cb574b2u, 0x25837a58u, 0xdc0921bdu,
14340e6a71cSBram Moolenaar 0xd19113f9u, 0x7ca92ff6u, 0x94324773u, 0x22f54701u,
14440e6a71cSBram Moolenaar 0x3ae5e581u, 0x37c2dadcu, 0xc8b57634u, 0x9af3dda7u,
14540e6a71cSBram Moolenaar 0xa9446146u, 0x0fd0030eu, 0xecc8c73eu, 0xa4751e41u,
14640e6a71cSBram Moolenaar 0xe238cd99u, 0x3bea0e2fu, 0x3280bba1u, 0x183eb331u,
14740e6a71cSBram Moolenaar 0x4e548b38u, 0x4f6db908u, 0x6f420d03u, 0xf60a04bfu,
14840e6a71cSBram Moolenaar 0x2cb81290u, 0x24977c79u, 0x5679b072u, 0xbcaf89afu,
14940e6a71cSBram Moolenaar 0xde9a771fu, 0xd9930810u, 0xb38bae12u, 0xdccf3f2eu,
15040e6a71cSBram Moolenaar 0x5512721fu, 0x2e6b7124u, 0x501adde6u, 0x9f84cd87u,
15140e6a71cSBram Moolenaar 0x7a584718u, 0x7408da17u, 0xbc9f9abcu, 0xe94b7d8cu,
15240e6a71cSBram Moolenaar 0xec7aec3au, 0xdb851dfau, 0x63094366u, 0xc464c3d2u,
15340e6a71cSBram Moolenaar 0xef1c1847u, 0x3215d908u, 0xdd433b37u, 0x24c2ba16u,
15440e6a71cSBram Moolenaar 0x12a14d43u, 0x2a65c451u, 0x50940002u, 0x133ae4ddu,
15540e6a71cSBram Moolenaar 0x71dff89eu, 0x10314e55u, 0x81ac77d6u, 0x5f11199bu,
15640e6a71cSBram Moolenaar 0x043556f1u, 0xd7a3c76bu, 0x3c11183bu, 0x5924a509u,
15740e6a71cSBram Moolenaar 0xf28fe6edu, 0x97f1fbfau, 0x9ebabf2cu, 0x1e153c6eu,
15840e6a71cSBram Moolenaar 0x86e34570u, 0xeae96fb1u, 0x860e5e0au, 0x5a3e2ab3u,
15940e6a71cSBram Moolenaar 0x771fe71cu, 0x4e3d06fau, 0x2965dcb9u, 0x99e71d0fu,
16040e6a71cSBram Moolenaar 0x803e89d6u, 0x5266c825u, 0x2e4cc978u, 0x9c10b36au,
16140e6a71cSBram Moolenaar 0xc6150ebau, 0x94e2ea78u, 0xa5fc3c53u, 0x1e0a2df4u,
16240e6a71cSBram Moolenaar 0xf2f74ea7u, 0x361d2b3du, 0x1939260fu, 0x19c27960u,
16340e6a71cSBram Moolenaar 0x5223a708u, 0xf71312b6u, 0xebadfe6eu, 0xeac31f66u,
16440e6a71cSBram Moolenaar 0xe3bc4595u, 0xa67bc883u, 0xb17f37d1u, 0x018cff28u,
16540e6a71cSBram Moolenaar 0xc332ddefu, 0xbe6c5aa5u, 0x65582185u, 0x68ab9802u,
16640e6a71cSBram Moolenaar 0xeecea50fu, 0xdb2f953bu, 0x2aef7dadu, 0x5b6e2f84u,
16740e6a71cSBram Moolenaar 0x1521b628u, 0x29076170u, 0xecdd4775u, 0x619f1510u,
16840e6a71cSBram Moolenaar 0x13cca830u, 0xeb61bd96u, 0x0334fe1eu, 0xaa0363cfu,
16940e6a71cSBram Moolenaar 0xb5735c90u, 0x4c70a239u, 0xd59e9e0bu, 0xcbaade14u,
17040e6a71cSBram Moolenaar 0xeecc86bcu, 0x60622ca7u, 0x9cab5cabu, 0xb2f3846eu,
17140e6a71cSBram Moolenaar 0x648b1eafu, 0x19bdf0cau, 0xa02369b9u, 0x655abb50u,
17240e6a71cSBram Moolenaar 0x40685a32u, 0x3c2ab4b3u, 0x319ee9d5u, 0xc021b8f7u,
17340e6a71cSBram Moolenaar 0x9b540b19u, 0x875fa099u, 0x95f7997eu, 0x623d7da8u,
17440e6a71cSBram Moolenaar 0xf837889au, 0x97e32d77u, 0x11ed935fu, 0x16681281u,
17540e6a71cSBram Moolenaar 0x0e358829u, 0xc7e61fd6u, 0x96dedfa1u, 0x7858ba99u,
17640e6a71cSBram Moolenaar 0x57f584a5u, 0x1b227263u, 0x9b83c3ffu, 0x1ac24696u,
17740e6a71cSBram Moolenaar 0xcdb30aebu, 0x532e3054u, 0x8fd948e4u, 0x6dbc3128u,
17840e6a71cSBram Moolenaar 0x58ebf2efu, 0x34c6ffeau, 0xfe28ed61u, 0xee7c3c73u,
17940e6a71cSBram Moolenaar 0x5d4a14d9u, 0xe864b7e3u, 0x42105d14u, 0x203e13e0u,
18040e6a71cSBram Moolenaar 0x45eee2b6u, 0xa3aaabeau, 0xdb6c4f15u, 0xfacb4fd0u,
18140e6a71cSBram Moolenaar 0xc742f442u, 0xef6abbb5u, 0x654f3b1du, 0x41cd2105u,
18240e6a71cSBram Moolenaar 0xd81e799eu, 0x86854dc7u, 0xe44b476au, 0x3d816250u,
18340e6a71cSBram Moolenaar 0xcf62a1f2u, 0x5b8d2646u, 0xfc8883a0u, 0xc1c7b6a3u,
18440e6a71cSBram Moolenaar 0x7f1524c3u, 0x69cb7492u, 0x47848a0bu, 0x5692b285u,
18540e6a71cSBram Moolenaar 0x095bbf00u, 0xad19489du, 0x1462b174u, 0x23820e00u,
18640e6a71cSBram Moolenaar 0x58428d2au, 0x0c55f5eau, 0x1dadf43eu, 0x233f7061u,
18740e6a71cSBram Moolenaar 0x3372f092u, 0x8d937e41u, 0xd65fecf1u, 0x6c223bdbu,
18840e6a71cSBram Moolenaar 0x7cde3759u, 0xcbee7460u, 0x4085f2a7u, 0xce77326eu,
18940e6a71cSBram Moolenaar 0xa6078084u, 0x19f8509eu, 0xe8efd855u, 0x61d99735u,
19040e6a71cSBram Moolenaar 0xa969a7aau, 0xc50c06c2u, 0x5a04abfcu, 0x800bcadcu,
19140e6a71cSBram Moolenaar 0x9e447a2eu, 0xc3453484u, 0xfdd56705u, 0x0e1e9ec9u,
19240e6a71cSBram Moolenaar 0xdb73dbd3u, 0x105588cdu, 0x675fda79u, 0xe3674340u,
19340e6a71cSBram Moolenaar 0xc5c43465u, 0x713e38d8u, 0x3d28f89eu, 0xf16dff20u,
19440e6a71cSBram Moolenaar 0x153e21e7u, 0x8fb03d4au, 0xe6e39f2bu, 0xdb83adf7u},
19540e6a71cSBram Moolenaar {0xe93d5a68u, 0x948140f7u, 0xf64c261cu, 0x94692934u,
19640e6a71cSBram Moolenaar 0x411520f7u, 0x7602d4f7u, 0xbcf46b2eu, 0xd4a20068u,
19740e6a71cSBram Moolenaar 0xd4082471u, 0x3320f46au, 0x43b7d4b7u, 0x500061afu,
19840e6a71cSBram Moolenaar 0x1e39f62eu, 0x97244546u, 0x14214f74u, 0xbf8b8840u,
19940e6a71cSBram Moolenaar 0x4d95fc1du, 0x96b591afu, 0x70f4ddd3u, 0x66a02f45u,
20040e6a71cSBram Moolenaar 0xbfbc09ecu, 0x03bd9785u, 0x7fac6dd0u, 0x31cb8504u,
20140e6a71cSBram Moolenaar 0x96eb27b3u, 0x55fd3941u, 0xda2547e6u, 0xabca0a9au,
20240e6a71cSBram Moolenaar 0x28507825u, 0x530429f4u, 0x0a2c86dau, 0xe9b66dfbu,
20340e6a71cSBram Moolenaar 0x68dc1462u, 0xd7486900u, 0x680ec0a4u, 0x27a18deeu,
20440e6a71cSBram Moolenaar 0x4f3ffea2u, 0xe887ad8cu, 0xb58ce006u, 0x7af4d6b6u,
20540e6a71cSBram Moolenaar 0xaace1e7cu, 0xd3375fecu, 0xce78a399u, 0x406b2a42u,
20640e6a71cSBram Moolenaar 0x20fe9e35u, 0xd9f385b9u, 0xee39d7abu, 0x3b124e8bu,
20740e6a71cSBram Moolenaar 0x1dc9faf7u, 0x4b6d1856u, 0x26a36631u, 0xeae397b2u,
20840e6a71cSBram Moolenaar 0x3a6efa74u, 0xdd5b4332u, 0x6841e7f7u, 0xca7820fbu,
20940e6a71cSBram Moolenaar 0xfb0af54eu, 0xd8feb397u, 0x454056acu, 0xba489527u,
21040e6a71cSBram Moolenaar 0x55533a3au, 0x20838d87u, 0xfe6ba9b7u, 0xd096954bu,
21140e6a71cSBram Moolenaar 0x55a867bcu, 0xa1159a58u, 0xcca92963u, 0x99e1db33u,
21240e6a71cSBram Moolenaar 0xa62a4a56u, 0x3f3125f9u, 0x5ef47e1cu, 0x9029317cu,
21340e6a71cSBram Moolenaar 0xfdf8e802u, 0x04272f70u, 0x80bb155cu, 0x05282ce3u,
21440e6a71cSBram Moolenaar 0x95c11548u, 0xe4c66d22u, 0x48c1133fu, 0xc70f86dcu,
21540e6a71cSBram Moolenaar 0x07f9c9eeu, 0x41041f0fu, 0x404779a4u, 0x5d886e17u,
21640e6a71cSBram Moolenaar 0x325f51ebu, 0xd59bc0d1u, 0xf2bcc18fu, 0x41113564u,
21740e6a71cSBram Moolenaar 0x257b7834u, 0x602a9c60u, 0xdff8e8a3u, 0x1f636c1bu,
21840e6a71cSBram Moolenaar 0x0e12b4c2u, 0x02e1329eu, 0xaf664fd1u, 0xcad18115u,
21940e6a71cSBram Moolenaar 0x6b2395e0u, 0x333e92e1u, 0x3b240b62u, 0xeebeb922u,
22040e6a71cSBram Moolenaar 0x85b2a20eu, 0xe6ba0d99u, 0xde720c8cu, 0x2da2f728u,
22140e6a71cSBram Moolenaar 0xd0127845u, 0x95b794fdu, 0x647d0862u, 0xe7ccf5f0u,
22240e6a71cSBram Moolenaar 0x5449a36fu, 0x877d48fau, 0xc39dfd27u, 0xf33e8d1eu,
22340e6a71cSBram Moolenaar 0x0a476341u, 0x992eff74u, 0x3a6f6eabu, 0xf4f8fd37u,
22440e6a71cSBram Moolenaar 0xa812dc60u, 0xa1ebddf8u, 0x991be14cu, 0xdb6e6b0du,
22540e6a71cSBram Moolenaar 0xc67b5510u, 0x6d672c37u, 0x2765d43bu, 0xdcd0e804u,
22640e6a71cSBram Moolenaar 0xf1290dc7u, 0xcc00ffa3u, 0xb5390f92u, 0x690fed0bu,
22740e6a71cSBram Moolenaar 0x667b9ffbu, 0xcedb7d9cu, 0xa091cf0bu, 0xd9155ea3u,
22840e6a71cSBram Moolenaar 0xbb132f88u, 0x515bad24u, 0x7b9479bfu, 0x763bd6ebu,
22940e6a71cSBram Moolenaar 0x37392eb3u, 0xcc115979u, 0x8026e297u, 0xf42e312du,
23040e6a71cSBram Moolenaar 0x6842ada7u, 0xc66a2b3bu, 0x12754cccu, 0x782ef11cu,
23140e6a71cSBram Moolenaar 0x6a124237u, 0xb79251e7u, 0x06a1bbe6u, 0x4bfb6350u,
23240e6a71cSBram Moolenaar 0x1a6b1018u, 0x11caedfau, 0x3d25bdd8u, 0xe2e1c3c9u,
23340e6a71cSBram Moolenaar 0x44421659u, 0x0a121386u, 0xd90cec6eu, 0xd5abea2au,
23440e6a71cSBram Moolenaar 0x64af674eu, 0xda86a85fu, 0xbebfe988u, 0x64e4c3feu,
23540e6a71cSBram Moolenaar 0x9dbc8057u, 0xf0f7c086u, 0x60787bf8u, 0x6003604du,
23640e6a71cSBram Moolenaar 0xd1fd8346u, 0xf6381fb0u, 0x7745ae04u, 0xd736fcccu,
23740e6a71cSBram Moolenaar 0x83426b33u, 0xf01eab71u, 0xb0804187u, 0x3c005e5fu,
23840e6a71cSBram Moolenaar 0x77a057beu, 0xbde8ae24u, 0x55464299u, 0xbf582e61u,
23940e6a71cSBram Moolenaar 0x4e58f48fu, 0xf2ddfda2u, 0xf474ef38u, 0x8789bdc2u,
24040e6a71cSBram Moolenaar 0x5366f9c3u, 0xc8b38e74u, 0xb475f255u, 0x46fcd9b9u,
24140e6a71cSBram Moolenaar 0x7aeb2661u, 0x8b1ddf84u, 0x846a0e79u, 0x915f95e2u,
24240e6a71cSBram Moolenaar 0x466e598eu, 0x20b45770u, 0x8cd55591u, 0xc902de4cu,
24340e6a71cSBram Moolenaar 0xb90bace1u, 0xbb8205d0u, 0x11a86248u, 0x7574a99eu,
24440e6a71cSBram Moolenaar 0xb77f19b6u, 0xe0a9dc09u, 0x662d09a1u, 0xc4324633u,
24540e6a71cSBram Moolenaar 0xe85a1f02u, 0x09f0be8cu, 0x4a99a025u, 0x1d6efe10u,
24640e6a71cSBram Moolenaar 0x1ab93d1du, 0x0ba5a4dfu, 0xa186f20fu, 0x2868f169u,
24740e6a71cSBram Moolenaar 0xdcb7da83u, 0x573906feu, 0xa1e2ce9bu, 0x4fcd7f52u,
24840e6a71cSBram Moolenaar 0x50115e01u, 0xa70683fau, 0xa002b5c4u, 0x0de6d027u,
24940e6a71cSBram Moolenaar 0x9af88c27u, 0x773f8641u, 0xc3604c06u, 0x61a806b5u,
25040e6a71cSBram Moolenaar 0xf0177a28u, 0xc0f586e0u, 0x006058aau, 0x30dc7d62u,
25140e6a71cSBram Moolenaar 0x11e69ed7u, 0x2338ea63u, 0x53c2dd94u, 0xc2c21634u,
25240e6a71cSBram Moolenaar 0xbbcbee56u, 0x90bcb6deu, 0xebfc7da1u, 0xce591d76u,
25340e6a71cSBram Moolenaar 0x6f05e409u, 0x4b7c0188u, 0x39720a3du, 0x7c927c24u,
25440e6a71cSBram Moolenaar 0x86e3725fu, 0x724d9db9u, 0x1ac15bb4u, 0xd39eb8fcu,
25540e6a71cSBram Moolenaar 0xed545578u, 0x08fca5b5u, 0xd83d7cd3u, 0x4dad0fc4u,
25640e6a71cSBram Moolenaar 0x1e50ef5eu, 0xb161e6f8u, 0xa28514d9u, 0x6c51133cu,
25740e6a71cSBram Moolenaar 0x6fd5c7e7u, 0x56e14ec4u, 0x362abfceu, 0xddc6c837u,
25840e6a71cSBram Moolenaar 0xd79a3234u, 0x92638212u, 0x670efa8eu, 0x406000e0u},
25940e6a71cSBram Moolenaar {0x3a39ce37u, 0xd3faf5cfu, 0xabc27737u, 0x5ac52d1bu,
26040e6a71cSBram Moolenaar 0x5cb0679eu, 0x4fa33742u, 0xd3822740u, 0x99bc9bbeu,
26140e6a71cSBram Moolenaar 0xd5118e9du, 0xbf0f7315u, 0xd62d1c7eu, 0xc700c47bu,
26240e6a71cSBram Moolenaar 0xb78c1b6bu, 0x21a19045u, 0xb26eb1beu, 0x6a366eb4u,
26340e6a71cSBram Moolenaar 0x5748ab2fu, 0xbc946e79u, 0xc6a376d2u, 0x6549c2c8u,
26440e6a71cSBram Moolenaar 0x530ff8eeu, 0x468dde7du, 0xd5730a1du, 0x4cd04dc6u,
26540e6a71cSBram Moolenaar 0x2939bbdbu, 0xa9ba4650u, 0xac9526e8u, 0xbe5ee304u,
26640e6a71cSBram Moolenaar 0xa1fad5f0u, 0x6a2d519au, 0x63ef8ce2u, 0x9a86ee22u,
26740e6a71cSBram Moolenaar 0xc089c2b8u, 0x43242ef6u, 0xa51e03aau, 0x9cf2d0a4u,
26840e6a71cSBram Moolenaar 0x83c061bau, 0x9be96a4du, 0x8fe51550u, 0xba645bd6u,
26940e6a71cSBram Moolenaar 0x2826a2f9u, 0xa73a3ae1u, 0x4ba99586u, 0xef5562e9u,
27040e6a71cSBram Moolenaar 0xc72fefd3u, 0xf752f7dau, 0x3f046f69u, 0x77fa0a59u,
27140e6a71cSBram Moolenaar 0x80e4a915u, 0x87b08601u, 0x9b09e6adu, 0x3b3ee593u,
27240e6a71cSBram Moolenaar 0xe990fd5au, 0x9e34d797u, 0x2cf0b7d9u, 0x022b8b51u,
27340e6a71cSBram Moolenaar 0x96d5ac3au, 0x017da67du, 0xd1cf3ed6u, 0x7c7d2d28u,
27440e6a71cSBram Moolenaar 0x1f9f25cfu, 0xadf2b89bu, 0x5ad6b472u, 0x5a88f54cu,
27540e6a71cSBram Moolenaar 0xe029ac71u, 0xe019a5e6u, 0x47b0acfdu, 0xed93fa9bu,
27640e6a71cSBram Moolenaar 0xe8d3c48du, 0x283b57ccu, 0xf8d56629u, 0x79132e28u,
27740e6a71cSBram Moolenaar 0x785f0191u, 0xed756055u, 0xf7960e44u, 0xe3d35e8cu,
27840e6a71cSBram Moolenaar 0x15056dd4u, 0x88f46dbau, 0x03a16125u, 0x0564f0bdu,
27940e6a71cSBram Moolenaar 0xc3eb9e15u, 0x3c9057a2u, 0x97271aecu, 0xa93a072au,
28040e6a71cSBram Moolenaar 0x1b3f6d9bu, 0x1e6321f5u, 0xf59c66fbu, 0x26dcf319u,
28140e6a71cSBram Moolenaar 0x7533d928u, 0xb155fdf5u, 0x03563482u, 0x8aba3cbbu,
28240e6a71cSBram Moolenaar 0x28517711u, 0xc20ad9f8u, 0xabcc5167u, 0xccad925fu,
28340e6a71cSBram Moolenaar 0x4de81751u, 0x3830dc8eu, 0x379d5862u, 0x9320f991u,
28440e6a71cSBram Moolenaar 0xea7a90c2u, 0xfb3e7bceu, 0x5121ce64u, 0x774fbe32u,
28540e6a71cSBram Moolenaar 0xa8b6e37eu, 0xc3293d46u, 0x48de5369u, 0x6413e680u,
28640e6a71cSBram Moolenaar 0xa2ae0810u, 0xdd6db224u, 0x69852dfdu, 0x09072166u,
28740e6a71cSBram Moolenaar 0xb39a460au, 0x6445c0ddu, 0x586cdecfu, 0x1c20c8aeu,
28840e6a71cSBram Moolenaar 0x5bbef7ddu, 0x1b588d40u, 0xccd2017fu, 0x6bb4e3bbu,
28940e6a71cSBram Moolenaar 0xdda26a7eu, 0x3a59ff45u, 0x3e350a44u, 0xbcb4cdd5u,
29040e6a71cSBram Moolenaar 0x72eacea8u, 0xfa6484bbu, 0x8d6612aeu, 0xbf3c6f47u,
29140e6a71cSBram Moolenaar 0xd29be463u, 0x542f5d9eu, 0xaec2771bu, 0xf64e6370u,
29240e6a71cSBram Moolenaar 0x740e0d8du, 0xe75b1357u, 0xf8721671u, 0xaf537d5du,
29340e6a71cSBram Moolenaar 0x4040cb08u, 0x4eb4e2ccu, 0x34d2466au, 0x0115af84u,
29440e6a71cSBram Moolenaar 0xe1b00428u, 0x95983a1du, 0x06b89fb4u, 0xce6ea048u,
29540e6a71cSBram Moolenaar 0x6f3f3b82u, 0x3520ab82u, 0x011a1d4bu, 0x277227f8u,
29640e6a71cSBram Moolenaar 0x611560b1u, 0xe7933fdcu, 0xbb3a792bu, 0x344525bdu,
29740e6a71cSBram Moolenaar 0xa08839e1u, 0x51ce794bu, 0x2f32c9b7u, 0xa01fbac9u,
29840e6a71cSBram Moolenaar 0xe01cc87eu, 0xbcc7d1f6u, 0xcf0111c3u, 0xa1e8aac7u,
29940e6a71cSBram Moolenaar 0x1a908749u, 0xd44fbd9au, 0xd0dadecbu, 0xd50ada38u,
30040e6a71cSBram Moolenaar 0x0339c32au, 0xc6913667u, 0x8df9317cu, 0xe0b12b4fu,
30140e6a71cSBram Moolenaar 0xf79e59b7u, 0x43f5bb3au, 0xf2d519ffu, 0x27d9459cu,
30240e6a71cSBram Moolenaar 0xbf97222cu, 0x15e6fc2au, 0x0f91fc71u, 0x9b941525u,
30340e6a71cSBram Moolenaar 0xfae59361u, 0xceb69cebu, 0xc2a86459u, 0x12baa8d1u,
30440e6a71cSBram Moolenaar 0xb6c1075eu, 0xe3056a0cu, 0x10d25065u, 0xcb03a442u,
30540e6a71cSBram Moolenaar 0xe0ec6e0eu, 0x1698db3bu, 0x4c98a0beu, 0x3278e964u,
30640e6a71cSBram Moolenaar 0x9f1f9532u, 0xe0d392dfu, 0xd3a0342bu, 0x8971f21eu,
30740e6a71cSBram Moolenaar 0x1b0a7441u, 0x4ba3348cu, 0xc5be7120u, 0xc37632d8u,
30840e6a71cSBram Moolenaar 0xdf359f8du, 0x9b992f2eu, 0xe60b6f47u, 0x0fe3f11du,
30940e6a71cSBram Moolenaar 0xe54cda54u, 0x1edad891u, 0xce6279cfu, 0xcd3e7e6fu,
31040e6a71cSBram Moolenaar 0x1618b166u, 0xfd2c1d05u, 0x848fd2c5u, 0xf6fb2299u,
31140e6a71cSBram Moolenaar 0xf523f357u, 0xa6327623u, 0x93a83531u, 0x56cccd02u,
31240e6a71cSBram Moolenaar 0xacf08162u, 0x5a75ebb5u, 0x6e163697u, 0x88d273ccu,
31340e6a71cSBram Moolenaar 0xde966292u, 0x81b949d0u, 0x4c50901bu, 0x71c65614u,
31440e6a71cSBram Moolenaar 0xe6c6c7bdu, 0x327a140au, 0x45e1d006u, 0xc3f27b9au,
31540e6a71cSBram Moolenaar 0xc9aa53fdu, 0x62a80f00u, 0xbb25bfe2u, 0x35bdd2f6u,
31640e6a71cSBram Moolenaar 0x71126905u, 0xb2040222u, 0xb6cbcf7cu, 0xcd769c2bu,
31740e6a71cSBram Moolenaar 0x53113ec0u, 0x1640e3d3u, 0x38abbd60u, 0x2547adf0u,
31840e6a71cSBram Moolenaar 0xba38209cu, 0xf746ce76u, 0x77afa1c5u, 0x20756060u,
31940e6a71cSBram Moolenaar 0x85cbfe4eu, 0x8ae88dd8u, 0x7aaaf9b0u, 0x4cf9aa7eu,
32040e6a71cSBram Moolenaar 0x1948c25cu, 0x02fb8a8cu, 0x01c36ae4u, 0xd6ebe1f9u,
32140e6a71cSBram Moolenaar 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu,
32240e6a71cSBram Moolenaar 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u
32340e6a71cSBram Moolenaar }
32440e6a71cSBram Moolenaar };
32540e6a71cSBram Moolenaar
32640e6a71cSBram Moolenaar #define F1(i) \
3278f4ac015SBram Moolenaar xl ^= bfs->pax[i]; \
3288f4ac015SBram Moolenaar xr ^= ((bfs->sbx[0][xl >> 24] + \
3298f4ac015SBram Moolenaar bfs->sbx[1][(xl & 0xFF0000) >> 16]) ^ \
3308f4ac015SBram Moolenaar bfs->sbx[2][(xl & 0xFF00) >> 8]) + \
3318f4ac015SBram Moolenaar bfs->sbx[3][xl & 0xFF];
33240e6a71cSBram Moolenaar
33340e6a71cSBram Moolenaar #define F2(i) \
3348f4ac015SBram Moolenaar xr ^= bfs->pax[i]; \
3358f4ac015SBram Moolenaar xl ^= ((bfs->sbx[0][xr >> 24] + \
3368f4ac015SBram Moolenaar bfs->sbx[1][(xr & 0xFF0000) >> 16]) ^ \
3378f4ac015SBram Moolenaar bfs->sbx[2][(xr & 0xFF00) >> 8]) + \
3388f4ac015SBram Moolenaar bfs->sbx[3][xr & 0xFF];
33940e6a71cSBram Moolenaar
34040e6a71cSBram Moolenaar static void
bf_e_block(bf_state_T * bfs,UINT32_T * p_xl,UINT32_T * p_xr)3417454a06eSBram Moolenaar bf_e_block(
3427454a06eSBram Moolenaar bf_state_T *bfs,
3437454a06eSBram Moolenaar UINT32_T *p_xl,
3447454a06eSBram Moolenaar UINT32_T *p_xr)
34540e6a71cSBram Moolenaar {
3468f4ac015SBram Moolenaar UINT32_T temp;
3478f4ac015SBram Moolenaar UINT32_T xl = *p_xl;
3488f4ac015SBram Moolenaar UINT32_T xr = *p_xr;
34940e6a71cSBram Moolenaar
3508f4ac015SBram Moolenaar F1(0) F2(1)
3518f4ac015SBram Moolenaar F1(2) F2(3)
3528f4ac015SBram Moolenaar F1(4) F2(5)
3538f4ac015SBram Moolenaar F1(6) F2(7)
3548f4ac015SBram Moolenaar F1(8) F2(9)
3558f4ac015SBram Moolenaar F1(10) F2(11)
3568f4ac015SBram Moolenaar F1(12) F2(13)
3578f4ac015SBram Moolenaar F1(14) F2(15)
3588f4ac015SBram Moolenaar xl ^= bfs->pax[16];
3598f4ac015SBram Moolenaar xr ^= bfs->pax[17];
360bbd6afe0SBram Moolenaar temp = xl;
361bbd6afe0SBram Moolenaar xl = xr;
362bbd6afe0SBram Moolenaar xr = temp;
363bbd6afe0SBram Moolenaar *p_xl = xl;
364bbd6afe0SBram Moolenaar *p_xr = xr;
36540e6a71cSBram Moolenaar }
36640e6a71cSBram Moolenaar
36740e6a71cSBram Moolenaar
3680bbabe80SBram Moolenaar #ifdef WORDS_BIGENDIAN
36940e6a71cSBram Moolenaar # define htonl2(x) \
37040e6a71cSBram Moolenaar x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \
37140e6a71cSBram Moolenaar (((x) & 0xff0000L) >> 8) | (((x) & 0xff000000L) >> 24))
37240e6a71cSBram Moolenaar #else
37340e6a71cSBram Moolenaar # define htonl2(x)
37440e6a71cSBram Moolenaar #endif
37540e6a71cSBram Moolenaar
37640e6a71cSBram Moolenaar static void
bf_e_cblock(bf_state_T * bfs,char_u * block)3777454a06eSBram Moolenaar bf_e_cblock(
3787454a06eSBram Moolenaar bf_state_T *bfs,
3797454a06eSBram Moolenaar char_u *block)
38040e6a71cSBram Moolenaar {
38140e6a71cSBram Moolenaar block8 bk;
382bbd6afe0SBram Moolenaar
38340e6a71cSBram Moolenaar memcpy(bk.uc, block, 8);
38440e6a71cSBram Moolenaar htonl2(bk.ul[0]);
38540e6a71cSBram Moolenaar htonl2(bk.ul[1]);
3868f4ac015SBram Moolenaar bf_e_block(bfs, &bk.ul[0], &bk.ul[1]);
38740e6a71cSBram Moolenaar htonl2(bk.ul[0]);
38840e6a71cSBram Moolenaar htonl2(bk.ul[1]);
38940e6a71cSBram Moolenaar memcpy(block, bk.uc, 8);
39040e6a71cSBram Moolenaar }
39140e6a71cSBram Moolenaar
39280794b1cSBram Moolenaar /*
39380794b1cSBram Moolenaar * Initialize the crypt method using "password" as the encryption key and
39480794b1cSBram Moolenaar * "salt[salt_len]" as the salt.
39580794b1cSBram Moolenaar */
3968f4ac015SBram Moolenaar static void
bf_key_init(bf_state_T * bfs,char_u * password,char_u * salt,int salt_len)3977454a06eSBram Moolenaar bf_key_init(
3987454a06eSBram Moolenaar bf_state_T *bfs,
3997454a06eSBram Moolenaar char_u *password,
4007454a06eSBram Moolenaar char_u *salt,
4017454a06eSBram Moolenaar int salt_len)
40240e6a71cSBram Moolenaar {
40340e6a71cSBram Moolenaar int i, j, keypos = 0;
4042f70a34eSBram Moolenaar unsigned u;
405fa7584cbSBram Moolenaar UINT32_T val, data_l, data_r;
406823a1651SBram Moolenaar char_u *key;
40740e6a71cSBram Moolenaar int keylen;
40840e6a71cSBram Moolenaar
409c667da51SBram Moolenaar // Process the key 1001 times.
410c667da51SBram Moolenaar // See http://en.wikipedia.org/wiki/Key_strengthening.
41180794b1cSBram Moolenaar key = sha256_key(password, salt, salt_len);
41280794b1cSBram Moolenaar for (i = 0; i < 1000; i++)
41380794b1cSBram Moolenaar key = sha256_key(key, salt, salt_len);
41480794b1cSBram Moolenaar
415c667da51SBram Moolenaar // Convert the key from 64 hex chars to 32 binary chars.
41680794b1cSBram Moolenaar keylen = (int)STRLEN(key) / 2;
41756be9500SBram Moolenaar if (keylen == 0)
41856be9500SBram Moolenaar {
419f9e3e09fSBram Moolenaar iemsg(_("E831: bf_key_init() called with empty password"));
42056be9500SBram Moolenaar return;
42156be9500SBram Moolenaar }
42280794b1cSBram Moolenaar for (i = 0; i < keylen; i++)
42380794b1cSBram Moolenaar {
4242f70a34eSBram Moolenaar sscanf((char *)&key[i * 2], "%2x", &u);
4252f70a34eSBram Moolenaar key[i] = u;
42680794b1cSBram Moolenaar }
42780794b1cSBram Moolenaar
428c667da51SBram Moolenaar // Use "key" to initialize the P-array ("pax") and S-boxes ("sbx") of
429c667da51SBram Moolenaar // Blowfish.
4308f4ac015SBram Moolenaar mch_memmove(bfs->sbx, sbx_init, 4 * 4 * 256);
43140e6a71cSBram Moolenaar
43240e6a71cSBram Moolenaar for (i = 0; i < 18; ++i)
43340e6a71cSBram Moolenaar {
43440e6a71cSBram Moolenaar val = 0;
43540e6a71cSBram Moolenaar for (j = 0; j < 4; ++j)
436823a1651SBram Moolenaar val = (val << 8) | key[keypos++ % keylen];
4378f4ac015SBram Moolenaar bfs->pax[i] = pax_init[i] ^ val;
43840e6a71cSBram Moolenaar }
43940e6a71cSBram Moolenaar
44040e6a71cSBram Moolenaar data_l = data_r = 0;
44140e6a71cSBram Moolenaar for (i = 0; i < 18; i += 2)
44240e6a71cSBram Moolenaar {
4438f4ac015SBram Moolenaar bf_e_block(bfs, &data_l, &data_r);
4448f4ac015SBram Moolenaar bfs->pax[i + 0] = data_l;
4458f4ac015SBram Moolenaar bfs->pax[i + 1] = data_r;
44640e6a71cSBram Moolenaar }
44740e6a71cSBram Moolenaar
44840e6a71cSBram Moolenaar for (i = 0; i < 4; ++i)
44940e6a71cSBram Moolenaar {
45040e6a71cSBram Moolenaar for (j = 0; j < 256; j += 2)
45140e6a71cSBram Moolenaar {
4528f4ac015SBram Moolenaar bf_e_block(bfs, &data_l, &data_r);
4538f4ac015SBram Moolenaar bfs->sbx[i][j + 0] = data_l;
4548f4ac015SBram Moolenaar bfs->sbx[i][j + 1] = data_r;
45540e6a71cSBram Moolenaar }
45640e6a71cSBram Moolenaar }
45740e6a71cSBram Moolenaar }
45840e6a71cSBram Moolenaar
45940e6a71cSBram Moolenaar /*
4608f4ac015SBram Moolenaar * Blowfish self-test for corrupted tables or instructions.
46140e6a71cSBram Moolenaar */
46240e6a71cSBram Moolenaar static int
bf_check_tables(UINT32_T pax[18],UINT32_T sbx[4][256],UINT32_T val)4637454a06eSBram Moolenaar bf_check_tables(
4647454a06eSBram Moolenaar UINT32_T pax[18],
4657454a06eSBram Moolenaar UINT32_T sbx[4][256],
4667454a06eSBram Moolenaar UINT32_T val)
46740e6a71cSBram Moolenaar {
46840e6a71cSBram Moolenaar int i, j;
469fa7584cbSBram Moolenaar UINT32_T c = 0;
47040e6a71cSBram Moolenaar
47140e6a71cSBram Moolenaar for (i = 0; i < 18; i++)
4728f4ac015SBram Moolenaar c ^= pax[i];
47340e6a71cSBram Moolenaar for (i = 0; i < 4; i++)
47440e6a71cSBram Moolenaar for (j = 0; j < 256; j++)
4758f4ac015SBram Moolenaar c ^= sbx[i][j];
47640e6a71cSBram Moolenaar return c == val;
47740e6a71cSBram Moolenaar }
47840e6a71cSBram Moolenaar
47940e6a71cSBram Moolenaar typedef struct {
48040e6a71cSBram Moolenaar char_u password[64];
48180794b1cSBram Moolenaar char_u salt[9];
48280794b1cSBram Moolenaar char_u plaintxt[9];
48380794b1cSBram Moolenaar char_u cryptxt[9];
484c667da51SBram Moolenaar char_u badcryptxt[9]; // cryptxt when big/little endian is wrong
485fa7584cbSBram Moolenaar UINT32_T keysum;
48640e6a71cSBram Moolenaar } struct_bf_test_data;
48740e6a71cSBram Moolenaar
4884a9b19acSBram Moolenaar /*
4894a9b19acSBram Moolenaar * Assert bf(password, plaintxt) is cryptxt.
4904a9b19acSBram Moolenaar * Assert csum(pax sbx(password)) is keysum.
4914a9b19acSBram Moolenaar */
49240e6a71cSBram Moolenaar static struct_bf_test_data bf_test_data[] = {
49340e6a71cSBram Moolenaar {
49440e6a71cSBram Moolenaar "password",
49580794b1cSBram Moolenaar "salt",
49640e6a71cSBram Moolenaar "plaintxt",
497c667da51SBram Moolenaar "\xad\x3d\xfa\x7f\xe8\xea\x40\xf6", // cryptxt
498c667da51SBram Moolenaar "\x72\x50\x3b\x38\x10\x60\x22\xa7", // badcryptxt
499c667da51SBram Moolenaar 0x56701b5du // keysum
50040e6a71cSBram Moolenaar },
50140e6a71cSBram Moolenaar };
50240e6a71cSBram Moolenaar
50340e6a71cSBram Moolenaar /*
50440e6a71cSBram Moolenaar * Return FAIL when there is something wrong with blowfish encryption.
50540e6a71cSBram Moolenaar */
50640e6a71cSBram Moolenaar static int
bf_self_test(void)5077454a06eSBram Moolenaar bf_self_test(void)
50840e6a71cSBram Moolenaar {
50940e6a71cSBram Moolenaar int i, bn;
51040e6a71cSBram Moolenaar int err = 0;
51140e6a71cSBram Moolenaar block8 bk;
512fa7584cbSBram Moolenaar UINT32_T ui = 0xffffffffUL;
5138f4ac015SBram Moolenaar bf_state_T state;
5148f4ac015SBram Moolenaar
515a80faa89SBram Moolenaar CLEAR_FIELD(state);
5168f4ac015SBram Moolenaar state.cfb_len = BF_MAX_CFB_LEN;
517fa7584cbSBram Moolenaar
518c667da51SBram Moolenaar // We can't simply use sizeof(UINT32_T), it would generate a compiler
519c667da51SBram Moolenaar // warning.
520fa7584cbSBram Moolenaar if (ui != 0xffffffffUL || ui + 1 != 0) {
521fa7584cbSBram Moolenaar err++;
522f9e3e09fSBram Moolenaar emsg(_("E820: sizeof(uint32_t) != 4"));
523fa7584cbSBram Moolenaar }
52440e6a71cSBram Moolenaar
5258f4ac015SBram Moolenaar if (!bf_check_tables(pax_init, sbx_init, 0x6ffa520a))
52640e6a71cSBram Moolenaar err++;
52740e6a71cSBram Moolenaar
52840e6a71cSBram Moolenaar bn = ARRAY_LENGTH(bf_test_data);
52940e6a71cSBram Moolenaar for (i = 0; i < bn; i++)
53040e6a71cSBram Moolenaar {
5318f4ac015SBram Moolenaar bf_key_init(&state, (char_u *)(bf_test_data[i].password),
53280794b1cSBram Moolenaar bf_test_data[i].salt,
53380794b1cSBram Moolenaar (int)STRLEN(bf_test_data[i].salt));
5348f4ac015SBram Moolenaar if (!bf_check_tables(state.pax, state.sbx, bf_test_data[i].keysum))
53540e6a71cSBram Moolenaar err++;
53640e6a71cSBram Moolenaar
537c667da51SBram Moolenaar // Don't modify bf_test_data[i].plaintxt, self test is idempotent.
53840e6a71cSBram Moolenaar memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
5398f4ac015SBram Moolenaar bf_e_cblock(&state, bk.uc);
54040e6a71cSBram Moolenaar if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
5410bbabe80SBram Moolenaar {
5420bbabe80SBram Moolenaar if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
543f9e3e09fSBram Moolenaar emsg(_("E817: Blowfish big/little endian use wrong"));
54440e6a71cSBram Moolenaar err++;
54540e6a71cSBram Moolenaar }
5460bbabe80SBram Moolenaar }
54740e6a71cSBram Moolenaar
54840e6a71cSBram Moolenaar return err > 0 ? FAIL : OK;
54940e6a71cSBram Moolenaar }
55040e6a71cSBram Moolenaar
5518f4ac015SBram Moolenaar /*
5528f4ac015SBram Moolenaar * CFB: Cipher Feedback Mode.
5538f4ac015SBram Moolenaar */
55440e6a71cSBram Moolenaar
55540e6a71cSBram Moolenaar /*
5568f4ac015SBram Moolenaar * Initialize with seed "seed[seed_len]".
55740e6a71cSBram Moolenaar */
5588f4ac015SBram Moolenaar static void
bf_cfb_init(bf_state_T * bfs,char_u * seed,int seed_len)5597454a06eSBram Moolenaar bf_cfb_init(
5607454a06eSBram Moolenaar bf_state_T *bfs,
5617454a06eSBram Moolenaar char_u *seed,
5627454a06eSBram Moolenaar int seed_len)
56340e6a71cSBram Moolenaar {
56440e6a71cSBram Moolenaar int i, mi;
56540e6a71cSBram Moolenaar
5668f4ac015SBram Moolenaar bfs->randbyte_offset = bfs->update_offset = 0;
5678f4ac015SBram Moolenaar vim_memset(bfs->cfb_buffer, 0, bfs->cfb_len);
5688f4ac015SBram Moolenaar if (seed_len > 0)
56940e6a71cSBram Moolenaar {
5708f4ac015SBram Moolenaar mi = seed_len > bfs->cfb_len ? seed_len : bfs->cfb_len;
57140e6a71cSBram Moolenaar for (i = 0; i < mi; i++)
5728f4ac015SBram Moolenaar bfs->cfb_buffer[i % bfs->cfb_len] ^= seed[i % seed_len];
57340e6a71cSBram Moolenaar }
57440e6a71cSBram Moolenaar }
57540e6a71cSBram Moolenaar
5768f4ac015SBram Moolenaar #define BF_CFB_UPDATE(bfs, c) { \
5778f4ac015SBram Moolenaar bfs->cfb_buffer[bfs->update_offset] ^= (char_u)c; \
5788f4ac015SBram Moolenaar if (++bfs->update_offset == bfs->cfb_len) \
5798f4ac015SBram Moolenaar bfs->update_offset = 0; \
58040e6a71cSBram Moolenaar }
58140e6a71cSBram Moolenaar
5828f4ac015SBram Moolenaar #define BF_RANBYTE(bfs, t) { \
5838f4ac015SBram Moolenaar if ((bfs->randbyte_offset & BF_BLOCK_MASK) == 0) \
5848f4ac015SBram Moolenaar bf_e_cblock(bfs, &(bfs->cfb_buffer[bfs->randbyte_offset])); \
5858f4ac015SBram Moolenaar t = bfs->cfb_buffer[bfs->randbyte_offset]; \
5868f4ac015SBram Moolenaar if (++bfs->randbyte_offset == bfs->cfb_len) \
5878f4ac015SBram Moolenaar bfs->randbyte_offset = 0; \
588bbd6afe0SBram Moolenaar }
58940e6a71cSBram Moolenaar
590bbd6afe0SBram Moolenaar /*
591bbd6afe0SBram Moolenaar * Encrypt "from[len]" into "to[len]".
592bbd6afe0SBram Moolenaar * "from" and "to" can be equal to encrypt in place.
593bbd6afe0SBram Moolenaar */
594bbd6afe0SBram Moolenaar void
crypt_blowfish_encode(cryptstate_T * state,char_u * from,size_t len,char_u * to,int last UNUSED)5957454a06eSBram Moolenaar crypt_blowfish_encode(
5967454a06eSBram Moolenaar cryptstate_T *state,
5977454a06eSBram Moolenaar char_u *from,
5987454a06eSBram Moolenaar size_t len,
599*f573c6e1SChristian Brabandt char_u *to,
600*f573c6e1SChristian Brabandt int last UNUSED)
601bbd6afe0SBram Moolenaar {
6028f4ac015SBram Moolenaar bf_state_T *bfs = state->method_state;
603bbd6afe0SBram Moolenaar size_t i;
604bbd6afe0SBram Moolenaar int ztemp, t;
605bbd6afe0SBram Moolenaar
606bbd6afe0SBram Moolenaar for (i = 0; i < len; ++i)
607bbd6afe0SBram Moolenaar {
608bbd6afe0SBram Moolenaar ztemp = from[i];
6098f4ac015SBram Moolenaar BF_RANBYTE(bfs, t);
6108f4ac015SBram Moolenaar BF_CFB_UPDATE(bfs, ztemp);
611bbd6afe0SBram Moolenaar to[i] = t ^ ztemp;
612bbd6afe0SBram Moolenaar }
613bbd6afe0SBram Moolenaar }
614bbd6afe0SBram Moolenaar
615bbd6afe0SBram Moolenaar /*
6168f4ac015SBram Moolenaar * Decrypt "from[len]" into "to[len]".
617bbd6afe0SBram Moolenaar */
618bbd6afe0SBram Moolenaar void
crypt_blowfish_decode(cryptstate_T * state,char_u * from,size_t len,char_u * to,int last UNUSED)6197454a06eSBram Moolenaar crypt_blowfish_decode(
6207454a06eSBram Moolenaar cryptstate_T *state,
6217454a06eSBram Moolenaar char_u *from,
6227454a06eSBram Moolenaar size_t len,
623*f573c6e1SChristian Brabandt char_u *to,
624*f573c6e1SChristian Brabandt int last UNUSED)
625bbd6afe0SBram Moolenaar {
6268f4ac015SBram Moolenaar bf_state_T *bfs = state->method_state;
6278f4ac015SBram Moolenaar size_t i;
628bbd6afe0SBram Moolenaar int t;
629bbd6afe0SBram Moolenaar
6308f4ac015SBram Moolenaar for (i = 0; i < len; ++i)
631bbd6afe0SBram Moolenaar {
6328f4ac015SBram Moolenaar BF_RANBYTE(bfs, t);
6338f4ac015SBram Moolenaar to[i] = from[i] ^ t;
6348f4ac015SBram Moolenaar BF_CFB_UPDATE(bfs, to[i]);
635bbd6afe0SBram Moolenaar }
636bbd6afe0SBram Moolenaar }
637bbd6afe0SBram Moolenaar
6386ee96587SBram Moolenaar int
crypt_blowfish_init(cryptstate_T * state,char_u * key,char_u * salt,int salt_len,char_u * seed,int seed_len)6397454a06eSBram Moolenaar crypt_blowfish_init(
6407454a06eSBram Moolenaar cryptstate_T *state,
6417454a06eSBram Moolenaar char_u* key,
6427454a06eSBram Moolenaar char_u* salt,
6437454a06eSBram Moolenaar int salt_len,
6447454a06eSBram Moolenaar char_u* seed,
6457454a06eSBram Moolenaar int seed_len)
646bbd6afe0SBram Moolenaar {
647c799fe20SBram Moolenaar bf_state_T *bfs = ALLOC_CLEAR_ONE(bf_state_T);
648bbd6afe0SBram Moolenaar
6496ee96587SBram Moolenaar if (bfs == NULL)
6506ee96587SBram Moolenaar return FAIL;
6518f4ac015SBram Moolenaar state->method_state = bfs;
65240e6a71cSBram Moolenaar
653c667da51SBram Moolenaar // "blowfish" uses a 64 byte buffer, causing it to repeat 8 byte groups 8
654c667da51SBram Moolenaar // times. "blowfish2" uses a 8 byte buffer to avoid repeating.
6558f4ac015SBram Moolenaar bfs->cfb_len = state->method_nr == CRYPT_M_BF ? BF_MAX_CFB_LEN : BF_BLOCK;
656a8ffcbbfSBram Moolenaar
6578f4ac015SBram Moolenaar if (blowfish_self_test() == FAIL)
6586ee96587SBram Moolenaar return FAIL;
659a8ffcbbfSBram Moolenaar
6608f4ac015SBram Moolenaar bf_key_init(bfs, key, salt, salt_len);
6618f4ac015SBram Moolenaar bf_cfb_init(bfs, seed, seed_len);
6626ee96587SBram Moolenaar
6636ee96587SBram Moolenaar return OK;
664a8ffcbbfSBram Moolenaar }
665a8ffcbbfSBram Moolenaar
66640e6a71cSBram Moolenaar /*
66740e6a71cSBram Moolenaar * Run a test to check if the encryption works as expected.
66840e6a71cSBram Moolenaar * Give an error and return FAIL when not.
66940e6a71cSBram Moolenaar */
67040e6a71cSBram Moolenaar int
blowfish_self_test(void)6717454a06eSBram Moolenaar blowfish_self_test(void)
67240e6a71cSBram Moolenaar {
67340e6a71cSBram Moolenaar if (sha256_self_test() == FAIL)
67440e6a71cSBram Moolenaar {
675f9e3e09fSBram Moolenaar emsg(_("E818: sha256 test failed"));
67640e6a71cSBram Moolenaar return FAIL;
67740e6a71cSBram Moolenaar }
67840e6a71cSBram Moolenaar if (bf_self_test() == FAIL)
67940e6a71cSBram Moolenaar {
680f9e3e09fSBram Moolenaar emsg(_("E819: Blowfish test failed"));
68140e6a71cSBram Moolenaar return FAIL;
68240e6a71cSBram Moolenaar }
68340e6a71cSBram Moolenaar return OK;
68440e6a71cSBram Moolenaar }
685c667da51SBram Moolenaar #endif // FEAT_CRYPT
686