diff options
author | Dmitriy Kuznetsov <dk@yandex.ru> | 2012-09-07 12:19:43 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2012-09-07 12:19:43 +0200 |
commit | 320951f42ff5def186da70d2e52457b7c1d06f50 (patch) | |
tree | b8dbd3e27959c3694c8639e3cd11335137a3a378 | |
parent | a3f83e72740bfc0062ab8232e5a0325354ecc1a8 (diff) | |
download | libssh-320951f42ff5def186da70d2e52457b7c1d06f50.tar.gz libssh-320951f42ff5def186da70d2e52457b7c1d06f50.tar.xz libssh-320951f42ff5def186da70d2e52457b7c1d06f50.zip |
kex: Add simple DES support for SSHv1.
-rw-r--r-- | include/libssh/wrapper.h | 7 | ||||
-rw-r--r-- | src/kex.c | 2 | ||||
-rw-r--r-- | src/kex1.c | 13 | ||||
-rw-r--r-- | src/libcrypto.c | 36 | ||||
-rw-r--r-- | src/libgcrypt.c | 35 | ||||
-rw-r--r-- | src/packet_cb.c | 2 | ||||
-rw-r--r-- | src/wrapper.c | 10 |
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); @@ -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; 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); } |