Skip to content
This repository has been archived by the owner on Feb 19, 2021. It is now read-only.

Commit

Permalink
Support for selecting AES from the GUI. In the process, I've had to
Browse files Browse the repository at this point in the history
introduce another layer of abstraction in SSH2 ciphers, such that a
single `logical cipher' (as desired by a user) can equate to more
than one `physical cipher'. This is because AES comes in several key
lengths (PuTTY will pick the highest supported by the remote end)
and several different SSH2-protocol-level names (aes*-cbc,
rijndael*-cbc, and an unofficial one rijndael-cbc@lysator.liu.se).


git-svn-id: svn://svn.tartarus.org/sgt/putty@967 cda61777-01e9-0310-a592-d414129be87e
  • Loading branch information
simon committed Mar 2, 2001
1 parent 8479e33 commit 0a3f1d4
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 89 deletions.
2 changes: 1 addition & 1 deletion putty.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ typedef struct {
int nopty;
int compression;
int agentfwd;
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES, CIPHER_AES } cipher;
char keyfile[FILENAME_MAX];
int sshprot; /* use v1 or v2 when both available */
int buggymac; /* MAC bug commmercial <=v2.3.x SSH2 */
Expand Down
9 changes: 7 additions & 2 deletions settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,11 @@ void save_settings (char *section, int do_host, Config *cfg) {
write_setting_i (sesskey, "Compression", cfg->compression);
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
write_setting_s (sesskey, "RemoteCmd", cfg->remote_cmd);
write_setting_s (sesskey, "Cipher", cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
cfg->cipher == CIPHER_DES ? "des" : "3des");
write_setting_s (sesskey, "Cipher",
cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
cfg->cipher == CIPHER_DES ? "des" :
cfg->cipher == CIPHER_AES ? "aes" :
"3des");
write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
write_setting_i (sesskey, "SshProt", cfg->sshprot);
write_setting_i (sesskey, "BuggyMAC", cfg->buggymac);
Expand Down Expand Up @@ -218,6 +221,8 @@ void load_settings (char *section, int do_host, Config *cfg) {
cfg->cipher = CIPHER_BLOWFISH;
else if (!strcmp(cipher, "des"))
cfg->cipher = CIPHER_DES;
else if (!strcmp(cipher, "aes"))
cfg->cipher = CIPHER_AES;
else
cfg->cipher = CIPHER_3DES;
}
Expand Down
96 changes: 56 additions & 40 deletions ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,11 @@ enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM };
#define crWaitUntilV(c) do { crReturnV; } while (!(c))

extern const struct ssh_cipher ssh_3des;
extern const struct ssh_cipher ssh_3des_ssh2;
extern const struct ssh2_ciphers ssh2_3des;
extern const struct ssh_cipher ssh_des;
extern const struct ssh_cipher ssh_aes128_ssh2;
extern const struct ssh_cipher ssh_aes192_ssh2;
extern const struct ssh_cipher ssh_aes256_ssh2;
extern const struct ssh2_ciphers ssh2_aes;
extern const struct ssh_cipher ssh_blowfish_ssh1;
extern const struct ssh_cipher ssh_blowfish_ssh2;
extern const struct ssh2_ciphers ssh2_blowfish;

extern char *x11_init (Socket *, char *, void *);
extern void x11_close (Socket);
Expand All @@ -184,12 +182,10 @@ extern void x11_invent_auth(char *, int, char *, int);
* SSH1. (3DES uses outer chaining; Blowfish has the opposite
* endianness and different-sized keys.)
*/
const static struct ssh_cipher *ciphers[] = {
&ssh_aes256_ssh2,
&ssh_aes192_ssh2,
&ssh_aes128_ssh2,
&ssh_blowfish_ssh2,
&ssh_3des_ssh2
const static struct ssh2_ciphers *ciphers[] = {
&ssh2_aes,
&ssh2_blowfish,
&ssh2_3des,
};

extern const struct ssh_kex ssh_diffiehellman;
Expand Down Expand Up @@ -278,8 +274,8 @@ static int ssh1_compressing;
static int ssh_agentfwd_enabled;
static int ssh_X11_fwd_enabled;
static const struct ssh_cipher *cipher = NULL;
static const struct ssh_cipher *cscipher = NULL;
static const struct ssh_cipher *sccipher = NULL;
static const struct ssh2_cipher *cscipher = NULL;
static const struct ssh2_cipher *sccipher = NULL;
static const struct ssh_mac *csmac = NULL;
static const struct ssh_mac *scmac = NULL;
static const struct ssh_compress *cscomp = NULL;
Expand Down Expand Up @@ -1396,9 +1392,15 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)

logevent("Encrypted session key");

cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH :
cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES :
SSH_CIPHER_3DES;
switch (cfg.cipher) {
case CIPHER_BLOWFISH: cipher_type = SSH_CIPHER_BLOWFISH; break;
case CIPHER_DES: cipher_type = SSH_CIPHER_DES; break;
case CIPHER_3DES: cipher_type = SSH_CIPHER_3DES; break;
case CIPHER_AES:
c_write("AES not supported in SSH1, falling back to 3DES\r\n", 49);
cipher_type = SSH_CIPHER_3DES;
break;
}
if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
c_write("Selected cipher not supported, falling back to 3DES\r\n", 53);
cipher_type = SSH_CIPHER_3DES;
Expand Down Expand Up @@ -2181,14 +2183,14 @@ static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr, char *keyspace
*/
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
{
static int i, len, nbits;
static int i, j, len, nbits;
static char *str;
static Bignum p, g, e, f, K;
static int kex_init_value, kex_reply_value;
static const struct ssh_mac **maclist;
static int nmacs;
static const struct ssh_cipher *cscipher_tobe = NULL;
static const struct ssh_cipher *sccipher_tobe = NULL;
static const struct ssh2_cipher *cscipher_tobe = NULL;
static const struct ssh2_cipher *sccipher_tobe = NULL;
static const struct ssh_mac *csmac_tobe = NULL;
static const struct ssh_mac *scmac_tobe = NULL;
static const struct ssh_compress *cscomp_tobe = NULL;
Expand All @@ -2199,7 +2201,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
static unsigned char exchange_hash[20];
static unsigned char first_exchange_hash[20];
static unsigned char keyspace[40];
static const struct ssh_cipher *preferred_cipher;
static const struct ssh2_ciphers *preferred_cipher;
static const struct ssh_compress *preferred_comp;
static int first_kex;

Expand All @@ -2211,15 +2213,17 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
* Set up the preferred cipher and compression.
*/
if (cfg.cipher == CIPHER_BLOWFISH) {
preferred_cipher = &ssh_blowfish_ssh2;
preferred_cipher = &ssh2_blowfish;
} else if (cfg.cipher == CIPHER_DES) {
logevent("Single DES not supported in SSH2; using 3DES");
preferred_cipher = &ssh_3des_ssh2;
preferred_cipher = &ssh2_3des;
} else if (cfg.cipher == CIPHER_3DES) {
preferred_cipher = &ssh_3des_ssh2;
preferred_cipher = &ssh2_3des;
} else if (cfg.cipher == CIPHER_AES) {
preferred_cipher = &ssh2_aes;
} else {
/* Shouldn't happen, but we do want to initialise to _something_. */
preferred_cipher = &ssh_3des_ssh2;
preferred_cipher = &ssh2_3des;
}
if (cfg.compression)
preferred_comp = &ssh_zlib;
Expand Down Expand Up @@ -2258,18 +2262,22 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
/* List client->server encryption algorithms. */
ssh2_pkt_addstring_start();
for (i = 0; i < lenof(ciphers)+1; i++) {
const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
ssh2_pkt_addstring_str(c->name);
if (i < lenof(ciphers))
ssh2_pkt_addstring_str(",");
const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1];
for (j = 0; j < c->nciphers; j++) {
ssh2_pkt_addstring_str(c->list[j]->name);
if (i < lenof(ciphers) || j < c->nciphers-1)
ssh2_pkt_addstring_str(",");
}
}
/* List server->client encryption algorithms. */
ssh2_pkt_addstring_start();
for (i = 0; i < lenof(ciphers)+1; i++) {
const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
ssh2_pkt_addstring_str(c->name);
if (i < lenof(ciphers))
ssh2_pkt_addstring_str(",");
const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1];
for (j = 0; j < c->nciphers; j++) {
ssh2_pkt_addstring_str(c->list[j]->name);
if (i < lenof(ciphers) || j < c->nciphers-1)
ssh2_pkt_addstring_str(",");
}
}
/* List client->server MAC algorithms. */
ssh2_pkt_addstring_start();
Expand Down Expand Up @@ -2345,19 +2353,27 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
}
ssh2_pkt_getstring(&str, &len); /* client->server cipher */
for (i = 0; i < lenof(ciphers)+1; i++) {
const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
if (in_commasep_string(c->name, str, len)) {
cscipher_tobe = c;
break;
const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1];
for (j = 0; j < c->nciphers; j++) {
if (in_commasep_string(c->list[j]->name, str, len)) {
cscipher_tobe = c->list[j];
break;
}
}
if (cscipher_tobe)
break;
}
ssh2_pkt_getstring(&str, &len); /* server->client cipher */
for (i = 0; i < lenof(ciphers)+1; i++) {
const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
if (in_commasep_string(c->name, str, len)) {
sccipher_tobe = c;
break;
const struct ssh2_ciphers *c = i==0 ? preferred_cipher : ciphers[i-1];
for (j = 0; j < c->nciphers; j++) {
if (in_commasep_string(c->list[j]->name, str, len)) {
sccipher_tobe = c->list[j];
break;
}
}
if (sccipher_tobe)
break;
}
ssh2_pkt_getstring(&str, &len); /* client->server mac */
for (i = 0; i < nmacs; i++) {
Expand Down
11 changes: 11 additions & 0 deletions ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ void SHA_Simple(void *p, int len, unsigned char *output);

struct ssh_cipher {
void (*sesskey)(unsigned char *key); /* for ssh 1 */
void (*encrypt)(unsigned char *blk, int len);
void (*decrypt)(unsigned char *blk, int len);
int blksize;
};

struct ssh2_cipher {
void (*setcsiv)(unsigned char *key); /* for ssh 2 */
void (*setcskey)(unsigned char *key); /* for ssh 2 */
void (*setsciv)(unsigned char *key); /* for ssh 2 */
Expand All @@ -106,6 +112,11 @@ struct ssh_cipher {
int keylen;
};

struct ssh2_ciphers {
int nciphers;
struct ssh2_cipher **list;
};

struct ssh_mac {
void (*setcskey)(unsigned char *key);
void (*setsckey)(unsigned char *key);
Expand Down
77 changes: 48 additions & 29 deletions sshaes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1023,8 +1023,7 @@ static void aes_ssh2_decrypt_blk(unsigned char *blk, int len) {
aes_decrypt_cbc(blk, len, &scctx);
}

struct ssh_cipher ssh_aes128_ssh2 = {
NULL,
static struct ssh2_cipher ssh_aes128 = {
aes_csiv, aes128_cskey,
aes_sciv, aes128_sckey,
aes_ssh2_encrypt_blk,
Expand All @@ -1033,8 +1032,7 @@ struct ssh_cipher ssh_aes128_ssh2 = {
16, 128
};

struct ssh_cipher ssh_aes192_ssh2 = {
NULL,
static struct ssh2_cipher ssh_aes192 = {
aes_csiv, aes192_cskey,
aes_sciv, aes192_sckey,
aes_ssh2_encrypt_blk,
Expand All @@ -1043,8 +1041,7 @@ struct ssh_cipher ssh_aes192_ssh2 = {
16, 192
};

struct ssh_cipher ssh_aes256_ssh2 = {
NULL,
static struct ssh2_cipher ssh_aes256 = {
aes_csiv, aes256_cskey,
aes_sciv, aes256_sckey,
aes_ssh2_encrypt_blk,
Expand All @@ -1053,31 +1050,53 @@ struct ssh_cipher ssh_aes256_ssh2 = {
16, 256
};

#ifdef TESTMODE
static struct ssh2_cipher ssh_rijndael128 = {
aes_csiv, aes128_cskey,
aes_sciv, aes128_sckey,
aes_ssh2_encrypt_blk,
aes_ssh2_decrypt_blk,
"rijndael128-cbc",
16, 128
};

#include <stdio.h>
static struct ssh2_cipher ssh_rijndael192 = {
aes_csiv, aes192_cskey,
aes_sciv, aes192_sckey,
aes_ssh2_encrypt_blk,
aes_ssh2_decrypt_blk,
"rijndael192-cbc",
16, 192
};

int main(void) {
AESContext c;
static unsigned char key[32] = {};
word32 block[32];
int i, j, k;
static struct ssh2_cipher ssh_rijndael256 = {
aes_csiv, aes256_cskey,
aes_sciv, aes256_sckey,
aes_ssh2_encrypt_blk,
aes_ssh2_decrypt_blk,
"rijndael256-cbc",
16, 256
};

for (i = 16; i <= 32; i += 8) {
for (j = 16; j <= 32; j += 8) {
printf("b%d, k%d: ", i, j);
fflush(stdout);
aes_setup(&c, i, key, j);
memset(block, 0, sizeof(block));
aes_encrypt(&c, block);
aes_decrypt(&c, block);
for (k = 0; k < i/4; k++)
printf("%08x ", block[k]);
printf("\n");
}
}
static struct ssh2_cipher ssh_rijndael_lysator = {
aes_csiv, aes256_cskey,
aes_sciv, aes256_sckey,
aes_ssh2_encrypt_blk,
aes_ssh2_decrypt_blk,
"rijndael-cbc@lysator.liu.se",
16, 256
};

return 0;
}
static struct ssh2_cipher *aes_list[] = {
&ssh_aes256,
&ssh_rijndael256,
&ssh_rijndael_lysator,
&ssh_aes192,
&ssh_rijndael192,
&ssh_aes128,
&ssh_rijndael128,
};

#endif
struct ssh2_ciphers ssh2_aes = {
sizeof(aes_list) / sizeof(*aes_list),
aes_list
};
17 changes: 11 additions & 6 deletions sshblowf.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,20 +509,25 @@ static void blowfish_ssh2_decrypt_blk(unsigned char *blk, int len)

struct ssh_cipher ssh_blowfish_ssh1 = {
blowfish_sesskey,
blowfish_csiv, blowfish_cskey,
blowfish_sciv, blowfish_sckey,
blowfish_ssh1_encrypt_blk,
blowfish_ssh1_decrypt_blk,
"blowfish-cbc",
8, 256
8
};

struct ssh_cipher ssh_blowfish_ssh2 = {
blowfish_sesskey,
static struct ssh2_cipher ssh_blowfish_ssh2 = {
blowfish_csiv, blowfish_cskey,
blowfish_sciv, blowfish_sckey,
blowfish_ssh2_encrypt_blk,
blowfish_ssh2_decrypt_blk,
"blowfish-cbc",
8, 128
};

static struct ssh2_cipher *blowfish_list[] = {
&ssh_blowfish_ssh2
};

struct ssh2_ciphers ssh2_blowfish = {
sizeof(blowfish_list) / sizeof(*blowfish_list),
blowfish_list
};
Loading

0 comments on commit 0a3f1d4

Please sign in to comment.