aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Kuznetsov <dk@yandex.ru>2012-09-07 12:19:43 +0200
committerAndreas Schneider <asn@cryptomilk.org>2012-09-07 12:19:43 +0200
commit320951f42ff5def186da70d2e52457b7c1d06f50 (patch)
treeb8dbd3e27959c3694c8639e3cd11335137a3a378
parenta3f83e72740bfc0062ab8232e5a0325354ecc1a8 (diff)
downloadlibssh-320951f42ff5def186da70d2e52457b7c1d06f50.tar.gz
libssh-320951f42ff5def186da70d2e52457b7c1d06f50.tar.xz
libssh-320951f42ff5def186da70d2e52457b7c1d06f50.zip
kex: Add simple DES support for SSHv1.
-rw-r--r--include/libssh/wrapper.h7
-rw-r--r--src/kex.c2
-rw-r--r--src/kex1.c13
-rw-r--r--src/libcrypto.c36
-rw-r--r--src/libgcrypt.c35
-rw-r--r--src/packet_cb.c2
-rw-r--r--src/wrapper.c10
7 files changed, 94 insertions, 11 deletions
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index 79d8745f..c5d714c8 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -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);
diff --git a/src/kex.c b/src/kex.c
index c23e2982..f2b5a939 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -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,
diff --git a/src/kex1.c b/src/kex1.c
index d0ce5c7b..b11cf007 100644
--- a/src/kex1.c
+++ b/src/kex1.c
@@ -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;
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 79775417..44b0fb36 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -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,
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 70ce828d..bc10bd8b 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -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);
@@ -462,6 +486,17 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.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,
.keylen = 0,
diff --git a/src/packet_cb.c b/src/packet_cb.c
index f236fe57..dd77dd7c 100644
--- a/src/packet_cb.c
+++ b/src/packet_cb.c
@@ -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;
}
diff --git a/src/wrapper.c b/src/wrapper.c
index edce03d4..e27579db 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -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);
}