From a2add20851e01de1e69564250aec54f193f742b3 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 14 Apr 2005 22:58:29 +0000 Subject: [PATCH] Implement my experimental arcfour modes. The 256-bit version is disabled until I can test it against someone else's implementation. git-svn-id: svn://svn.tartarus.org/sgt/putty@5633 cda61777-01e9-0310-a592-d414129be87e --- Recipe | 2 +- config.c | 1 + doc/config.but | 2 + doc/errors.but | 2 +- doc/index.but | 3 ++ putty.h | 1 + settings.c | 1 + ssh.c | 3 ++ ssh.h | 1 + ssharcf.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 ssharcf.c diff --git a/Recipe b/Recipe index 4c8a0592..f0facd6e 100644 --- a/Recipe +++ b/Recipe @@ -205,7 +205,7 @@ NONSSH = telnet raw rlogin ldisc pinger # SSH back end (putty, plink, pscp, psftp). SSH = ssh sshcrc sshdes sshmd5 sshrsa sshrand sshsha sshblowf + sshdh sshcrcda sshpubk sshzlib sshdss x11fwd portfwd - + sshaes sshsh512 sshbn wildcard pinger + + sshaes sshsh512 sshbn wildcard pinger ssharcf WINSSH = SSH winnoise winpgntc UXSSH = SSH uxnoise uxagentc MACSSH = SSH macnoise diff --git a/config.c b/config.c index 8a471953..638e3d8d 100644 --- a/config.c +++ b/config.c @@ -120,6 +120,7 @@ static void cipherlist_handler(union control *ctrl, void *dlg, { "Blowfish", CIPHER_BLOWFISH }, { "DES", CIPHER_DES }, { "AES (SSH-2 only)", CIPHER_AES }, + { "Arcfour (SSH-2 only)", CIPHER_ARCFOUR }, { "-- warn below here --", CIPHER_WARN } }; diff --git a/doc/config.but b/doc/config.but index bd92b96f..72fd59f1 100644 --- a/doc/config.but +++ b/doc/config.but @@ -2127,6 +2127,8 @@ PuTTY currently supports the following algorithms: \b \i{AES} (Rijndael) - 256, 192, or 128-bit CBC (SSH-2 only) +\b \i{Arcfour} (RC4) - 256 or 128-bit stream cipher (SSH-2 only) + \b \i{Blowfish} - 128-bit CBC \b \ii{Triple-DES} - 168-bit CBC diff --git a/doc/errors.but b/doc/errors.but index bc352ce5..f3fa117b 100644 --- a/doc/errors.but +++ b/doc/errors.but @@ -74,7 +74,7 @@ this, let us know and we'll move it up our priority list. This occurs when the SSH server does not offer any ciphers which you have configured PuTTY to consider strong enough. By default, PuTTY -puts up this warning only for \ii{single-DES} encryption. +puts up this warning only for \ii{single-DES} and \i{Arcfour} encryption. See \k{config-ssh-encryption} for more information on this message. diff --git a/doc/index.but b/doc/index.but index 963eed1e..ba01c8f0 100644 --- a/doc/index.but +++ b/doc/index.but @@ -595,6 +595,9 @@ saved sessions from \IM{AES} Advanced Encryption Standard \IM{AES} Rijndael +\IM{Arcfour} Arcfour +\IM{Arcfour} RC4 + \IM{triple-DES} triple-DES \IM{single-DES} single-DES diff --git a/putty.h b/putty.h index fd8e13d6..b08eec81 100644 --- a/putty.h +++ b/putty.h @@ -261,6 +261,7 @@ enum { CIPHER_BLOWFISH, CIPHER_AES, /* (SSH-2 only) */ CIPHER_DES, + CIPHER_ARCFOUR, CIPHER_MAX /* no. ciphers (inc warn) */ }; diff --git a/settings.c b/settings.c index 11efd751..9dce4f8c 100644 --- a/settings.c +++ b/settings.c @@ -18,6 +18,7 @@ static const struct keyval ciphernames[] = { { "blowfish", CIPHER_BLOWFISH }, { "3des", CIPHER_3DES }, { "WARN", CIPHER_WARN }, + { "arcfour", CIPHER_ARCFOUR }, { "des", CIPHER_DES } }; diff --git a/ssh.c b/ssh.c index b5f34a52..8c7f7757 100644 --- a/ssh.c +++ b/ssh.c @@ -4915,6 +4915,9 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, case CIPHER_AES: s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes; break; + case CIPHER_ARCFOUR: + s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour; + break; case CIPHER_WARN: /* Flag for later. Don't bother if it's the last in * the list. */ diff --git a/ssh.h b/ssh.h index bf1ba48b..87011e97 100644 --- a/ssh.h +++ b/ssh.h @@ -233,6 +233,7 @@ extern const struct ssh2_ciphers ssh2_3des; extern const struct ssh2_ciphers ssh2_des; extern const struct ssh2_ciphers ssh2_aes; extern const struct ssh2_ciphers ssh2_blowfish; +extern const struct ssh2_ciphers ssh2_arcfour; extern const struct ssh_kex ssh_diffiehellman_group1; extern const struct ssh_kex ssh_diffiehellman_group14; extern const struct ssh_kex ssh_diffiehellman_gex; diff --git a/ssharcf.c b/ssharcf.c new file mode 100644 index 00000000..59464881 --- /dev/null +++ b/ssharcf.c @@ -0,0 +1,127 @@ +/* + * Arcfour (RC4) implementation for PuTTY. + * + * Coded from Schneier. + */ + +#include +#include "ssh.h" + +typedef struct { + unsigned char i, j, s[256]; +} ArcfourContext; + +static void arcfour_block(void *handle, unsigned char *blk, int len) +{ + ArcfourContext *ctx = (ArcfourContext *)handle; + unsigned k; + unsigned char tmp, i, j, *s; + + s = ctx->s; + i = ctx->i; j = ctx->j; + for (k = 0; k < len; k++) { + i = (i + 1) & 0xff; + j = (j + s[i]) & 0xff; + tmp = s[i]; s[i] = s[j]; s[j] = tmp; + blk[k] ^= s[(s[i]+s[j]) & 0xff]; + } + ctx->i = i; ctx->j = j; +} + +static void arcfour_setkey(ArcfourContext *ctx, unsigned char const *key, + unsigned keybytes) +{ + unsigned char tmp, k[256], *s; + unsigned i, j; + + s = ctx->s; + assert(keybytes <= 256); + ctx->i = ctx->j = 0; + for (i = 0; i < 256; i++) { + s[i] = i; + k[i] = key[i % keybytes]; + } + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + k[i]) & 0xff; + tmp = s[i]; s[i] = s[j]; s[j] = tmp; + } +} + +/* -- Interface with PuTTY -- */ + +/* + * We don't implement Arcfour in SSH-1 because it's utterly insecure in + * several ways. See CERT Vulnerability Notes VU#25309, VU#665372, + * and VU#565052. + * + * We don't implement the "arcfour" algorithm in SSH-2 because it doesn't + * stir the cipher state before emitting keystream, and hence is likely + * to leak data about the key. + */ + +static void *arcfour_make_context(void) +{ + return snew(ArcfourContext); +} + +static void arcfour_free_context(void *handle) +{ + sfree(handle); +} + +static void arcfour_stir(ArcfourContext *ctx) +{ + unsigned char *junk = snewn(1536, unsigned char); + memset(junk, 0, 1536); + arcfour_block(ctx, junk, 1536); + memset(junk, 0, 1536); + sfree(junk); +} + +static void arcfour128_key(void *handle, unsigned char *key) +{ + ArcfourContext *ctx = (ArcfourContext *)handle; + arcfour_setkey(ctx, key, 16); + arcfour_stir(ctx); +} + +static void arcfour256_key(void *handle, unsigned char *key) +{ + ArcfourContext *ctx = (ArcfourContext *)handle; + arcfour_setkey(ctx, key, 32); + arcfour_stir(ctx); +} + +static void arcfour_iv(void *handle, unsigned char *key) +{ + +} + +const struct ssh2_cipher ssh_arcfour128_ssh2 = { + arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key, + arcfour_block, arcfour_block, + "arcfour128-draft-00@putty.projects.tartarus.org", + 1, 128, "Arcfour-128" +}; + +const struct ssh2_cipher ssh_arcfour256_ssh2 = { + arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key, + arcfour_block, arcfour_block, + "arcfour256-draft-00@putty.projects.tartarus.org", + 1, 256, "Arcfour-256" +}; + +/* + * arcfour256-draft-00@putty.projects.tartarus.org is as-yet untested + * against any other implementation, and hence is commented out. + */ +static const struct ssh2_cipher *const arcfour_list[] = { +/* &ssh_arcfour256_ssh2, */ + &ssh_arcfour128_ssh2, +}; + +const struct ssh2_ciphers ssh2_arcfour = { + sizeof(arcfour_list) / sizeof(*arcfour_list), + arcfour_list +}; -- 2.11.0