mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
updated for version 7.4.399
Problem: Encryption implementation is messy. Blowfish encryption has a weakness. Solution: Refactor the encryption, store the state in an allocated struct instead of using a save/restore mechanism. Introduce the "blowfish2" method, which does not have the weakness and encrypts the whole undo file. (largely by David Leadbeater)
This commit is contained in:
158
src/crypt_zip.c
Normal file
158
src/crypt_zip.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* vi:set ts=8 sts=4 sw=4:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* crypt_zip.c: Zip encryption support.
|
||||
*/
|
||||
#include "vim.h"
|
||||
|
||||
#if defined(FEAT_CRYPT) || defined(PROTO)
|
||||
/*
|
||||
* Optional encryption support.
|
||||
* Mohsin Ahmed, mosh@sasi.com, 98-09-24
|
||||
* Based on zip/crypt sources.
|
||||
*
|
||||
* NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
|
||||
* most countries. There are a few exceptions, but that still should not be a
|
||||
* problem since this code was originally created in Europe and India.
|
||||
*/
|
||||
|
||||
/* Need a type that should be 32 bits. 64 also works but wastes space. */
|
||||
# if VIM_SIZEOF_INT >= 4
|
||||
typedef unsigned int u32_T; /* int is at least 32 bits */
|
||||
# else
|
||||
typedef unsigned long u32_T; /* long should be 32 bits or more */
|
||||
# endif
|
||||
|
||||
/* The state of encryption, referenced by cryptstate_T. */
|
||||
typedef struct {
|
||||
u32_T keys[3];
|
||||
} zip_state_T;
|
||||
|
||||
|
||||
static void make_crc_tab __ARGS((void));
|
||||
|
||||
static u32_T crc_32_table[256];
|
||||
|
||||
/*
|
||||
* Fill the CRC table, if not done already.
|
||||
*/
|
||||
static void
|
||||
make_crc_tab()
|
||||
{
|
||||
u32_T s, t, v;
|
||||
static int done = FALSE;
|
||||
|
||||
if (done)
|
||||
return;
|
||||
for (t = 0; t < 256; t++)
|
||||
{
|
||||
v = t;
|
||||
for (s = 0; s < 8; s++)
|
||||
v = (v >> 1) ^ ((v & 1) * (u32_T)0xedb88320L);
|
||||
crc_32_table[t] = v;
|
||||
}
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
#define CRC32(c, b) (crc_32_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
|
||||
|
||||
/*
|
||||
* Return the next byte in the pseudo-random sequence.
|
||||
*/
|
||||
#define DECRYPT_BYTE_ZIP(keys, t) { \
|
||||
short_u temp = (short_u)keys[2] | 2; \
|
||||
t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the encryption keys with the next byte of plain text.
|
||||
*/
|
||||
#define UPDATE_KEYS_ZIP(keys, 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)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize for encryption/decryption.
|
||||
*/
|
||||
void
|
||||
crypt_zip_init(state, key, salt, salt_len, seed, seed_len)
|
||||
cryptstate_T *state;
|
||||
char_u *key;
|
||||
char_u *salt UNUSED;
|
||||
int salt_len UNUSED;
|
||||
char_u *seed UNUSED;
|
||||
int seed_len UNUSED;
|
||||
{
|
||||
char_u *p;
|
||||
zip_state_T *zs;
|
||||
|
||||
zs = (zip_state_T *)alloc(sizeof(zip_state_T));
|
||||
state->method_state = zs;
|
||||
|
||||
make_crc_tab();
|
||||
zs->keys[0] = 305419896L;
|
||||
zs->keys[1] = 591751049L;
|
||||
zs->keys[2] = 878082192L;
|
||||
for (p = key; *p != NUL; ++p)
|
||||
{
|
||||
UPDATE_KEYS_ZIP(zs->keys, (int)*p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt "from[len]" into "to[len]".
|
||||
* "from" and "to" can be equal to encrypt in place.
|
||||
*/
|
||||
void
|
||||
crypt_zip_encode(state, from, len, to)
|
||||
cryptstate_T *state;
|
||||
char_u *from;
|
||||
size_t len;
|
||||
char_u *to;
|
||||
{
|
||||
zip_state_T *zs = state->method_state;
|
||||
size_t i;
|
||||
int ztemp, t;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
ztemp = from[i];
|
||||
DECRYPT_BYTE_ZIP(zs->keys, t);
|
||||
UPDATE_KEYS_ZIP(zs->keys, ztemp);
|
||||
to[i] = t ^ ztemp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt "from[len]" into "to[len]".
|
||||
*/
|
||||
void
|
||||
crypt_zip_decode(state, from, len, to)
|
||||
cryptstate_T *state;
|
||||
char_u *from;
|
||||
size_t len;
|
||||
char_u *to;
|
||||
{
|
||||
zip_state_T *zs = state->method_state;
|
||||
size_t i;
|
||||
short_u temp;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
temp = (short_u)zs->keys[2] | 2;
|
||||
temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
|
||||
UPDATE_KEYS_ZIP(zs->keys, to[i] = from[i] ^ temp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FEAT_CRYPT */
|
Reference in New Issue
Block a user