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:
parent
528a826574
commit
9848062b86
50
ssh.c
50
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;
|
||||
|
22
ssh.h
22
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 {
|
||||
|
114
sshaes.c
114
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");
|
||||
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[] = {
|
||||
|
81
sshblowf.c
81
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[] = {
|
||||
|
212
sshdes.c
212
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_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"
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user