1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

kex: Add simple DES support for SSHv1.

This commit is contained in:
Dmitriy Kuznetsov
2012-09-07 12:19:43 +02:00
committed by Andreas Schneider
parent a3f83e7274
commit 320951f42f
7 changed files with 94 additions and 11 deletions

View File

@@ -38,6 +38,11 @@ enum ssh_hmac_e {
SSH_HMAC_MD5 SSH_HMAC_MD5
}; };
enum ssh_des_e {
SSH_3DES,
SSH_DES
};
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx; typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void); MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len); 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_update(HMACCTX c, const void *data, unsigned long len);
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *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); int crypt_set_algorithms_server(ssh_session session);
struct ssh_crypto_struct *crypto_new(void); struct ssh_crypto_struct *crypto_new(void);
void crypto_free(struct ssh_crypto_struct *crypto); void crypto_free(struct ssh_crypto_struct *crypto);

View File

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

View File

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

View File

@@ -415,6 +415,30 @@ static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
#endif #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 */ #endif /* HAS_DES */
/* /*
@@ -539,6 +563,18 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
des3_1_encrypt, des3_1_encrypt,
des3_1_decrypt 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 */ #endif /* HAS_DES */
{ {
NULL, NULL,

View File

@@ -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); 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) { static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
if (cipher->key == NULL) { if (cipher->key == NULL) {
if (alloc_key(cipher) < 0) { 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; 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, static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in,
void *out, unsigned long len) { void *out, unsigned long len) {
gcry_cipher_encrypt(cipher->key[0], out, len, in, 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_encrypt = des3_1_encrypt,
.cbc_decrypt = des3_1_decrypt .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, .name = NULL,
.blocksize = 0, .blocksize = 0,

View File

@@ -143,7 +143,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
* Set the cryptographic functions for the next crypto * Set the cryptographic functions for the next crypto
* (it is needed for generate_session_keys for key lengths) * (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; goto error;
} }

View File

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