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;
}
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);
}
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.
}
/* 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);
/*
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;
}
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;
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);
/*
* 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;
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
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;
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 {
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)
}
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[] = {
/* -- 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[] = {
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)) )
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] = {
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;
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,
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;
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,
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;
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,
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;
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)
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));
}
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"
};
/*
* 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[] = {
};
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"
};