aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crypt.c280
-rw-r--r--src/crypt.h15
-rw-r--r--src/ex_docmd.c1
-rw-r--r--src/fileio.c1
-rw-r--r--src/main.c1
-rw-r--r--src/memline.c1
-rw-r--r--src/misc2.c276
-rw-r--r--src/misc2.h10
-rw-r--r--src/option.c1
-rw-r--r--src/undo.c1
10 files changed, 301 insertions, 286 deletions
diff --git a/src/crypt.c b/src/crypt.c
new file mode 100644
index 0000000000..21fd03b44a
--- /dev/null
+++ b/src/crypt.c
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+#include "vim.h"
+#include "misc2.h"
+#include "blowfish.h"
+#include "ex_getln.h"
+#include "message.h"
+#include "option.h"
+
+/* from zip.h */
+
+typedef unsigned short ush; /* unsigned 16-bit value */
+typedef unsigned long ulg; /* unsigned 32-bit value */
+
+static void make_crc_tab(void);
+
+static ulg crc_32_tab[256];
+
+/*
+ * Fill the CRC table.
+ */
+static void make_crc_tab(void) {
+ ulg 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) * (ulg)0xedb88320L);
+ crc_32_tab[t] = v;
+ }
+ done = TRUE;
+}
+
+#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+static ulg keys[3]; /* keys defining the pseudo-random sequence */
+
+/*
+ * Return the next byte in the pseudo-random sequence.
+ */
+#define DECRYPT_BYTE_ZIP(t) { \
+ ush temp; \
+ \
+ temp = (ush)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(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)); \
+}
+
+static int crypt_busy = 0;
+static ulg saved_keys[3];
+static int saved_crypt_method;
+
+/*
+ * Return int value for crypt method string:
+ * 0 for "zip", the old method. Also for any non-valid value.
+ * 1 for "blowfish".
+ */
+int crypt_method_from_string(char_u *s)
+{
+ return *s == 'b' ? 1 : 0;
+}
+
+/*
+ * Get the crypt method for buffer "buf" as a number.
+ */
+int get_crypt_method(buf_T *buf)
+{
+ return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
+}
+
+/*
+ * Set the crypt method for buffer "buf" to "method" using the int value as
+ * returned by crypt_method_from_string().
+ */
+void set_crypt_method(buf_T *buf, int method)
+{
+ free_string_option(buf->b_p_cm);
+ buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
+}
+
+/*
+ * Prepare for initializing encryption. If already doing encryption then save
+ * the state.
+ * Must always be called symmetrically with crypt_pop_state().
+ */
+void crypt_push_state(void) {
+ if (crypt_busy == 1) {
+ /* save the state */
+ if (use_crypt_method == 0) {
+ saved_keys[0] = keys[0];
+ saved_keys[1] = keys[1];
+ saved_keys[2] = keys[2];
+ } else
+ bf_crypt_save();
+ saved_crypt_method = use_crypt_method;
+ } else if (crypt_busy > 1)
+ EMSG2(_(e_intern2), "crypt_push_state()");
+ ++crypt_busy;
+}
+
+/*
+ * End encryption. If doing encryption before crypt_push_state() then restore
+ * the saved state.
+ * Must always be called symmetrically with crypt_push_state().
+ */
+void crypt_pop_state(void) {
+ --crypt_busy;
+ if (crypt_busy == 1) {
+ use_crypt_method = saved_crypt_method;
+ if (use_crypt_method == 0) {
+ keys[0] = saved_keys[0];
+ keys[1] = saved_keys[1];
+ keys[2] = saved_keys[2];
+ } else
+ bf_crypt_restore();
+ }
+}
+
+/*
+ * Encrypt "from[len]" into "to[len]".
+ * "from" and "to" can be equal to encrypt in place.
+ */
+void crypt_encode(char_u *from, size_t len, char_u *to)
+{
+ size_t i;
+ int ztemp, t;
+
+ if (use_crypt_method == 0)
+ for (i = 0; i < len; ++i) {
+ ztemp = from[i];
+ DECRYPT_BYTE_ZIP(t);
+ UPDATE_KEYS_ZIP(ztemp);
+ to[i] = t ^ ztemp;
+ }
+ else
+ bf_crypt_encode(from, len, to);
+}
+
+/*
+ * Decrypt "ptr[len]" in place.
+ */
+void crypt_decode(char_u *ptr, long len)
+{
+ char_u *p;
+
+ if (use_crypt_method == 0)
+ for (p = ptr; p < ptr + len; ++p) {
+ ush temp;
+
+ temp = (ush)keys[2] | 2;
+ temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
+ UPDATE_KEYS_ZIP(*p ^= temp);
+ }
+ else
+ bf_crypt_decode(ptr, len);
+}
+
+/*
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ * If "passwd" is NULL or empty, don't do anything.
+ */
+void
+crypt_init_keys (
+ char_u *passwd /* password string with which to modify keys */
+)
+{
+ if (passwd != NULL && *passwd != NUL) {
+ if (use_crypt_method == 0) {
+ char_u *p;
+
+ make_crc_tab();
+ keys[0] = 305419896L;
+ keys[1] = 591751049L;
+ keys[2] = 878082192L;
+ for (p = passwd; *p!= NUL; ++p) {
+ UPDATE_KEYS_ZIP((int)*p);
+ }
+ } else
+ bf_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(char_u *key)
+{
+ char_u *p;
+
+ if (key != NULL) {
+ for (p = key; *p != NUL; ++p)
+ *p = 0;
+ vim_free(key);
+ }
+}
+
+/*
+ * Ask the user for a crypt key.
+ * When "store" is TRUE, the new key is stored in the 'key' option, and the
+ * 'key' option value is returned: Don't free it.
+ * When "store" is FALSE, the typed key is returned in allocated memory.
+ * Returns NULL on failure.
+ */
+char_u *
+get_crypt_key (
+ int store,
+ int twice /* Ask for the key twice. */
+)
+{
+ char_u *p1, *p2 = NULL;
+ int round;
+
+ for (round = 0;; ++round) {
+ cmdline_star = TRUE;
+ cmdline_row = msg_row;
+ p1 = getcmdline_prompt(NUL, round == 0
+ ? (char_u *)_("Enter encryption key: ")
+ : (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
+ NULL);
+ cmdline_star = FALSE;
+
+ if (p1 == NULL)
+ break;
+
+ if (round == twice) {
+ if (p2 != NULL && STRCMP(p1, p2) != 0) {
+ MSG(_("Keys don't match!"));
+ free_crypt_key(p1);
+ free_crypt_key(p2);
+ p2 = NULL;
+ round = -1; /* do it again */
+ continue;
+ }
+
+ if (store) {
+ set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
+ free_crypt_key(p1);
+ p1 = curbuf->b_p_key;
+ }
+ break;
+ }
+ p2 = p1;
+ }
+
+ /* since the user typed this, no need to wait for return */
+ if (msg_didout)
+ msg_putchar('\n');
+ need_wait_return = FALSE;
+ msg_didout = FALSE;
+
+ free_crypt_key(p2);
+ return p1;
+}
+
diff --git a/src/crypt.h b/src/crypt.h
new file mode 100644
index 0000000000..4cbb5ba272
--- /dev/null
+++ b/src/crypt.h
@@ -0,0 +1,15 @@
+#ifndef NEOVIM_CRYPT_H
+#define NEOVIM_CRYPT_H
+
+int crypt_method_from_string(char_u *s);
+int get_crypt_method(buf_T *buf);
+void set_crypt_method(buf_T *buf, int method);
+void crypt_push_state(void);
+void crypt_pop_state(void);
+void crypt_encode(char_u *from, size_t len, char_u *to);
+void crypt_decode(char_u *ptr, long len);
+void crypt_init_keys(char_u *passwd);
+void free_crypt_key(char_u *key);
+char_u *get_crypt_key(int store, int twice);
+
+#endif /* NEOVIM_CRYPT_H */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 5f118c255c..9cf812a7f3 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -37,6 +37,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "file_search.h"
#include "garray.h"
#include "move.h"
diff --git a/src/fileio.c b/src/fileio.c
index 4613c7cf1a..6eddf06dc6 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -31,6 +31,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "garray.h"
#include "move.h"
#include "option.h"
diff --git a/src/main.c b/src/main.c
index e3f14707ca..13b1179711 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,6 +29,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "garray.h"
#include "move.h"
#include "normal.h"
diff --git a/src/memline.c b/src/memline.c
index 6fb29c2ddb..a75b70a992 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -55,6 +55,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "option.h"
#include "os_unix.h"
#include "screen.h"
diff --git a/src/misc2.c b/src/misc2.c
index 360524b0a0..a900078e2d 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2862,282 +2862,6 @@ int get_shape_idx(int mouse)
#endif /* CURSOR_SHAPE */
-
-/*
- * 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.
- *
- * 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 */
-
-typedef unsigned short ush; /* unsigned 16-bit value */
-typedef unsigned long ulg; /* unsigned 32-bit value */
-
-static void make_crc_tab(void);
-
-static ulg crc_32_tab[256];
-
-/*
- * Fill the CRC table.
- */
-static void make_crc_tab(void) {
- ulg 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) * (ulg)0xedb88320L);
- crc_32_tab[t] = v;
- }
- done = TRUE;
-}
-
-#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
-
-static ulg keys[3]; /* keys defining the pseudo-random sequence */
-
-/*
- * Return the next byte in the pseudo-random sequence.
- */
-#define DECRYPT_BYTE_ZIP(t) { \
- ush temp; \
- \
- temp = (ush)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(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)); \
-}
-
-static int crypt_busy = 0;
-static ulg saved_keys[3];
-static int saved_crypt_method;
-
-/*
- * Return int value for crypt method string:
- * 0 for "zip", the old method. Also for any non-valid value.
- * 1 for "blowfish".
- */
-int crypt_method_from_string(char_u *s)
-{
- return *s == 'b' ? 1 : 0;
-}
-
-/*
- * Get the crypt method for buffer "buf" as a number.
- */
-int get_crypt_method(buf_T *buf)
-{
- return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
-}
-
-/*
- * Set the crypt method for buffer "buf" to "method" using the int value as
- * returned by crypt_method_from_string().
- */
-void set_crypt_method(buf_T *buf, int method)
-{
- free_string_option(buf->b_p_cm);
- buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
-}
-
-/*
- * Prepare for initializing encryption. If already doing encryption then save
- * the state.
- * Must always be called symmetrically with crypt_pop_state().
- */
-void crypt_push_state(void) {
- if (crypt_busy == 1) {
- /* save the state */
- if (use_crypt_method == 0) {
- saved_keys[0] = keys[0];
- saved_keys[1] = keys[1];
- saved_keys[2] = keys[2];
- } else
- bf_crypt_save();
- saved_crypt_method = use_crypt_method;
- } else if (crypt_busy > 1)
- EMSG2(_(e_intern2), "crypt_push_state()");
- ++crypt_busy;
-}
-
-/*
- * End encryption. If doing encryption before crypt_push_state() then restore
- * the saved state.
- * Must always be called symmetrically with crypt_push_state().
- */
-void crypt_pop_state(void) {
- --crypt_busy;
- if (crypt_busy == 1) {
- use_crypt_method = saved_crypt_method;
- if (use_crypt_method == 0) {
- keys[0] = saved_keys[0];
- keys[1] = saved_keys[1];
- keys[2] = saved_keys[2];
- } else
- bf_crypt_restore();
- }
-}
-
-/*
- * Encrypt "from[len]" into "to[len]".
- * "from" and "to" can be equal to encrypt in place.
- */
-void crypt_encode(char_u *from, size_t len, char_u *to)
-{
- size_t i;
- int ztemp, t;
-
- if (use_crypt_method == 0)
- for (i = 0; i < len; ++i) {
- ztemp = from[i];
- DECRYPT_BYTE_ZIP(t);
- UPDATE_KEYS_ZIP(ztemp);
- to[i] = t ^ ztemp;
- }
- else
- bf_crypt_encode(from, len, to);
-}
-
-/*
- * Decrypt "ptr[len]" in place.
- */
-void crypt_decode(char_u *ptr, long len)
-{
- char_u *p;
-
- if (use_crypt_method == 0)
- for (p = ptr; p < ptr + len; ++p) {
- ush temp;
-
- temp = (ush)keys[2] | 2;
- temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
- UPDATE_KEYS_ZIP(*p ^= temp);
- }
- else
- bf_crypt_decode(ptr, len);
-}
-
-/*
- * Initialize the encryption keys and the random header according to
- * the given password.
- * If "passwd" is NULL or empty, don't do anything.
- */
-void
-crypt_init_keys (
- char_u *passwd /* password string with which to modify keys */
-)
-{
- if (passwd != NULL && *passwd != NUL) {
- if (use_crypt_method == 0) {
- char_u *p;
-
- make_crc_tab();
- keys[0] = 305419896L;
- keys[1] = 591751049L;
- keys[2] = 878082192L;
- for (p = passwd; *p!= NUL; ++p) {
- UPDATE_KEYS_ZIP((int)*p);
- }
- } else
- bf_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(char_u *key)
-{
- char_u *p;
-
- if (key != NULL) {
- for (p = key; *p != NUL; ++p)
- *p = 0;
- vim_free(key);
- }
-}
-
-/*
- * Ask the user for a crypt key.
- * When "store" is TRUE, the new key is stored in the 'key' option, and the
- * 'key' option value is returned: Don't free it.
- * When "store" is FALSE, the typed key is returned in allocated memory.
- * Returns NULL on failure.
- */
-char_u *
-get_crypt_key (
- int store,
- int twice /* Ask for the key twice. */
-)
-{
- char_u *p1, *p2 = NULL;
- int round;
-
- for (round = 0;; ++round) {
- cmdline_star = TRUE;
- cmdline_row = msg_row;
- p1 = getcmdline_prompt(NUL, round == 0
- ? (char_u *)_("Enter encryption key: ")
- : (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
- NULL);
- cmdline_star = FALSE;
-
- if (p1 == NULL)
- break;
-
- if (round == twice) {
- if (p2 != NULL && STRCMP(p1, p2) != 0) {
- MSG(_("Keys don't match!"));
- free_crypt_key(p1);
- free_crypt_key(p2);
- p2 = NULL;
- round = -1; /* do it again */
- continue;
- }
-
- if (store) {
- set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
- free_crypt_key(p1);
- p1 = curbuf->b_p_key;
- }
- break;
- }
- p2 = p1;
- }
-
- /* since the user typed this, no need to wait for return */
- if (msg_didout)
- msg_putchar('\n');
- need_wait_return = FALSE;
- msg_didout = FALSE;
-
- free_crypt_key(p2);
- return p1;
-}
-
-
/*
* Change directory to "new_dir". If FEAT_SEARCHPATH is defined, search
* 'cdpath' for relative directory names, otherwise just mch_chdir().
diff --git a/src/misc2.h b/src/misc2.h
index 0e3e6af2ed..bcb3e0dd0c 100644
--- a/src/misc2.h
+++ b/src/misc2.h
@@ -81,16 +81,6 @@ int illegal_slash(char *name);
char_u *parse_shape_opt(int what);
int get_shape_idx(int mouse);
void update_mouseshape(int shape_idx);
-int crypt_method_from_string(char_u *s);
-int get_crypt_method(buf_T *buf);
-void set_crypt_method(buf_T *buf, int method);
-void crypt_push_state(void);
-void crypt_pop_state(void);
-void crypt_encode(char_u *from, size_t len, char_u *to);
-void crypt_decode(char_u *ptr, long len);
-void crypt_init_keys(char_u *passwd);
-void free_crypt_key(char_u *key);
-char_u *get_crypt_key(int store, int twice);
int vim_chdir(char_u *new_dir);
int get_user_name(char_u *buf, int len);
void sort_strings(char_u **files, int count);
diff --git a/src/option.c b/src/option.c
index 127e417e47..5a78777916 100644
--- a/src/option.c
+++ b/src/option.c
@@ -53,6 +53,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "garray.h"
#include "move.h"
#include "normal.h"
diff --git a/src/undo.c b/src/undo.c
index 87adf3f9bc..62984b5c76 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -92,6 +92,7 @@
#include "message.h"
#include "misc1.h"
#include "misc2.h"
+#include "crypt.h"
#include "garray.h"
#include "option.h"
#include "os_unix.h"