1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

SSH ciphers now use dynamically allocated contexts.

[originally from svn r2130]
This commit is contained in:
Simon Tatham 2002-10-25 12:35:22 +00:00
parent 528a826574
commit 9848062b86
5 changed files with 249 additions and 230 deletions

50
ssh.c
View File

@ -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;

22
ssh.h
View File

@ -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 {

114
sshaes.c
View File

@ -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");
AESContext *ctx = (AESContext *)handle;
aes_setup(ctx, 16, key, 32);
}
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)
static void aes_iv(void *handle, unsigned char *iv)
{
AESContext *ctx = (AESContext *)handle;
int i;
for (i = 0; i < 4; i++)
csctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
ctx->iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
}
static void aes_sciv(unsigned char *iv)
static void aes_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
{
int i;
for (i = 0; i < 4; i++)
scctx.iv[i] = GET_32BIT_MSB_FIRST(iv + 4 * i);
AESContext *ctx = (AESContext *)handle;
aes_encrypt_cbc(blk, len, ctx);
}
static void aes_ssh2_encrypt_blk(unsigned char *blk, int len)
static void aes_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
{
aes_encrypt_cbc(blk, len, &csctx);
}
static void aes_ssh2_decrypt_blk(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[] = {

View File

@ -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[] = {

212
sshdes.c
View File

@ -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_cskey(unsigned char *key)
static void *des3_make_context(void)
{
return smalloc(3*sizeof(DESContext));
}
static void *des3_ssh1_make_context(void)
{
/* Need 3 keys for each direction, in SSH1 */
return smalloc(6*sizeof(DESContext));
}
static void *des_make_context(void)
{
return smalloc(sizeof(DESContext));
}
static void *des_ssh1_make_context(void)
{
/* Need one key for each direction, in SSH1 */
return smalloc(2*sizeof(DESContext));
}
static void des3_free_context(void *handle) /* used for both 3DES and DES */
{
sfree(handle);
}
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), &cskeys[0]);
GET_32BIT_MSB_FIRST(key + 4), &keys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &cskeys[1]);
GET_32BIT_MSB_FIRST(key + 12), &keys[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");
GET_32BIT_MSB_FIRST(key + 20), &keys[2]);
}
static void des_cskey(unsigned char *key)
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_key(void *handle, unsigned char *key)
{
DESContext *keys = (DESContext *) handle;
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key + 4), &cskeys[0]);
logevent("Initialised single-DES client->server encryption");
GET_32BIT_MSB_FIRST(key + 4), &keys[0]);
}
static void des3_csiv(unsigned char *key)
static void des3_sesskey(void *handle, unsigned char *key)
{
cskeys[0].eiv0 = GET_32BIT_MSB_FIRST(key);
cskeys[0].eiv1 = GET_32BIT_MSB_FIRST(key + 4);
DESContext *keys = (DESContext *) handle;
des3_key(keys, key);
des3_key(keys+3, key);
}
static void des3_sciv(unsigned char *key)
static void des3_encrypt_blk(void *handle, unsigned char *blk, int len)
{
sckeys[0].div0 = GET_32BIT_MSB_FIRST(key);
sckeys[0].div1 = GET_32BIT_MSB_FIRST(key + 4);
DESContext *keys = (DESContext *) handle;
des_3cbc_encrypt(blk, blk, len, keys);
}
static void des3_sckey(unsigned char *key)
static void des3_decrypt_blk(void *handle, unsigned char *blk, int len)
{
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key + 4), &sckeys[0]);
des_key_setup(GET_32BIT_MSB_FIRST(key + 8),
GET_32BIT_MSB_FIRST(key + 12), &sckeys[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");
DESContext *keys = (DESContext *) handle;
des_3cbc_decrypt(blk, blk, len, keys+3);
}
static void des_sckey(unsigned char *key)
static void des3_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
{
des_key_setup(GET_32BIT_MSB_FIRST(key),
GET_32BIT_MSB_FIRST(key + 4), &sckeys[0]);
logevent("Initialised single-DES server->client encryption");
DESContext *keys = (DESContext *) handle;
des_cbc3_encrypt(blk, blk, len, keys);
}
static void des3_sesskey(unsigned char *key)
static void des3_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
{
des3_cskey(key);
des3_sckey(key);
DESContext *keys = (DESContext *) handle;
des_cbc3_decrypt(blk, blk, len, keys);
}
static void des3_encrypt_blk(unsigned char *blk, int len)
static void des_ssh2_encrypt_blk(void *handle, unsigned char *blk, int len)
{
des_3cbc_encrypt(blk, blk, len, cskeys);
DESContext *keys = (DESContext *) handle;
des_cbc_encrypt(blk, blk, len, keys);
}
static void des3_decrypt_blk(unsigned char *blk, int len)
static void des_ssh2_decrypt_blk(void *handle, unsigned char *blk, int len)
{
des_3cbc_decrypt(blk, blk, len, sckeys);
}
static void des3_ssh2_encrypt_blk(unsigned char *blk, int len)
{
des_cbc3_encrypt(blk, blk, len, cskeys);
}
static void des3_ssh2_decrypt_blk(unsigned char *blk, int len)
{
des_cbc3_decrypt(blk, blk, len, sckeys);
}
static void des_ssh2_encrypt_blk(unsigned char *blk, int len)
{
des_cbc_encrypt(blk, blk, len, cskeys);
}
static void des_ssh2_decrypt_blk(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"
};