version 1.37, 2000/10/23 19:31:54 |
version 1.37.2.2, 2001/02/19 17:18:46 |
|
|
#include "includes.h" |
#include "includes.h" |
RCSID("$OpenBSD$"); |
RCSID("$OpenBSD$"); |
|
|
#include "ssh.h" |
|
#include "xmalloc.h" |
#include "xmalloc.h" |
|
#include "log.h" |
|
#include "cipher.h" |
|
|
#include <openssl/md5.h> |
#include <openssl/md5.h> |
|
|
|
|
|
|
memcpy(&iv1, iv2, 8); |
memcpy(&iv1, iv2, 8); |
|
|
des_cbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT); |
des_ncbc_encrypt(src, dest, len, cc->u.des3.key1, &iv1, DES_ENCRYPT); |
memcpy(&iv1, dest + len - 8, 8); |
des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT); |
|
des_ncbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT); |
des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_DECRYPT); |
|
memcpy(iv2, &iv1, 8); /* Note how iv1 == iv2 on entry and exit. */ |
|
|
|
des_cbc_encrypt(dest, dest, len, cc->u.des3.key3, iv3, DES_ENCRYPT); |
|
memcpy(iv3, dest + len - 8, 8); |
|
} |
} |
void |
void |
des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, |
des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, |
|
|
|
|
memcpy(&iv1, iv2, 8); |
memcpy(&iv1, iv2, 8); |
|
|
des_cbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT); |
des_ncbc_encrypt(src, dest, len, cc->u.des3.key3, iv3, DES_DECRYPT); |
memcpy(iv3, src + len - 8, 8); |
des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT); |
|
des_ncbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT); |
des_cbc_encrypt(dest, dest, len, cc->u.des3.key2, iv2, DES_ENCRYPT); |
|
memcpy(iv2, dest + len - 8, 8); |
|
|
|
des_cbc_encrypt(dest, dest, len, cc->u.des3.key1, &iv1, DES_DECRYPT); |
|
/* memcpy(&iv1, iv2, 8); */ |
|
/* Note how iv1 == iv2 on entry and exit. */ |
|
} |
} |
|
|
/* Blowfish */ |
/* Blowfish */ |
void |
void |
blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
{ |
{ |
BF_set_key(&cc->u.bf.key, keylen, (unsigned char *)key); |
BF_set_key(&cc->u.bf.key, keylen, (u_char *)key); |
} |
} |
void |
void |
blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
|
|
* and after encryption/decryption. Thus the swap_bytes stuff (yuk). |
* and after encryption/decryption. Thus the swap_bytes stuff (yuk). |
*/ |
*/ |
static void |
static void |
swap_bytes(const unsigned char *src, unsigned char *dst, int n) |
swap_bytes(const u_char *src, u_char *dst, int n) |
{ |
{ |
char c[4]; |
char c[4]; |
|
|
|
|
void |
void |
cast_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
cast_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
{ |
{ |
CAST_set_key(&cc->u.cast.key, keylen, (unsigned char *) key); |
CAST_set_key(&cc->u.cast.key, keylen, (u_char *) key); |
} |
} |
void |
void |
cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
{ |
{ |
if (iv == NULL) |
if (iv == NULL) |
fatal("no IV for %s.", cc->cipher->name); |
fatal("no IV for %s.", cc->cipher->name); |
memcpy(cc->u.cast.iv, (char *)iv, 8); |
memcpy(cc->u.cast.iv, (char *)iv, 8); |
} |
} |
|
|
void |
void |
rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen) |
{ |
{ |
if (iv == NULL) |
if (iv == NULL) |
fatal("no IV for %s.", cc->cipher->name); |
fatal("no IV for %s.", cc->cipher->name); |
memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE); |
memcpy((u_char *)cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE); |
} |
} |
|
|
SSH_CIPHER_SSH2, 16, 32, |
SSH_CIPHER_SSH2, 16, 32, |
rijndael_setkey, rijndael_setiv, |
rijndael_setkey, rijndael_setiv, |
rijndael_cbc_encrypt, rijndael_cbc_decrypt }, |
rijndael_cbc_encrypt, rijndael_cbc_decrypt }, |
{ NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } |
{ NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL } |
}; |
}; |
|
|
/*--*/ |
/*--*/ |
|
|
unsigned int |
u_int |
cipher_mask_ssh1(int client) |
cipher_mask_ssh1(int client) |
{ |
{ |
unsigned int mask = 0; |
u_int mask = 0; |
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ |
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ |
mask |= 1 << SSH_CIPHER_BLOWFISH; |
mask |= 1 << SSH_CIPHER_BLOWFISH; |
if (client) { |
if (client) { |
|
|
const char *passphrase) |
const char *passphrase) |
{ |
{ |
MD5_CTX md; |
MD5_CTX md; |
unsigned char digest[16]; |
u_char digest[16]; |
|
|
MD5_Init(&md); |
MD5_Init(&md); |
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); |
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); |