From 371e569c350575d3f9b41c71e2ff51de9ef62483 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 25 Oct 2002 12:35:22 +0000 Subject: [PATCH] SSH ciphers now use dynamically allocated contexts. git-svn-id: svn://svn.tartarus.org/sgt/putty@2130 cda61777-01e9-0310-a592-d414129be87e --- ssh.c | 50 +++++++++++++---- ssh.h | 22 +++++--- sshaes.c | 114 ++++++++++++++----------------------- sshblowf.c | 81 +++++++++++++++------------ sshdes.c | 186 +++++++++++++++++++++++++++++++------------------------------ 5 files changed, 236 insertions(+), 217 deletions(-) diff --git a/ssh.c b/ssh.c index 115e902f..c8ba298d 100644 --- a/ssh.c +++ b/ssh.c @@ -550,7 +550,9 @@ struct ssh_tag { int X11_fwd_enabled; int remote_bugs; const struct ssh_cipher *cipher; + void *v1_cipher_ctx; const struct ssh2_cipher *cscipher, *sccipher; + void *cs_cipher_ctx, *sc_cipher_ctx; const struct ssh_mac *csmac, *scmac; const struct ssh_compress *cscomp, *sccomp; const struct ssh_kex *kex; @@ -803,7 +805,7 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen) } if (ssh->cipher) - ssh->cipher->decrypt(ssh->pktin.data, st->biglen); + ssh->cipher->decrypt(ssh->v1_cipher_ctx, ssh->pktin.data, st->biglen); st->realcrc = crc32(ssh->pktin.data, st->biglen - 4); st->gotcrc = GET_32BIT(ssh->pktin.data + st->biglen - 4); @@ -917,7 +919,8 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) } if (ssh->sccipher) - ssh->sccipher->decrypt(ssh->pktin.data, st->cipherblk); + ssh->sccipher->decrypt(ssh->sc_cipher_ctx, + ssh->pktin.data, st->cipherblk); /* * Now get the length and padding figures. @@ -968,7 +971,8 @@ static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen) } /* Decrypt everything _except_ the MAC. */ if (ssh->sccipher) - ssh->sccipher->decrypt(ssh->pktin.data + st->cipherblk, + ssh->sccipher->decrypt(ssh->sc_cipher_ctx, + ssh->pktin.data + st->cipherblk, st->packetlen - st->cipherblk); /* @@ -1172,7 +1176,7 @@ static int s_wrpkt_prepare(Ssh ssh) PUT_32BIT(ssh->pktout.data, len); if (ssh->cipher) - ssh->cipher->encrypt(ssh->pktout.data + 4, biglen); + ssh->cipher->encrypt(ssh->v1_cipher_ctx, ssh->pktout.data + 4, biglen); return biglen + 4; } @@ -1469,7 +1473,8 @@ static int ssh2_pkt_construct(Ssh ssh) ssh->v2_outgoing_sequence++; /* whether or not we MACed */ if (ssh->cscipher) - ssh->cscipher->encrypt(ssh->pktout.data, ssh->pktout.length + padding); + ssh->cscipher->encrypt(ssh->cs_cipher_ctx, + ssh->pktout.data, ssh->pktout.length + padding); /* Ready-to-send packet starts at ssh->pktout.data. We return length. */ return ssh->pktout.length + padding + maclen; @@ -2353,7 +2358,13 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 : s->cipher_type == SSH_CIPHER_DES ? &ssh_des : &ssh_3des); - ssh->cipher->sesskey(ssh->session_key); + ssh->v1_cipher_ctx = ssh->cipher->make_context(); + ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key); + { + char buf[256]; + sprintf(buf, "Initialised %.200s encryption", ssh->cipher->text_name); + logevent(buf); + } crWaitUntil(ispkt); @@ -4016,8 +4027,14 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) /* * Create and initialise session keys. */ + if (ssh->cs_cipher_ctx) + ssh->cscipher->free_context(ssh->cs_cipher_ctx); ssh->cscipher = s->cscipher_tobe; + ssh->cs_cipher_ctx = ssh->cscipher->make_context(); + if (ssh->sc_cipher_ctx) + ssh->sccipher->free_context(ssh->sc_cipher_ctx); ssh->sccipher = s->sccipher_tobe; + ssh->sc_cipher_ctx = ssh->sccipher->make_context(); ssh->csmac = s->csmac_tobe; ssh->scmac = s->scmac_tobe; ssh->cscomp = s->cscomp_tobe; @@ -4034,18 +4051,28 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) memcpy(ssh->v2_session_id, s->exchange_hash, sizeof(s->exchange_hash)); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'C',keyspace); - ssh->cscipher->setcskey(keyspace); + ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'D',keyspace); - ssh->sccipher->setsckey(keyspace); + ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'A',keyspace); - ssh->cscipher->setcsiv(keyspace); + ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'B',keyspace); - ssh->sccipher->setsciv(keyspace); + ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'E',keyspace); ssh->csmac->setcskey(keyspace); ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'F',keyspace); ssh->scmac->setsckey(keyspace); } + { + char buf[256]; + sprintf(buf, "Initialised %.200s client->server encryption", + ssh->cscipher->text_name); + logevent(buf); + sprintf(buf, "Initialised %.200s server->client encryption", + ssh->sccipher->text_name); + logevent(buf); + } + /* * If this is the first key exchange phase, we must pass the @@ -5752,8 +5779,11 @@ static char *ssh_init(void *frontend_handle, void **backend_handle, ssh = smalloc(sizeof(*ssh)); ssh->s = NULL; ssh->cipher = NULL; + ssh->v1_cipher_ctx = NULL; ssh->cscipher = NULL; + ssh->cs_cipher_ctx = NULL; ssh->sccipher = NULL; + ssh->sc_cipher_ctx = NULL; ssh->csmac = NULL; ssh->scmac = NULL; ssh->cscomp = NULL; diff --git a/ssh.h b/ssh.h index 59a7b460..a99b6336 100644 --- a/ssh.h +++ b/ssh.h @@ -123,22 +123,26 @@ void SHA512_Final(SHA512_State * s, unsigned char *output); void SHA512_Simple(const 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); + void *(*make_context)(void); + void (*free_context)(void *); + void (*sesskey) (void *, unsigned char *key); /* for ssh 1 */ + void (*encrypt) (void *, unsigned char *blk, int len); + void (*decrypt) (void *, unsigned char *blk, int len); int blksize; + char *text_name; }; 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 */ - void (*setsckey) (unsigned char *key); /* for ssh 2 */ - void (*encrypt) (unsigned char *blk, int len); - void (*decrypt) (unsigned char *blk, int len); + void *(*make_context)(void); + void (*free_context)(void *); + void (*setiv) (void *, unsigned char *key); /* for ssh 2 */ + void (*setkey) (void *, unsigned char *key);/* for ssh 2 */ + void (*encrypt) (void *, unsigned char *blk, int len); + void (*decrypt) (void *, unsigned char *blk, int len); char *name; int blksize; int keylen; + char *text_name; }; struct ssh2_ciphers { diff --git a/sshaes.c b/sshaes.c index 01dd04c2..1dfb5f92 100644 --- a/sshaes.c +++ b/sshaes.c @@ -1086,66 +1086,52 @@ static void aes_decrypt_cbc(unsigned char *blk, int len, AESContext * ctx) memcpy(ctx->iv, iv, sizeof(iv)); } -static AESContext csctx, scctx; - -static void aes128_cskey(unsigned char *key) +static void *aes_make_context(void) { - aes_setup(&csctx, 16, key, 16); - logevent("Initialised AES-128 client->server encryption"); + return smalloc(sizeof(AESContext)); } -static void aes128_sckey(unsigned char *key) +static void aes_free_context(void *handle) { - aes_setup(&scctx, 16, key, 16); - logevent("Initialised AES-128 server->client encryption"); + sfree(handle); } -static void aes192_cskey(unsigned char *key) +static void aes128_key(void *handle, unsigned char *key) { - aes_setup(&csctx, 16, key, 24); - logevent("Initialised AES-192 client->server encryption"); + AESContext *ctx = (AESContext *)handle; + aes_setup(ctx, 16, key, 16); } -static void aes192_sckey(unsigned char *key) +static void aes192_key(void *handle, unsigned char *key) { - aes_setup(&scctx, 16, key, 24); - logevent("Initialised AES-192 server->client encryption"); + AESContext *ctx = (AESContext *)handle; + aes_setup(ctx, 16, key, 24); } -static void aes256_cskey(unsigned char *key) +static void aes256_key(void *handle, unsigned char *key) { - aes_setup(&csctx, 16, key, 32); - logevent("Initialised AES-256 client->server encryption"); -} - -static void aes256_sckey(unsigned char *key) -{ - aes_setup(&scctx, 16, key, 32); - logevent("Initialised AES-256 server->client encryption"); -} - -static void aes_csiv(unsigned char *iv) -{ - int i; - for (i = 0; i < 4; i++) - csctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i); + AESContext *ctx = (AESContext *)handle; + aes_setup(ctx, 16, key, 32); } -static void aes_sciv(unsigned char *iv) +static void aes_iv(void *handle, unsigned char *iv) { + AESContext *ctx = (AESContext *)handle; int i; for (i = 0; i < 4; i++) - scctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i); + ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i); } -static void aes_ssh2_encrypt_blk(unsigned char *blk, int len) +static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len) { - aes_encrypt_cbc(blk, len, &csctx); + AESContext *ctx = (AESContext *)handle; + aes_encrypt_cbc(blk, len, ctx); } -static void aes_ssh2_decrypt_blk(unsigned char *blk, int len) +static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len) { - aes_decrypt_cbc(blk, len, &scctx); + AESContext *ctx = (AESContext *)handle; + aes_decrypt_cbc(blk, len, ctx); } void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len) @@ -1167,66 +1153,52 @@ void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) } static const struct ssh2_cipher ssh_aes128 = { - aes_csiv, aes128_cskey, - aes_sciv, aes128_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes128_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes128-cbc", - 16, 128 + 16, 128, "AES-128" }; static const struct ssh2_cipher ssh_aes192 = { - aes_csiv, aes192_cskey, - aes_sciv, aes192_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes192_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes192-cbc", - 16, 192 + 16, 192, "AES-192" }; static const struct ssh2_cipher ssh_aes256 = { - aes_csiv, aes256_cskey, - aes_sciv, aes256_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes256_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes256-cbc", - 16, 256 + 16, 256, "AES-256" }; static const struct ssh2_cipher ssh_rijndael128 = { - aes_csiv, aes128_cskey, - aes_sciv, aes128_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes128_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "rijndael128-cbc", - 16, 128 + 16, 128, "AES-128" }; static const struct ssh2_cipher ssh_rijndael192 = { - aes_csiv, aes192_cskey, - aes_sciv, aes192_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes192_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "rijndael192-cbc", - 16, 192 + 16, 192, "AES-192" }; static const struct ssh2_cipher ssh_rijndael256 = { - aes_csiv, aes256_cskey, - aes_sciv, aes256_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes256_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "rijndael256-cbc", - 16, 256 + 16, 256, "AES-256" }; static const struct ssh2_cipher ssh_rijndael_lysator = { - aes_csiv, aes256_cskey, - aes_sciv, aes256_sckey, - aes_ssh2_encrypt_blk, - aes_ssh2_decrypt_blk, + aes_make_context, aes_free_context, aes_iv, aes256_key, + aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "rijndael-cbc@lysator.liu.se", - 16, 256 + 16, 256, "AES-256" }; static const struct ssh2_cipher *const aes_list[] = { diff --git a/sshblowf.c b/sshblowf.c index a4b43dec..6bbe7d27 100644 --- a/sshblowf.c +++ b/sshblowf.c @@ -475,75 +475,84 @@ static void blowfish_setkey(BlowfishContext * ctx, /* -- Interface with PuTTY -- */ #define SSH_SESSION_KEY_LENGTH 32 -static BlowfishContext ectx, dctx; -static void blowfish_cskey(unsigned char *key) +static void *blowfish_make_context(void) { - blowfish_setkey(&ectx, key, 16); - logevent("Initialised Blowfish client->server encryption"); + return smalloc(sizeof(BlowfishContext)); } -static void blowfish_sckey(unsigned char *key) +static void *blowfish_ssh1_make_context(void) { - blowfish_setkey(&dctx, key, 16); - logevent("Initialised Blowfish server->client encryption"); + /* In SSH1, need one key for each direction */ + return smalloc(2*sizeof(BlowfishContext)); } -static void blowfish_csiv(unsigned char *key) +static void blowfish_free_context(void *handle) { - ectx.iv0 = GET_32BIT_MSB_FIRST(key); - ectx.iv1 = GET_32BIT_MSB_FIRST(key + 4); + sfree(handle); } -static void blowfish_sciv(unsigned char *key) +static void blowfish_key(void *handle, unsigned char *key) { - dctx.iv0 = GET_32BIT_MSB_FIRST(key); - dctx.iv1 = GET_32BIT_MSB_FIRST(key + 4); + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_setkey(ctx, key, 16); } -static void blowfish_sesskey(unsigned char *key) +static void blowfish_iv(void *handle, unsigned char *key) { - blowfish_setkey(&ectx, key, SSH_SESSION_KEY_LENGTH); - ectx.iv0 = 0; - ectx.iv1 = 0; - dctx = ectx; - logevent("Initialised Blowfish encryption"); + BlowfishContext *ctx = (BlowfishContext *)handle; + ctx->iv0 = GET_32BIT_MSB_FIRST(key); + ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4); } -static void blowfish_ssh1_encrypt_blk(unsigned char *blk, int len) +static void blowfish_sesskey(void *handle, unsigned char *key) { - blowfish_lsb_encrypt_cbc(blk, len, &ectx); + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH); + ctx->iv0 = 0; + ctx->iv1 = 0; + ctx[1] = ctx[0]; /* structure copy */ } -static void blowfish_ssh1_decrypt_blk(unsigned char *blk, int len) +static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk, + int len) { - blowfish_lsb_decrypt_cbc(blk, len, &dctx); + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_lsb_encrypt_cbc(blk, len, ctx); } -static void blowfish_ssh2_encrypt_blk(unsigned char *blk, int len) +static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk, + int len) { - blowfish_msb_encrypt_cbc(blk, len, &ectx); + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_lsb_decrypt_cbc(blk, len, ctx+1); } -static void blowfish_ssh2_decrypt_blk(unsigned char *blk, int len) +static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk, + int len) { - blowfish_msb_decrypt_cbc(blk, len, &dctx); + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_msb_encrypt_cbc(blk, len, ctx); +} + +static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk, + int len) +{ + BlowfishContext *ctx = (BlowfishContext *)handle; + blowfish_msb_decrypt_cbc(blk, len, ctx); } const struct ssh_cipher ssh_blowfish_ssh1 = { - blowfish_sesskey, - blowfish_ssh1_encrypt_blk, - blowfish_ssh1_decrypt_blk, - 8 + blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey, + blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk, + 8, "Blowfish" }; static const struct ssh2_cipher ssh_blowfish_ssh2 = { - blowfish_csiv, blowfish_cskey, - blowfish_sciv, blowfish_sckey, - blowfish_ssh2_encrypt_blk, - blowfish_ssh2_decrypt_blk, + blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key, + blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, "blowfish-cbc", - 8, 128 + 8, 128, "Blowfish" }; static const struct ssh2_cipher *const blowfish_list[] = { diff --git a/sshdes.c b/sshdes.c index 9cb9cfa6..d8b3369d 100644 --- a/sshdes.c +++ b/sshdes.c @@ -278,8 +278,7 @@ typedef struct { word32 k0246[16], k1357[16]; - word32 eiv0, eiv1; - word32 div0, div1; + word32 iv0, iv1; } DESContext; #define rotl(x, c) ( (x << c) | (x >> (32-c)) ) @@ -346,8 +345,7 @@ void des_key_setup(word32 key_msw, word32 key_lsw, DESContext * sched) sched->k1357[i] = bitsel(buf, PC2_1357, 32); } - sched->eiv0 = sched->eiv1 = 0; - sched->div0 = sched->div1 = 0; /* for good measure */ + sched->iv0 = sched->iv1 = 0; } static const word32 SPboxes[8][64] = { @@ -620,8 +618,8 @@ static void des_cbc_encrypt(unsigned char *dest, const unsigned char *src, assert((len & 7) == 0); - iv0 = sched->eiv0; - iv1 = sched->eiv1; + iv0 = sched->iv0; + iv1 = sched->iv1; for (i = 0; i < len; i += 8) { iv0 ^= GET_32BIT_MSB_FIRST(src); src += 4; @@ -635,8 +633,8 @@ static void des_cbc_encrypt(unsigned char *dest, const unsigned char *src, PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4; } - sched->eiv0 = iv0; - sched->eiv1 = iv1; + sched->iv0 = iv0; + sched->iv1 = iv1; } static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src, @@ -647,8 +645,8 @@ static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src, assert((len & 7) == 0); - iv0 = sched->div0; - iv1 = sched->div1; + iv0 = sched->iv0; + iv1 = sched->iv1; for (i = 0; i < len; i += 8) { xL = GET_32BIT_MSB_FIRST(src); src += 4; @@ -664,8 +662,8 @@ static void des_cbc_decrypt(unsigned char *dest, const unsigned char *src, iv0 = xL; iv1 = xR; } - sched->div0 = iv0; - sched->div1 = iv1; + sched->iv0 = iv0; + sched->iv1 = iv1; } static void des_3cbc_encrypt(unsigned char *dest, const unsigned char *src, @@ -684,8 +682,8 @@ static void des_cbc3_encrypt(unsigned char *dest, const unsigned char *src, assert((len & 7) == 0); - iv0 = scheds->eiv0; - iv1 = scheds->eiv1; + iv0 = scheds->iv0; + iv1 = scheds->iv1; for (i = 0; i < len; i += 8) { iv0 ^= GET_32BIT_MSB_FIRST(src); src += 4; @@ -701,8 +699,8 @@ static void des_cbc3_encrypt(unsigned char *dest, const unsigned char *src, PUT_32BIT_MSB_FIRST(dest, iv1); dest += 4; } - scheds->eiv0 = iv0; - scheds->eiv1 = iv1; + scheds->iv0 = iv0; + scheds->iv1 = iv1; } static void des_3cbc_decrypt(unsigned char *dest, const unsigned char *src, @@ -721,8 +719,8 @@ static void des_cbc3_decrypt(unsigned char *dest, const unsigned char *src, assert((len & 7) == 0); - iv0 = scheds->div0; - iv1 = scheds->div1; + iv0 = scheds->iv0; + iv1 = scheds->iv1; for (i = 0; i < len; i += 8) { xL = GET_32BIT_MSB_FIRST(src); src += 4; @@ -740,94 +738,103 @@ static void des_cbc3_decrypt(unsigned char *dest, const unsigned char *src, iv0 = xL; iv1 = xR; } - scheds->div0 = iv0; - scheds->div1 = iv1; + scheds->iv0 = iv0; + scheds->iv1 = iv1; } -static DESContext cskeys[3], sckeys[3]; +static void *des3_make_context(void) +{ + return smalloc(3*sizeof(DESContext)); +} -static void des3_cskey(unsigned char *key) +static void *des3_ssh1_make_context(void) { - des_key_setup(GET_32BIT_MSB_FIRST(key), - GET_32BIT_MSB_FIRST(key + 4), &cskeys[0]); - des_key_setup(GET_32BIT_MSB_FIRST(key + 8), - GET_32BIT_MSB_FIRST(key + 12), &cskeys[1]); - des_key_setup(GET_32BIT_MSB_FIRST(key + 16), - GET_32BIT_MSB_FIRST(key + 20), &cskeys[2]); - logevent("Initialised triple-DES client->server encryption"); + /* Need 3 keys for each direction, in SSH1 */ + return smalloc(6*sizeof(DESContext)); } -static void des_cskey(unsigned char *key) +static void *des_make_context(void) { - des_key_setup(GET_32BIT_MSB_FIRST(key), - GET_32BIT_MSB_FIRST(key + 4), &cskeys[0]); - logevent("Initialised single-DES client->server encryption"); + return smalloc(sizeof(DESContext)); } -static void des3_csiv(unsigned char *key) +static void *des_ssh1_make_context(void) { - cskeys[0].eiv0 = GET_32BIT_MSB_FIRST(key); - cskeys[0].eiv1 = GET_32BIT_MSB_FIRST(key + 4); + /* Need one key for each direction, in SSH1 */ + return smalloc(2*sizeof(DESContext)); } -static void des3_sciv(unsigned char *key) +static void des3_free_context(void *handle) /* used for both 3DES and DES */ { - sckeys[0].div0 = GET_32BIT_MSB_FIRST(key); - sckeys[0].div1 = GET_32BIT_MSB_FIRST(key + 4); + sfree(handle); } -static void des3_sckey(unsigned char *key) +static void des3_key(void *handle, unsigned char *key) { + DESContext *keys = (DESContext *) handle; des_key_setup(GET_32BIT_MSB_FIRST(key), - GET_32BIT_MSB_FIRST(key + 4), &sckeys[0]); + GET_32BIT_MSB_FIRST(key + 4), &keys[0]); des_key_setup(GET_32BIT_MSB_FIRST(key + 8), - GET_32BIT_MSB_FIRST(key + 12), &sckeys[1]); + GET_32BIT_MSB_FIRST(key + 12), &keys[1]); des_key_setup(GET_32BIT_MSB_FIRST(key + 16), - GET_32BIT_MSB_FIRST(key + 20), &sckeys[2]); - logevent("Initialised triple-DES server->client encryption"); + GET_32BIT_MSB_FIRST(key + 20), &keys[2]); +} + +static void des3_iv(void *handle, unsigned char *key) +{ + DESContext *keys = (DESContext *) handle; + keys[0].iv0 = GET_32BIT_MSB_FIRST(key); + keys[0].iv1 = GET_32BIT_MSB_FIRST(key + 4); } -static void des_sckey(unsigned char *key) +static void des_key(void *handle, unsigned char *key) { + DESContext *keys = (DESContext *) handle; des_key_setup(GET_32BIT_MSB_FIRST(key), - GET_32BIT_MSB_FIRST(key + 4), &sckeys[0]); - logevent("Initialised single-DES server->client encryption"); + GET_32BIT_MSB_FIRST(key + 4), &keys[0]); } -static void des3_sesskey(unsigned char *key) +static void des3_sesskey(void *handle, unsigned char *key) { - des3_cskey(key); - des3_sckey(key); + DESContext *keys = (DESContext *) handle; + des3_key(keys, key); + des3_key(keys+3, key); } -static void des3_encrypt_blk(unsigned char *blk, int len) +static void des3_encrypt_blk(void *handle, unsigned char *blk, int len) { - des_3cbc_encrypt(blk, blk, len, cskeys); + DESContext *keys = (DESContext *) handle; + des_3cbc_encrypt(blk, blk, len, keys); } -static void des3_decrypt_blk(unsigned char *blk, int len) +static void des3_decrypt_blk(void *handle, unsigned char *blk, int len) { - des_3cbc_decrypt(blk, blk, len, sckeys); + DESContext *keys = (DESContext *) handle; + des_3cbc_decrypt(blk, blk, len, keys+3); } -static void des3_ssh2_encrypt_blk(unsigned char *blk, int len) +static void des3_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc3_encrypt(blk, blk, len, cskeys); + DESContext *keys = (DESContext *) handle; + des_cbc3_encrypt(blk, blk, len, keys); } -static void des3_ssh2_decrypt_blk(unsigned char *blk, int len) +static void des3_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc3_decrypt(blk, blk, len, sckeys); + DESContext *keys = (DESContext *) handle; + des_cbc3_decrypt(blk, blk, len, keys); } -static void des_ssh2_encrypt_blk(unsigned char *blk, int len) +static void des_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc_encrypt(blk, blk, len, cskeys); + DESContext *keys = (DESContext *) handle; + des_cbc_encrypt(blk, blk, len, keys); } -static void des_ssh2_decrypt_blk(unsigned char *blk, int len) +static void des_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc_decrypt(blk, blk, len, sckeys); + DESContext *keys = (DESContext *) handle; + des_cbc_decrypt(blk, blk, len, keys); } void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) @@ -866,8 +873,8 @@ void des3_decrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, GET_32BIT_MSB_FIRST(key + 12), &ourkeys[1]); des_key_setup(GET_32BIT_MSB_FIRST(key + 16), GET_32BIT_MSB_FIRST(key + 20), &ourkeys[2]); - ourkeys[0].div0 = GET_32BIT_MSB_FIRST(iv); - ourkeys[0].div1 = GET_32BIT_MSB_FIRST(iv+4); + ourkeys[0].iv0 = GET_32BIT_MSB_FIRST(iv); + ourkeys[0].iv1 = GET_32BIT_MSB_FIRST(iv+4); des_cbc3_decrypt(blk, blk, len, ourkeys); memset(ourkeys, 0, sizeof(ourkeys)); } @@ -882,19 +889,17 @@ void des3_encrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, GET_32BIT_MSB_FIRST(key + 12), &ourkeys[1]); des_key_setup(GET_32BIT_MSB_FIRST(key + 16), GET_32BIT_MSB_FIRST(key + 20), &ourkeys[2]); - ourkeys[0].eiv0 = GET_32BIT_MSB_FIRST(iv); - ourkeys[0].eiv1 = GET_32BIT_MSB_FIRST(iv+4); + ourkeys[0].iv0 = GET_32BIT_MSB_FIRST(iv); + ourkeys[0].iv1 = GET_32BIT_MSB_FIRST(iv+4); des_cbc3_encrypt(blk, blk, len, ourkeys); memset(ourkeys, 0, sizeof(ourkeys)); } static const struct ssh2_cipher ssh_3des_ssh2 = { - des3_csiv, des3_cskey, - des3_sciv, des3_sckey, - des3_ssh2_encrypt_blk, - des3_ssh2_decrypt_blk, + des3_make_context, des3_free_context, des3_iv, des3_key, + des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk, "3des-cbc", - 8, 168 + 8, 168, "triple-DES" }; /* @@ -903,12 +908,10 @@ static const struct ssh2_cipher ssh_3des_ssh2 = { * only people to do so, so we sigh and implement it anyway. */ static const struct ssh2_cipher ssh_des_ssh2 = { - des3_csiv, des_cskey, /* iv functions shared with 3des */ - des3_sciv, des_sckey, - des_ssh2_encrypt_blk, - des_ssh2_decrypt_blk, + des3_make_context, des3_free_context, des3_iv, des_key, + des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, "des-cbc", - 8, 56 + 8, 56, "single-DES" }; static const struct ssh2_cipher *const des3_list[] = { @@ -930,31 +933,32 @@ const struct ssh2_ciphers ssh2_des = { }; const struct ssh_cipher ssh_3des = { - des3_sesskey, - des3_encrypt_blk, - des3_decrypt_blk, - 8 + des3_ssh1_make_context, des3_free_context, des3_sesskey, + des3_encrypt_blk, des3_decrypt_blk, + 8, "triple-DES" }; -static void des_sesskey(unsigned char *key) +static void des_sesskey(void *handle, unsigned char *key) { - des_cskey(key); - des_sckey(key); + DESContext *keys = (DESContext *) handle; + des_key(keys, key); + des_key(keys+1, key); } -static void des_encrypt_blk(unsigned char *blk, int len) +static void des_encrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc_encrypt(blk, blk, len, cskeys); + DESContext *keys = (DESContext *) handle; + des_cbc_encrypt(blk, blk, len, keys); } -static void des_decrypt_blk(unsigned char *blk, int len) +static void des_decrypt_blk(void *handle, unsigned char *blk, int len) { - des_cbc_decrypt(blk, blk, len, cskeys); + DESContext *keys = (DESContext *) handle; + des_cbc_decrypt(blk, blk, len, keys+1); } const struct ssh_cipher ssh_des = { - des_sesskey, - des_encrypt_blk, - des_decrypt_blk, - 8 + des_ssh1_make_context, des3_free_context, des_sesskey, + des_encrypt_blk, des_decrypt_blk, + 8, "single-DES" }; -- 2.11.0