]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Implement my experimental arcfour modes. The 256-bit version is disabled
authorBen Harris <bjh21@bjh21.me.uk>
Thu, 14 Apr 2005 22:58:29 +0000 (22:58 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Thu, 14 Apr 2005 22:58:29 +0000 (22:58 +0000)
until I can test it against someone else's implementation.

[originally from svn r5633]

Recipe
config.c
doc/config.but
doc/errors.but
doc/index.but
putty.h
settings.c
ssh.c
ssh.h
ssharcf.c [new file with mode: 0644]

diff --git a/Recipe b/Recipe
index 4c8a05924040fda1db1ccc4b7941fddd440933fe..f0facd6edc107203d0f7c3f52ae110d37e4ac004 100644 (file)
--- 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
index 8a4719537a43fe85f2b53431f6cf8bf10a4eb705..638e3d8dac59894ce8f306b0561078b02a978b84 100644 (file)
--- 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 }
        };
 
index bd92b96f3cddde623bace267871436dffde2f6ad..72fd59f17cea4338ffe2fb78f0ea1cc61d191fca 100644 (file)
@@ -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
index bc352ce5792485e600231f6e63c742a282685ce6..f3fa117b80329de7ff9f1e4b46d876931e5b71c2 100644 (file)
@@ -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.
 
index 963eed1eaaed2599b3d3663fd708da2589bfbbc2..ba01c8f051286f582f5ec48117bed3f853903c79 100644 (file)
@@ -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 fd8e13d6e00775f5631345dfde1ad27ab791104c..b08eec8147eb989e4f144743739f6b321f454b3d 100644 (file)
--- 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) */
 };
 
index 11efd751aed50199fd5c9bdcf2549595a65a1104..9dce4f8c79e96ea237a19c5da35853072eb78281 100644 (file)
@@ -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 b5f34a52afcb738a4ab83455d50894feae859d4e..8c7f7757125bcf8b655fbf3ae6e78d376faafac8 100644 (file)
--- 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 bf1ba48b8962bcc18b8d4a3dc76a1db82f64d62a..87011e97ff6b6da12413b11c88182264c845484e 100644 (file)
--- 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 (file)
index 0000000..5946488
--- /dev/null
+++ b/ssharcf.c
@@ -0,0 +1,127 @@
+/*
+ * Arcfour (RC4) implementation for PuTTY.
+ *
+ * Coded from Schneier.
+ */
+
+#include <assert.h>
+#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
+};