/* vi:set ts=8 sts=4 sw=4 noet:
*
* 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.c: Generic encryption support.
*/
#include "vim.h"
#if defined(FEAT_CRYPT) || defined(PROTO)
/*
* Optional encryption support.
* Mohsin Ahmed, mosh@sasi.com, 1998-09-24
* Based on zip/crypt sources.
* Refactored by David Leadbeater, 2014.
*
* NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
* most countries. There are a few exceptions, but that still should not be a
* problem since this code was originally created in Europe and India.
*
* Blowfish addition originally made by Mohsin Ahmed,
* http://www.cs.albany.edu/~mosh 2010-03-14
* Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
* and sha256 by Christophe Devine.
*/
typedef struct {
char *name; // encryption name as used in 'cryptmethod'
char *magic; // magic bytes stored in file header
int salt_len; // length of salt, or 0 when not using salt
int seed_len; // length of seed, or 0 when not using seed
#ifdef CRYPT_NOT_INPLACE
int works_inplace; // encryption/decryption can be done in-place
#endif
int whole_undofile; // whole undo file is encrypted
// Optional function pointer for a self-test.
int (* self_test_fn)();
// Function pointer for initializing encryption/decryption.
int (* init_fn)(cryptstate_T *state, char_u *key,
char_u *salt, int salt_len, char_u *seed, int seed_len);
// Function pointers for encoding/decoding from one buffer into another.
// Optional, however, these or the _buffer ones should be configured.
void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len,
char_u *to, int last);
void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len,
char_u *to, int last);
// Function pointers for encoding and decoding, can buffer data if needed.
// Optional (however, these or the above should be configured).
long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
char_u **newptr, int last);
long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
char_u **newptr, int last);
// Function pointers for in-place encoding and decoding, used for
// crypt_*_inplace(). "from" and "to" arguments will be equal.
// These may be the same as decode_fn and encode_fn above, however an
// algorithm may implement them in a way that is not interchangeable with
// the crypt_(en|de)code() interface (for example because it wishes to add
// padding to files).
// This method is used for swap and undo files which have a rigid format.
void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
char_u *p2, int last);
void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
char_u *p2, int last);
} cryptmethod_T;
// index is method_nr of cryptstate_T, CRYPT_M_*
static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
// PK_Zip; very weak
{
"zip",
"VimCrypt~01!",
0,
0,
#ifdef CRYPT_NOT_INPLACE
TRUE,
#endif
FALSE,
NULL,
crypt_zip_init,
crypt_zip_encode, crypt_zip_decode,
NULL, NULL,
crypt_zip_encode, crypt_zip_decode,
},
// Blowfish/CFB + SHA-256 custom key derivation; implementation issues.
{
"blowfish",
"VimCrypt~02!",
8,
8,
#ifdef CRYPT_NOT_INPLACE
TRUE,
#endif
FALSE,
blowfish_self_test,
crypt_blowfish_init,
crypt_blowfish_encode, crypt_blowfish_decode,
NULL, NULL,
crypt_blowfish_encode, crypt_blowfish_decode,
},
// Blowfish/CFB + SHA-256 custom key derivation; fixed.
{
"blowfish2",
"VimCrypt~03!",
8,
8,
#ifdef CRYPT_NOT_INPLACE
TRUE,
#endif
TRUE,
blowfish_self_test,
crypt_blowfish_init,
crypt_blowfish_encode, crypt_blowfish_decode,
NULL, NULL,
crypt_blowfish_encode, crypt_blowfish_decode,
},
// XChaCha20 using libsodium
{
"xchacha20",
"VimCrypt~04!",
#ifdef FEAT_SODIUM
crypto_pwhash_argon2id_SALTBYTES, // 16
#else
16,
#endif
8,
#ifdef CRYPT_NOT_INPLACE
FALSE,
#endif
FALSE,
NULL,
crypt_sodium_init,
NULL, NULL,
crypt_sodium_buffer_encode, crypt_sodiu