diff options
Diffstat (limited to 'libssh')
-rw-r--r-- | libssh/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libssh/libcrypto.c | 443 | ||||
-rw-r--r-- | libssh/libgcrypt.c | 423 | ||||
-rw-r--r-- | libssh/wrapper.c | 802 |
4 files changed, 874 insertions, 796 deletions
diff --git a/libssh/CMakeLists.txt b/libssh/CMakeLists.txt index bd3390c..9baea9f 100644 --- a/libssh/CMakeLists.txt +++ b/libssh/CMakeLists.txt @@ -93,6 +93,8 @@ set(libssh_SRCS keyfiles.c keys.c legacy.c + libcrypto.c + libgcrypt.c log.c match.c messages.c diff --git a/libssh/libcrypto.c b/libssh/libcrypto.c new file mode 100644 index 0000000..f43a91e --- /dev/null +++ b/libssh/libcrypto.c @@ -0,0 +1,443 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2009 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libssh/priv.h" +#include "libssh/session.h" +#include "libssh/crypto.h" +#include "libssh/wrapper.h" +#include "libssh/libcrypto.h" + +#ifdef HAVE_LIBCRYPTO + +#include <openssl/sha.h> +#include <openssl/md5.h> +#include <openssl/dsa.h> +#include <openssl/rsa.h> +#include <openssl/hmac.h> +#include <openssl/opensslv.h> +#ifdef HAVE_OPENSSL_AES_H +#define HAS_AES +#include <openssl/aes.h> +#endif +#ifdef HAVE_OPENSSL_BLOWFISH_H +#define HAS_BLOWFISH +#include <openssl/blowfish.h> +#endif +#ifdef HAVE_OPENSSL_DES_H +#define HAS_DES +#include <openssl/des.h> +#endif + +#if (OPENSSL_VERSION_NUMBER<0x00907000L) +#define OLD_CRYPTO +#endif + +#include "libssh/crypto.h" + +static int alloc_key(struct crypto_struct *cipher) { + cipher->key = malloc(cipher->keylen); + if (cipher->key == NULL) { + return -1; + } + + return 0; +} + +SHACTX sha1_init(void) { + SHACTX c = malloc(sizeof(*c)); + if (c == NULL) { + return NULL; + } + SHA1_Init(c); + + return c; +} + +void sha1_update(SHACTX c, const void *data, unsigned long len) { + SHA1_Update(c,data,len); +} + +void sha1_final(unsigned char *md, SHACTX c) { + SHA1_Final(md, c); + SAFE_FREE(c); +} + +void sha1(unsigned char *digest, int len, unsigned char *hash) { + SHA1(digest, len, hash); +} + +MD5CTX md5_init(void) { + MD5CTX c = malloc(sizeof(*c)); + if (c == NULL) { + return NULL; + } + + MD5_Init(c); + + return c; +} + +void md5_update(MD5CTX c, const void *data, unsigned long len) { + MD5_Update(c, data, len); +} + +void md5_final(unsigned char *md, MD5CTX c) { + MD5_Final(md,c); + SAFE_FREE(c); +} + +HMACCTX hmac_init(const void *key, int len, int type) { + HMACCTX ctx = NULL; + + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) { + return NULL; + } + +#ifndef OLD_CRYPTO + HMAC_CTX_init(ctx); // openssl 0.9.7 requires it. +#endif + + switch(type) { + case HMAC_SHA1: + HMAC_Init(ctx, key, len, EVP_sha1()); + break; + case HMAC_MD5: + HMAC_Init(ctx, key, len, EVP_md5()); + break; + default: + SAFE_FREE(ctx); + ctx = NULL; + } + + return ctx; +} + +void hmac_update(HMACCTX ctx, const void *data, unsigned long len) { + HMAC_Update(ctx, data, len); +} + +void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) { + HMAC_Final(ctx,hashmacbuf,len); + +#ifndef OLD_CRYPTO + HMAC_CTX_cleanup(ctx); +#else + HMAC_cleanup(ctx); +#endif + + SAFE_FREE(ctx); +} + +#ifdef HAS_BLOWFISH +/* the wrapper functions for blowfish */ +static int blowfish_set_key(struct crypto_struct *cipher, void *key){ + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + BF_set_key(cipher->key, 16, key); + } + + return 0; +} + +static void blowfish_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { + BF_cbc_encrypt(in, out, len, cipher->key, IV, BF_ENCRYPT); +} + +static void blowfish_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { + BF_cbc_encrypt(in, out, len, cipher->key, IV, BF_DECRYPT); +} +#endif /* HAS_BLOWFISH */ + +#ifdef HAS_AES +static int aes_set_encrypt_key(struct crypto_struct *cipher, void *key) { + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + if (AES_set_encrypt_key(key,cipher->keysize,cipher->key) < 0) { + SAFE_FREE(cipher->key); + return -1; + } + } + + return 0; +} +static int aes_set_decrypt_key(struct crypto_struct *cipher, void *key) { + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + if (AES_set_decrypt_key(key,cipher->keysize,cipher->key) < 0) { + SAFE_FREE(cipher->key); + return -1; + } + } + + return 0; +} + +static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, + unsigned long len, void *IV) { + AES_cbc_encrypt(in, out, len, cipher->key, IV, AES_ENCRYPT); +} + +static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, + unsigned long len, void *IV) { + AES_cbc_encrypt(in, out, len, cipher->key, IV, AES_DECRYPT); +} + +#ifndef BROKEN_AES_CTR +/* OpenSSL until 0.9.7c has a broken AES_ctr128_encrypt implementation which + * increments the counter from 2^64 instead of 1. It's better not to use it + */ + +/** @internal + * @brief encrypts/decrypts data with stream cipher AES_ctr128. 128 bits is actually + * the size of the CTR counter and incidentally the blocksize, but not the keysize. + * @param len[in] must be a multiple of AES128 block size. + */ +static void aes_ctr128_encrypt(struct crypto_struct *cipher, void *in, void *out, + unsigned long len, void *IV) { + unsigned char tmp_buffer[128/8]; + unsigned int num=0; + /* Some things are special with ctr128 : + * In this case, tmp_buffer is not being used, because it is used to store temporary data + * when an encryption is made on lengths that are not multiple of blocksize. + * Same for num, which is being used to store the current offset in blocksize in CTR + * function. + */ + AES_ctr128_encrypt(in, out, len, cipher->key, IV, tmp_buffer, &num); +} +#endif /* BROKEN_AES_CTR */ +#endif /* HAS_AES */ + +#ifdef HAS_DES +static int des3_set_key(struct crypto_struct *cipher, void *key) { + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + + DES_set_odd_parity(key); + DES_set_odd_parity((void*)((uint8_t*)key + 8)); + DES_set_odd_parity((void*)((uint8_t*)key + 16)); + DES_set_key_unchecked(key, cipher->key); + DES_set_key_unchecked((void*)((uint8_t*)key + 8), (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule))); + DES_set_key_unchecked((void*)((uint8_t*)key + 16), (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule))); + } + + return 0; +} + +static void des3_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { + DES_ede3_cbc_encrypt(in, out, len, cipher->key, + (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), + (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), + IV, 1); +} + +static void des3_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { + DES_ede3_cbc_encrypt(in, out, len, cipher->key, + (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), + (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), + IV, 0); +} + +static void des3_1_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { +#ifdef DEBUG_CRYPTO + ssh_print_hexa("Encrypt IV before", IV, 24); +#endif + DES_ncbc_encrypt(in, out, len, cipher->key, IV, 1); + DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), + (void*)((uint8_t*)IV + 8), 0); + DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), + (void*)((uint8_t*)IV + 16), 1); +#ifdef DEBUG_CRYPTO + ssh_print_hexa("Encrypt IV after", IV, 24); +#endif +} + +static void des3_1_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len, void *IV) { +#ifdef DEBUG_CRYPTO + ssh_print_hexa("Decrypt IV before", IV, 24); +#endif + + DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), + IV, 0); + DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), + (void*)((uint8_t*)IV + 8), 1); + DES_ncbc_encrypt(in, out, len, cipher->key, (void*)((uint8_t*)IV + 16), 0); + +#ifdef DEBUG_CRYPTO + ssh_print_hexa("Decrypt IV after", IV, 24); +#endif +} + +#endif /* HAS_DES */ + +/* + * The table of supported ciphers + * + * WARNING: If you modify crypto_struct, you must make sure the order is + * correct! + */ +static struct crypto_struct ssh_ciphertab[] = { +#ifdef HAS_BLOWFISH + { + "blowfish-cbc", + 8, + sizeof (BF_KEY), + NULL, + 128, + blowfish_set_key, + blowfish_set_key, + blowfish_encrypt, + blowfish_decrypt + }, +#endif /* HAS_BLOWFISH */ +#ifdef HAS_AES +#ifndef BROKEN_AES_CTR + { + "aes128-ctr", + 16, + sizeof(AES_KEY), + NULL, + 128, + aes_set_encrypt_key, + aes_set_encrypt_key, + aes_ctr128_encrypt, + aes_ctr128_encrypt + }, + { + "aes192-ctr", + 16, + sizeof(AES_KEY), + NULL, + 192, + aes_set_encrypt_key, + aes_set_encrypt_key, + aes_ctr128_encrypt, + aes_ctr128_encrypt + }, + { + "aes256-ctr", + 16, + sizeof(AES_KEY), + NULL, + 256, + aes_set_encrypt_key, + aes_set_encrypt_key, + aes_ctr128_encrypt, + aes_ctr128_encrypt + }, +#endif /* BROKEN_AES_CTR */ + { + "aes128-cbc", + 16, + sizeof(AES_KEY), + NULL, + 128, + aes_set_encrypt_key, + aes_set_decrypt_key, + aes_encrypt, + aes_decrypt + }, + { + "aes192-cbc", + 16, + sizeof(AES_KEY), + NULL, + 192, + aes_set_encrypt_key, + aes_set_decrypt_key, + aes_encrypt, + aes_decrypt + }, + { + "aes256-cbc", + 16, + sizeof(AES_KEY), + NULL, + 256, + aes_set_encrypt_key, + aes_set_decrypt_key, + aes_encrypt, + aes_decrypt + }, +#endif /* HAS_AES */ +#ifdef HAS_DES + { + "3des-cbc", + 8, + sizeof(DES_key_schedule) * 3, + NULL, + 192, + des3_set_key, + des3_set_key, + des3_encrypt, + des3_decrypt + }, + { + "3des-cbc-ssh1", + 8, + sizeof(DES_key_schedule) * 3, + NULL, + 192, + des3_set_key, + des3_set_key, + des3_1_encrypt, + des3_1_decrypt + }, +#endif /* HAS_DES */ + { + NULL, + 0, + 0, + NULL, + 0, + NULL, + NULL, + NULL, + NULL + } +}; + + +struct crypto_struct *ssh_get_ciphertab(){ + return ssh_ciphertab; +} + +#endif /* LIBCRYPTO */ + diff --git a/libssh/libgcrypt.c b/libssh/libgcrypt.c new file mode 100644 index 0000000..f8fe96f --- /dev/null +++ b/libssh/libgcrypt.c @@ -0,0 +1,423 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2009 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libssh/priv.h" +#include "libssh/session.h" +#include "libssh/crypto.h" +#include "libssh/wrapper.h" + +#ifdef HAVE_LIBGCRYPT +#include <gcrypt.h> + + +static int alloc_key(struct crypto_struct *cipher) { + cipher->key = malloc(cipher->keylen); + if (cipher->key == NULL) { + return -1; + } + + return 0; +} + +SHACTX sha1_init(void) { + SHACTX ctx = NULL; + gcry_md_open(&ctx, GCRY_MD_SHA1, 0); + + return ctx; +} + +void sha1_update(SHACTX c, const void *data, unsigned long len) { + gcry_md_write(c, data, len); +} + +void sha1_final(unsigned char *md, SHACTX c) { + gcry_md_final(c); + memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN); + gcry_md_close(c); +} + +void sha1(unsigned char *digest, int len, unsigned char *hash) { + gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len); +} + +MD5CTX md5_init(void) { + MD5CTX c = NULL; + gcry_md_open(&c, GCRY_MD_MD5, 0); + + return c; +} + +void md5_update(MD5CTX c, const void *data, unsigned long len) { + gcry_md_write(c,data,len); +} + +void md5_final(unsigned char *md, MD5CTX c) { + gcry_md_final(c); + memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN); + gcry_md_close(c); +} + +HMACCTX hmac_init(const void *key, int len, int type) { + HMACCTX c = NULL; + + switch(type) { + case HMAC_SHA1: + gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + break; + case HMAC_MD5: + gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); + break; + default: + c = NULL; + } + + gcry_md_setkey(c, key, len); + + return c; +} + +void hmac_update(HMACCTX c, const void *data, unsigned long len) { + gcry_md_write(c, data, len); +} + +void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len) { + *len = gcry_md_get_algo_dlen(gcry_md_get_algo(c)); + memcpy(hashmacbuf, gcry_md_read(c, 0), *len); + gcry_md_close(c); +} + +/* the wrapper functions for blowfish */ +static int blowfish_set_key(struct crypto_struct *cipher, void *key, void *IV){ + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_BLOWFISH, + GCRY_CIPHER_MODE_CBC, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setkey(cipher->key[0], key, 16)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + } + + return 0; +} + +static void blowfish_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_encrypt(cipher->key[0], out, len, in, len); +} + +static void blowfish_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_decrypt(cipher->key[0], out, len, in, len); +} + +static int aes_set_key(struct crypto_struct *cipher, void *key, void *IV) { + int mode=GCRY_CIPHER_MODE_CBC; + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + if(strstr(cipher->name,"-ctr")) + mode=GCRY_CIPHER_MODE_CTR; + switch (cipher->keysize) { + case 128: + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES128, + mode, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + break; + case 192: + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES192, + mode, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + break; + case 256: + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES256, + mode, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + break; + } + if (gcry_cipher_setkey(cipher->key[0], key, cipher->keysize / 8)) { + SAFE_FREE(cipher->key); + return -1; + } + if(mode == GCRY_CIPHER_MODE_CBC){ + if (gcry_cipher_setiv(cipher->key[0], IV, 16)) { + + SAFE_FREE(cipher->key); + return -1; + } + } else { + if(gcry_cipher_setctr(cipher->key[0],IV,16)){ + SAFE_FREE(cipher->key); + return -1; + } + } + } + + return 0; +} + +static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, + unsigned long len) { + gcry_cipher_encrypt(cipher->key[0], out, len, in, len); +} + +static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, + unsigned long len) { + gcry_cipher_decrypt(cipher->key[0], out, len, in, len); +} + +static int des3_set_key(struct crypto_struct *cipher, void *key, void *IV) { + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_3DES, + GCRY_CIPHER_MODE_CBC, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setkey(cipher->key[0], key, 24)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + } + + return 0; +} + +static void des3_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_encrypt(cipher->key[0], out, len, in, len); +} + +static void des3_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_decrypt(cipher->key[0], out, len, in, len); +} + +static int des3_1_set_key(struct crypto_struct *cipher, void *key, void *IV) { + if (cipher->key == NULL) { + if (alloc_key(cipher) < 0) { + return -1; + } + if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES, + GCRY_CIPHER_MODE_CBC, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setkey(cipher->key[0], key, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + + if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES, + GCRY_CIPHER_MODE_CBC, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setkey(cipher->key[1], (unsigned char *)key + 8, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setiv(cipher->key[1], (unsigned char *)IV + 8, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + + if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES, + GCRY_CIPHER_MODE_CBC, 0)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setkey(cipher->key[2], (unsigned char *)key + 16, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + if (gcry_cipher_setiv(cipher->key[2], (unsigned char *)IV + 16, 8)) { + SAFE_FREE(cipher->key); + return -1; + } + } + + return 0; +} + +static void des3_1_encrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_encrypt(cipher->key[0], out, len, in, len); + gcry_cipher_decrypt(cipher->key[1], in, len, out, len); + gcry_cipher_encrypt(cipher->key[2], out, len, in, len); +} + +static void des3_1_decrypt(struct crypto_struct *cipher, void *in, + void *out, unsigned long len) { + gcry_cipher_decrypt(cipher->key[2], out, len, in, len); + gcry_cipher_encrypt(cipher->key[1], in, len, out, len); + gcry_cipher_decrypt(cipher->key[0], out, len, in, len); +} + +/* the table of supported ciphers */ +static struct crypto_struct ssh_ciphertab[] = { + { + .name = "blowfish-cbc", + .blocksize = 8, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 128, + .set_encrypt_key = blowfish_set_key, + .set_decrypt_key = blowfish_set_key, + .cbc_encrypt = blowfish_encrypt, + .cbc_decrypt = blowfish_decrypt + }, + { + .name = "aes128-ctr", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 128, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_encrypt + }, + { + .name = "aes192-ctr", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 192, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_encrypt + }, + { + .name = "aes256-ctr", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 256, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_encrypt + }, + { + .name = "aes128-cbc", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 128, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_decrypt + }, + { + .name = "aes192-cbc", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 192, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_decrypt + }, + { + .name = "aes256-cbc", + .blocksize = 16, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 256, + .set_encrypt_key = aes_set_key, + .set_decrypt_key = aes_set_key, + .cbc_encrypt = aes_encrypt, + .cbc_decrypt = aes_decrypt + }, + { + .name = "3des-cbc", + .blocksize = 8, + .keylen = sizeof(gcry_cipher_hd_t), + .key = NULL, + .keysize = 192, + .set_encrypt_key = des3_set_key, + .set_decrypt_key = des3_set_key, + .cbc_encrypt = des3_encrypt, + .cbc_decrypt = des3_decrypt + }, + { + .name = "3des-cbc-ssh1", + .blocksize = 8, + .keylen = sizeof(gcry_cipher_hd_t) * 3, + .key = NULL, + .keysize = 192, + .set_encrypt_key = des3_1_set_key, + .set_decrypt_key = des3_1_set_key, + .cbc_encrypt = des3_1_encrypt, + .cbc_decrypt = des3_1_decrypt + }, + { + .name = NULL, + .blocksize = 0, + .keylen = 0, + .key = NULL, + .keysize = 0, + .set_encrypt_key = NULL, + .set_decrypt_key = NULL, + .cbc_encrypt = NULL, + .cbc_decrypt = NULL + } +}; + +struct crypto_struct *ssh_get_ciphertab(){ + return ssh_ciphertab; +} +#endif diff --git a/libssh/wrapper.c b/libssh/wrapper.c index af5bbe0..b91077e 100644 --- a/libssh/wrapper.c +++ b/libssh/wrapper.c @@ -32,6 +32,8 @@ */ #include "config.h" + + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -41,800 +43,6 @@ #include "libssh/crypto.h" #include "libssh/wrapper.h" -#ifdef HAVE_LIBGCRYPT -#include <gcrypt.h> - - -static int alloc_key(struct crypto_struct *cipher) { - cipher->key = malloc(cipher->keylen); - if (cipher->key == NULL) { - return -1; - } - - return 0; -} - -SHACTX sha1_init(void) { - SHACTX ctx = NULL; - gcry_md_open(&ctx, GCRY_MD_SHA1, 0); - - return ctx; -} - -void sha1_update(SHACTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void sha1_final(unsigned char *md, SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN); - gcry_md_close(c); -} - -void sha1(unsigned char *digest, int len, unsigned char *hash) { - gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len); -} - -MD5CTX md5_init(void) { - MD5CTX c = NULL; - gcry_md_open(&c, GCRY_MD_MD5, 0); - - return c; -} - -void md5_update(MD5CTX c, const void *data, unsigned long len) { - gcry_md_write(c,data,len); -} - -void md5_final(unsigned char *md, MD5CTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN); - gcry_md_close(c); -} - -HMACCTX hmac_init(const void *key, int len, int type) { - HMACCTX c = NULL; - - switch(type) { - case HMAC_SHA1: - gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); - break; - case HMAC_MD5: - gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); - break; - default: - c = NULL; - } - - gcry_md_setkey(c, key, len); - - return c; -} - -void hmac_update(HMACCTX c, const void *data, unsigned long len) { - gcry_md_write(c, data, len); -} - -void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len) { - *len = gcry_md_get_algo_dlen(gcry_md_get_algo(c)); - memcpy(hashmacbuf, gcry_md_read(c, 0), *len); - gcry_md_close(c); -} - -/* the wrapper functions for blowfish */ -static int blowfish_set_key(struct crypto_struct *cipher, void *key, void *IV){ - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_BLOWFISH, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 16)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void blowfish_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void blowfish_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int aes_set_key(struct crypto_struct *cipher, void *key, void *IV) { - int mode=GCRY_CIPHER_MODE_CBC; - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if(strstr(cipher->name,"-ctr")) - mode=GCRY_CIPHER_MODE_CTR; - switch (cipher->keysize) { - case 128: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES128, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - case 192: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES192, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - case 256: - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES256, - mode, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - break; - } - if (gcry_cipher_setkey(cipher->key[0], key, cipher->keysize / 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if(mode == GCRY_CIPHER_MODE_CBC){ - if (gcry_cipher_setiv(cipher->key[0], IV, 16)) { - - SAFE_FREE(cipher->key); - return -1; - } - } else { - if(gcry_cipher_setctr(cipher->key[0],IV,16)){ - SAFE_FREE(cipher->key); - return -1; - } - } - } - - return 0; -} - -static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, - unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, - unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int des3_set_key(struct crypto_struct *cipher, void *key, void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_3DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 24)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void des3_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); -} - -static void des3_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -static int des3_1_set_key(struct crypto_struct *cipher, void *key, void *IV) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[0], key, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - - if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[1], (unsigned char *)key + 8, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[1], (unsigned char *)IV + 8, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - - if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES, - GCRY_CIPHER_MODE_CBC, 0)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setkey(cipher->key[2], (unsigned char *)key + 16, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - if (gcry_cipher_setiv(cipher->key[2], (unsigned char *)IV + 16, 8)) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void des3_1_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_encrypt(cipher->key[0], out, len, in, len); - gcry_cipher_decrypt(cipher->key[1], in, len, out, len); - gcry_cipher_encrypt(cipher->key[2], out, len, in, len); -} - -static void des3_1_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len) { - gcry_cipher_decrypt(cipher->key[2], out, len, in, len); - gcry_cipher_encrypt(cipher->key[1], in, len, out, len); - gcry_cipher_decrypt(cipher->key[0], out, len, in, len); -} - -/* the table of supported ciphers */ -static struct crypto_struct ssh_ciphertab[] = { - { - .name = "blowfish-cbc", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = blowfish_set_key, - .set_decrypt_key = blowfish_set_key, - .cbc_encrypt = blowfish_encrypt, - .cbc_decrypt = blowfish_decrypt - }, - { - .name = "aes128-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_encrypt - }, - { - .name = "aes192-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_encrypt - }, - { - .name = "aes256-ctr", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 256, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_encrypt - }, - { - .name = "aes128-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 128, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_decrypt - }, - { - .name = "aes192-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_decrypt - }, - { - .name = "aes256-cbc", - .blocksize = 16, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 256, - .set_encrypt_key = aes_set_key, - .set_decrypt_key = aes_set_key, - .cbc_encrypt = aes_encrypt, - .cbc_decrypt = aes_decrypt - }, - { - .name = "3des-cbc", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t), - .key = NULL, - .keysize = 192, - .set_encrypt_key = des3_set_key, - .set_decrypt_key = des3_set_key, - .cbc_encrypt = des3_encrypt, - .cbc_decrypt = des3_decrypt - }, - { - .name = "3des-cbc-ssh1", - .blocksize = 8, - .keylen = sizeof(gcry_cipher_hd_t) * 3, - .key = NULL, - .keysize = 192, - .set_encrypt_key = des3_1_set_key, - .set_decrypt_key = des3_1_set_key, - .cbc_encrypt = des3_1_encrypt, - .cbc_decrypt = des3_1_decrypt - }, - { - .name = NULL, - .blocksize = 0, - .keylen = 0, - .key = NULL, - .keysize = 0, - .set_encrypt_key = NULL, - .set_decrypt_key = NULL, - .cbc_encrypt = NULL, - .cbc_decrypt = NULL - } -}; - -#elif defined HAVE_LIBCRYPTO - -#include <openssl/sha.h> -#include <openssl/md5.h> -#include <openssl/dsa.h> -#include <openssl/rsa.h> -#include <openssl/hmac.h> -#include <openssl/opensslv.h> -#ifdef HAVE_OPENSSL_AES_H -#define HAS_AES -#include <openssl/aes.h> -#endif -#ifdef HAVE_OPENSSL_BLOWFISH_H -#define HAS_BLOWFISH -#include <openssl/blowfish.h> -#endif -#ifdef HAVE_OPENSSL_DES_H -#define HAS_DES -#include <openssl/des.h> -#endif - -#if (OPENSSL_VERSION_NUMBER<0x00907000L) -#define OLD_CRYPTO -#endif - -#include "libssh/crypto.h" - -static int alloc_key(struct crypto_struct *cipher) { - cipher->key = malloc(cipher->keylen); - if (cipher->key == NULL) { - return -1; - } - - return 0; -} - -SHACTX sha1_init(void) { - SHACTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - SHA1_Init(c); - - return c; -} - -void sha1_update(SHACTX c, const void *data, unsigned long len) { - SHA1_Update(c,data,len); -} - -void sha1_final(unsigned char *md, SHACTX c) { - SHA1_Final(md, c); - SAFE_FREE(c); -} - -void sha1(unsigned char *digest, int len, unsigned char *hash) { - SHA1(digest, len, hash); -} - -MD5CTX md5_init(void) { - MD5CTX c = malloc(sizeof(*c)); - if (c == NULL) { - return NULL; - } - - MD5_Init(c); - - return c; -} - -void md5_update(MD5CTX c, const void *data, unsigned long len) { - MD5_Update(c, data, len); -} - -void md5_final(unsigned char *md, MD5CTX c) { - MD5_Final(md,c); - SAFE_FREE(c); -} - -HMACCTX hmac_init(const void *key, int len, int type) { - HMACCTX ctx = NULL; - - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) { - return NULL; - } - -#ifndef OLD_CRYPTO - HMAC_CTX_init(ctx); // openssl 0.9.7 requires it. -#endif - - switch(type) { - case HMAC_SHA1: - HMAC_Init(ctx, key, len, EVP_sha1()); - break; - case HMAC_MD5: - HMAC_Init(ctx, key, len, EVP_md5()); - break; - default: - SAFE_FREE(ctx); - ctx = NULL; - } - - return ctx; -} - -void hmac_update(HMACCTX ctx, const void *data, unsigned long len) { - HMAC_Update(ctx, data, len); -} - -void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) { - HMAC_Final(ctx,hashmacbuf,len); - -#ifndef OLD_CRYPTO - HMAC_CTX_cleanup(ctx); -#else - HMAC_cleanup(ctx); -#endif - - SAFE_FREE(ctx); -} - -#ifdef HAS_BLOWFISH -/* the wrapper functions for blowfish */ -static int blowfish_set_key(struct crypto_struct *cipher, void *key){ - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - BF_set_key(cipher->key, 16, key); - } - - return 0; -} - -static void blowfish_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { - BF_cbc_encrypt(in, out, len, cipher->key, IV, BF_ENCRYPT); -} - -static void blowfish_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { - BF_cbc_encrypt(in, out, len, cipher->key, IV, BF_DECRYPT); -} -#endif /* HAS_BLOWFISH */ - -#ifdef HAS_AES -static int aes_set_encrypt_key(struct crypto_struct *cipher, void *key) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (AES_set_encrypt_key(key,cipher->keysize,cipher->key) < 0) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} -static int aes_set_decrypt_key(struct crypto_struct *cipher, void *key) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - if (AES_set_decrypt_key(key,cipher->keysize,cipher->key) < 0) { - SAFE_FREE(cipher->key); - return -1; - } - } - - return 0; -} - -static void aes_encrypt(struct crypto_struct *cipher, void *in, void *out, - unsigned long len, void *IV) { - AES_cbc_encrypt(in, out, len, cipher->key, IV, AES_ENCRYPT); -} - -static void aes_decrypt(struct crypto_struct *cipher, void *in, void *out, - unsigned long len, void *IV) { - AES_cbc_encrypt(in, out, len, cipher->key, IV, AES_DECRYPT); -} - -#ifndef BROKEN_AES_CTR -/* OpenSSL until 0.9.7c has a broken AES_ctr128_encrypt implementation which - * increments the counter from 2^64 instead of 1. It's better not to use it - */ - -/** @internal - * @brief encrypts/decrypts data with stream cipher AES_ctr128. 128 bits is actually - * the size of the CTR counter and incidentally the blocksize, but not the keysize. - * @param len[in] must be a multiple of AES128 block size. - */ -static void aes_ctr128_encrypt(struct crypto_struct *cipher, void *in, void *out, - unsigned long len, void *IV) { - unsigned char tmp_buffer[128/8]; - unsigned int num=0; - /* Some things are special with ctr128 : - * In this case, tmp_buffer is not being used, because it is used to store temporary data - * when an encryption is made on lengths that are not multiple of blocksize. - * Same for num, which is being used to store the current offset in blocksize in CTR - * function. - */ - AES_ctr128_encrypt(in, out, len, cipher->key, IV, tmp_buffer, &num); -} -#endif /* BROKEN_AES_CTR */ -#endif /* HAS_AES */ - -#ifdef HAS_DES -static int des3_set_key(struct crypto_struct *cipher, void *key) { - if (cipher->key == NULL) { - if (alloc_key(cipher) < 0) { - return -1; - } - - DES_set_odd_parity(key); - DES_set_odd_parity((void*)((uint8_t*)key + 8)); - DES_set_odd_parity((void*)((uint8_t*)key + 16)); - DES_set_key_unchecked(key, cipher->key); - DES_set_key_unchecked((void*)((uint8_t*)key + 8), (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule))); - DES_set_key_unchecked((void*)((uint8_t*)key + 16), (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule))); - } - - return 0; -} - -static void des3_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { - DES_ede3_cbc_encrypt(in, out, len, cipher->key, - (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - IV, 1); -} - -static void des3_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { - DES_ede3_cbc_encrypt(in, out, len, cipher->key, - (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - IV, 0); -} - -static void des3_1_encrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Encrypt IV before", IV, 24); -#endif - DES_ncbc_encrypt(in, out, len, cipher->key, IV, 1); - DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)IV + 8), 0); - DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - (void*)((uint8_t*)IV + 16), 1); -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Encrypt IV after", IV, 24); -#endif -} - -static void des3_1_decrypt(struct crypto_struct *cipher, void *in, - void *out, unsigned long len, void *IV) { -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Decrypt IV before", IV, 24); -#endif - - DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)), - IV, 0); - DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)), - (void*)((uint8_t*)IV + 8), 1); - DES_ncbc_encrypt(in, out, len, cipher->key, (void*)((uint8_t*)IV + 16), 0); - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("Decrypt IV after", IV, 24); -#endif -} - -#endif /* HAS_DES */ - -/* - * The table of supported ciphers - * - * WARNING: If you modify crypto_struct, you must make sure the order is - * correct! - */ -static struct crypto_struct ssh_ciphertab[] = { -#ifdef HAS_BLOWFISH - { - "blowfish-cbc", - 8, - sizeof (BF_KEY), - NULL, - 128, - blowfish_set_key, - blowfish_set_key, - blowfish_encrypt, - blowfish_decrypt - }, -#endif /* HAS_BLOWFISH */ -#ifdef HAS_AES -#ifndef BROKEN_AES_CTR - { - "aes128-ctr", - 16, - sizeof(AES_KEY), - NULL, - 128, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, - { - "aes192-ctr", - 16, - sizeof(AES_KEY), - NULL, - 192, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, - { - "aes256-ctr", - 16, - sizeof(AES_KEY), - NULL, - 256, - aes_set_encrypt_key, - aes_set_encrypt_key, - aes_ctr128_encrypt, - aes_ctr128_encrypt - }, -#endif /* BROKEN_AES_CTR */ - { - "aes128-cbc", - 16, - sizeof(AES_KEY), - NULL, - 128, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, - { - "aes192-cbc", - 16, - sizeof(AES_KEY), - NULL, - 192, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, - { - "aes256-cbc", - 16, - sizeof(AES_KEY), - NULL, - 256, - aes_set_encrypt_key, - aes_set_decrypt_key, - aes_encrypt, - aes_decrypt - }, -#endif /* HAS_AES */ -#ifdef HAS_DES - { - "3des-cbc", - 8, - sizeof(DES_key_schedule) * 3, - NULL, - 192, - des3_set_key, - des3_set_key, - des3_encrypt, - des3_decrypt - }, - { - "3des-cbc-ssh1", - 8, - sizeof(DES_key_schedule) * 3, - NULL, - 192, - des3_set_key, - des3_set_key, - des3_1_encrypt, - des3_1_decrypt - }, -#endif /* HAS_DES */ - { - NULL, - 0, - 0, - NULL, - 0, - NULL, - NULL, - NULL, - NULL - } -}; -#endif /* OPENSSL_CRYPTO */ - /* it allocates a new cipher structure based on its offset into the global table */ static struct crypto_struct *cipher_new(int offset) { struct crypto_struct *cipher = NULL; @@ -845,7 +53,7 @@ static struct crypto_struct *cipher_new(int offset) { } /* note the memcpy will copy the pointers : so, you shouldn't free them */ - memcpy(cipher, &ssh_ciphertab[offset], sizeof(*cipher)); + memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher)); return cipher; } @@ -909,7 +117,7 @@ void crypto_free(struct ssh_crypto_struct *crypto){ static int crypt_set_algorithms2(ssh_session session){ const char *wanted; int i = 0; - + struct crypto_struct *ssh_ciphertab=ssh_get_ciphertab(); /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */ /* out */ wanted = session->client_kex.methods[SSH_CRYPT_C_S]; @@ -965,6 +173,7 @@ static int crypt_set_algorithms2(ssh_session session){ static int crypt_set_algorithms1(ssh_session session) { int i = 0; + struct crypto_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, @@ -1003,6 +212,7 @@ int crypt_set_algorithms_server(ssh_session session){ char *client = NULL; char *match = NULL; int i = 0; + struct crypto_struct *ssh_ciphertab=ssh_get_ciphertab(); /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */ enter_function(); |