1
1

kex: Add simple DES support for SSHv1.

Этот коммит содержится в:
Dmitriy Kuznetsov 2012-09-07 12:19:43 +02:00 коммит произвёл Andreas Schneider
родитель a3f83e7274
Коммит 320951f42f
7 изменённых файлов: 94 добавлений и 11 удалений

Просмотреть файл

@ -38,6 +38,11 @@ enum ssh_hmac_e {
SSH_HMAC_MD5
};
enum ssh_des_e {
SSH_3DES,
SSH_DES
};
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len);
@ -58,7 +63,7 @@ HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
void hmac_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
int crypt_set_algorithms(ssh_session );
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type);
int crypt_set_algorithms_server(ssh_session session);
struct ssh_crypto_struct *crypto_new(void);
void crypto_free(struct ssh_crypto_struct *crypto);

Просмотреть файл

@ -56,6 +56,7 @@
#endif
#define DES "3des-cbc"
#define SIMPLEDES "des-cbc-ssh1"
#endif
#ifdef WITH_ZLIB
@ -93,6 +94,7 @@ const char *supported_methods[] = {
HOSTKEYS,
AES BLOWFISH DES,
AES BLOWFISH DES,
SIMPLEDES,
"hmac-sha1",
"hmac-sha1",
ZLIB,

Просмотреть файл

@ -312,6 +312,8 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
ssh_string enc_session = NULL;
uint16_t bits;
int ko;
uint32_t support_3DES = 0;
uint32_t support_DES = 0;
enter_function();
(void)type;
(void)user;
@ -397,7 +399,10 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
/* now, we must choose an encryption algo */
/* hardcode 3des */
if (!(supported_ciphers_mask & (1 << SSH_CIPHER_3DES))) {
//
support_3DES = (supported_ciphers_mask & (1<<SSH_CIPHER_3DES));
support_DES = (supported_ciphers_mask & (1<<SSH_CIPHER_DES));
if(!support_3DES && !support_DES){
ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
goto error;
}
@ -406,7 +411,7 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
goto error;
}
if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
if (buffer_add_u8(session->out_buffer, support_3DES ? SSH_CIPHER_3DES : SSH_CIPHER_DES) < 0) {
goto error;
}
if (buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
@ -440,8 +445,8 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
}
/* we can set encryption */
if (crypt_set_algorithms(session)) {
goto error;
if(crypt_set_algorithms(session, support_3DES ? SSH_3DES : SSH_DES)){
goto error;
}
session->current_crypto = session->next_crypto;

Просмотреть файл

@ -415,6 +415,30 @@ static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
#endif
}
static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){
if(!cipher->key){
if (alloc_key(cipher) < 0) {
return -1;
}
DES_set_odd_parity(key);
DES_set_key_unchecked(key,cipher->key);
}
cipher->IV=IV;
return 0;
}
static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len){
DES_ncbc_encrypt(in, out, len, cipher->key, cipher->IV, 1);
}
static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len){
DES_ncbc_encrypt(in,out,len, cipher->key, cipher->IV, 0);
}
#endif /* HAS_DES */
/*
@ -539,6 +563,18 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
des3_1_encrypt,
des3_1_decrypt
},
{
"des-cbc-ssh1",
8,
sizeof(DES_key_schedule),
NULL,
NULL,
64,
des1_set_key,
des1_set_key,
des1_1_encrypt,
des1_1_decrypt
},
#endif /* HAS_DES */
{
NULL,

Просмотреть файл

@ -262,6 +262,17 @@ static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
}
static int des1_set_key(struct ssh_cipher_struct *cipher, void *key){
if(!cipher->key){
if (alloc_key(cipher) < 0) {
return -1;
}
DES_set_odd_parity(key);
DES_set_key_unchecked(key,cipher->key);
}
return 0;
}
static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
if (cipher->key == NULL) {
if (alloc_key(cipher) < 0) {
@ -285,6 +296,19 @@ static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
return 0;
}
static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len, void *IV){
DES_ncbc_encrypt(in, out, len, cipher->key, IV, 1);
}
static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len, void *IV){
DES_ncbc_encrypt(in,out,len, cipher->key, IV, 0);
}
static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in,
void *out, unsigned long len) {
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
@ -461,6 +485,17 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.cbc_encrypt = des3_1_encrypt,
.cbc_decrypt = des3_1_decrypt
},
{
.name = "des-cbc-ssh1",
.blocksize = 8,
.keylen = sizeof(DES_key_schedule),
.key = NULL,
.keysize = 64,
.set_encrypt_key = des1_set_key,
.set_decrypt_key = des1_set_key,
.cbc_encrypt = des1_1_encrypt,
.cbc_decrypt = des1_1_decrypt
},
{
.name = NULL,
.blocksize = 0,

Просмотреть файл

@ -143,7 +143,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
* Set the cryptographic functions for the next crypto
* (it is needed for generate_session_keys for key lengths)
*/
if (crypt_set_algorithms(session)) {
if (crypt_set_algorithms(session, SSH_3DES) /* knows nothing about DES*/ ) {
goto error;
}

Просмотреть файл

@ -228,18 +228,18 @@ error:
return rc;
}
static int crypt_set_algorithms1(ssh_session session) {
static int crypt_set_algorithms1(ssh_session session, enum ssh_des_e des_type) {
int i = 0;
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
/* right now, we force 3des-cbc to be taken */
while (ssh_ciphertab[i].name && strcmp(ssh_ciphertab[i].name,
"3des-cbc-ssh1")) {
des_type == SSH_DES ? "des-cbc-ssh1" : "3des-cbc-ssh1")) {
i++;
}
if (ssh_ciphertab[i].name == NULL) {
ssh_set_error(session, SSH_FATAL, "cipher 3des-cbc-ssh1 not found!");
ssh_set_error(session, SSH_FATAL, "cipher 3des-cbc-ssh1 or des-cbc-ssh1 not found!");
return SSH_ERROR;
}
@ -258,8 +258,8 @@ static int crypt_set_algorithms1(ssh_session session) {
return SSH_OK;
}
int crypt_set_algorithms(ssh_session session) {
return (session->version == 1) ? crypt_set_algorithms1(session) :
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type) {
return (session->version == 1) ? crypt_set_algorithms1(session, des_type) :
crypt_set_algorithms2(session);
}