wrapper.c   wrapper.c 
skipping to change at line 34 skipping to change at line 34
/* /*
* Why a wrapper? * Why a wrapper?
* *
* Let's say you want to port libssh from libcrypto of openssl to libfoo * Let's say you want to port libssh from libcrypto of openssl to libfoo
* you are going to spend hours to remove every references to SHA1_Update() * you are going to spend hours to remove every references to SHA1_Update()
* to libfoo_sha1_update after the work is finished, you're going to have * to libfoo_sha1_update after the work is finished, you're going to have
* only this file to modify it's not needed to say that your modifications * only this file to modify it's not needed to say that your modifications
* are welcome. * are welcome.
*/ */
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "libssh/priv.h" #include "libssh/priv.h"
#include "libssh/session.h"
#include "libssh/crypto.h"
#include "libssh/wrapper.h"
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
#include <gcrypt.h> #include <gcrypt.h>
#include "libssh/crypto.h"
static int alloc_key(struct crypto_struct *cipher) { static int alloc_key(struct crypto_struct *cipher) {
cipher->key = malloc(cipher->keylen); cipher->key = malloc(cipher->keylen);
if (cipher->key == NULL) { if (cipher->key == NULL) {
return -1; return -1;
} }
return 0; return 0;
} }
SHACTX sha1_init(void) { SHACTX sha1_init(void) {
skipping to change at line 265 skipping to change at line 267
if (gcry_cipher_setiv(cipher->key[0], IV, 8)) { if (gcry_cipher_setiv(cipher->key[0], IV, 8)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES, if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES,
GCRY_CIPHER_MODE_CBC, 0)) { GCRY_CIPHER_MODE_CBC, 0)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_setkey(cipher->key[1], key + 8, 8)) { if (gcry_cipher_setkey(cipher->key[1], (unsigned char *)key + 8, 8)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_setiv(cipher->key[1], IV + 8, 8)) { if (gcry_cipher_setiv(cipher->key[1], (unsigned char *)IV + 8, 8)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES, if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES,
GCRY_CIPHER_MODE_CBC, 0)) { GCRY_CIPHER_MODE_CBC, 0)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_setkey(cipher->key[2], key + 16, 8)) { if (gcry_cipher_setkey(cipher->key[2], (unsigned char *)key + 16, 8)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
if (gcry_cipher_setiv(cipher->key[2], IV + 16, 8)) { if (gcry_cipher_setiv(cipher->key[2], (unsigned char *)IV + 16, 8)) {
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
return -1; return -1;
} }
} }
return 0; return 0;
} }
static void des3_1_encrypt(struct crypto_struct *cipher, void *in, static void des3_1_encrypt(struct crypto_struct *cipher, void *in,
void *out, unsigned long len) { void *out, unsigned long len) {
skipping to change at line 408 skipping to change at line 410
#endif #endif
#ifdef HAVE_OPENSSL_BLOWFISH_H #ifdef HAVE_OPENSSL_BLOWFISH_H
#define HAS_BLOWFISH #define HAS_BLOWFISH
#include <openssl/blowfish.h> #include <openssl/blowfish.h>
#endif #endif
#ifdef HAVE_OPENSSL_DES_H #ifdef HAVE_OPENSSL_DES_H
#define HAS_DES #define HAS_DES
#include <openssl/des.h> #include <openssl/des.h>
#endif #endif
#if (OPENSSL_VERSION_NUMBER<0x009070000) #if (OPENSSL_VERSION_NUMBER<0x00907000L)
#define OLD_CRYPTO #define OLD_CRYPTO
#endif #endif
#include "libssh/crypto.h" #include "libssh/crypto.h"
static int alloc_key(struct crypto_struct *cipher) { static int alloc_key(struct crypto_struct *cipher) {
cipher->key = malloc(cipher->keylen); cipher->key = malloc(cipher->keylen);
if (cipher->key == NULL) { if (cipher->key == NULL) {
return -1; return -1;
} }
skipping to change at line 580 skipping to change at line 582
#endif /* HAS_AES */ #endif /* HAS_AES */
#ifdef HAS_DES #ifdef HAS_DES
static int des3_set_key(struct crypto_struct *cipher, void *key) { static int des3_set_key(struct crypto_struct *cipher, void *key) {
if (cipher->key == NULL) { if (cipher->key == NULL) {
if (alloc_key(cipher) < 0) { if (alloc_key(cipher) < 0) {
return -1; return -1;
} }
DES_set_odd_parity(key); DES_set_odd_parity(key);
DES_set_odd_parity(key + 8); DES_set_odd_parity((void*)((uint8_t*)key + 8));
DES_set_odd_parity(key + 16); DES_set_odd_parity((void*)((uint8_t*)key + 16));
DES_set_key_unchecked(key, cipher->key); DES_set_key_unchecked(key, cipher->key);
DES_set_key_unchecked(key + 8, cipher->key + sizeof(DES_key_schedule)); DES_set_key_unchecked((void*)((uint8_t*)key + 8), (void*)((uint8_t*)cip
DES_set_key_unchecked(key + 16, cipher->key + 2 * sizeof(DES_key_schedu her->key + sizeof(DES_key_schedule)));
le)); DES_set_key_unchecked((void*)((uint8_t*)key + 16), (void*)((uint8_t*)ci
pher->key + 2 * sizeof(DES_key_schedule)));
} }
return 0; return 0;
} }
static void des3_encrypt(struct crypto_struct *cipher, void *in, static void des3_encrypt(struct crypto_struct *cipher, void *in,
void *out, unsigned long len, void *IV) { void *out, unsigned long len, void *IV) {
DES_ede3_cbc_encrypt(in, out, len, cipher->key, DES_ede3_cbc_encrypt(in, out, len, cipher->key,
cipher->key + sizeof(DES_key_schedule), (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)),
cipher->key + 2 * sizeof(DES_key_schedule), (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)),
IV, 1); IV, 1);
} }
static void des3_decrypt(struct crypto_struct *cipher, void *in, static void des3_decrypt(struct crypto_struct *cipher, void *in,
void *out, unsigned long len, void *IV) { void *out, unsigned long len, void *IV) {
DES_ede3_cbc_encrypt(in, out, len, cipher->key, DES_ede3_cbc_encrypt(in, out, len, cipher->key,
cipher->key + sizeof(DES_key_schedule), (void*)((uint8_t*)cipher->key + sizeof(DES_key_schedule)),
cipher->key + 2 * sizeof(DES_key_schedule), (void*)((uint8_t*)cipher->key + 2 * sizeof(DES_key_schedule)),
IV, 0); IV, 0);
} }
static void des3_1_encrypt(struct crypto_struct *cipher, void *in, static void des3_1_encrypt(struct crypto_struct *cipher, void *in,
void *out, unsigned long len, void *IV) { void *out, unsigned long len, void *IV) {
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Encrypt IV before", IV, 24); ssh_print_hexa("Encrypt IV before", IV, 24);
#endif #endif
DES_ncbc_encrypt(in, out, len, cipher->key, IV, 1); DES_ncbc_encrypt(in, out, len, cipher->key, IV, 1);
DES_ncbc_encrypt(out, in, len, cipher->key + sizeof(DES_key_schedule), DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES
IV + 8, 0); _key_schedule)),
DES_ncbc_encrypt(in, out, len, cipher->key + 2 * sizeof(DES_key_schedule) (void*)((uint8_t*)IV + 8), 0);
, DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof
IV + 16, 1); (DES_key_schedule)),
(void*)((uint8_t*)IV + 16), 1);
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Encrypt IV after", IV, 24); ssh_print_hexa("Encrypt IV after", IV, 24);
#endif #endif
} }
static void des3_1_decrypt(struct crypto_struct *cipher, void *in, static void des3_1_decrypt(struct crypto_struct *cipher, void *in,
void *out, unsigned long len, void *IV) { void *out, unsigned long len, void *IV) {
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Decrypt IV before", IV, 24); ssh_print_hexa("Decrypt IV before", IV, 24);
#endif #endif
DES_ncbc_encrypt(in, out, len, cipher->key + 2 * sizeof(DES_key_schedule) , DES_ncbc_encrypt(in, out, len, (void*)((uint8_t*)cipher->key + 2 * sizeof (DES_key_schedule)),
IV, 0); IV, 0);
DES_ncbc_encrypt(out, in, len, cipher->key + sizeof(DES_key_schedule), DES_ncbc_encrypt(out, in, len, (void*)((uint8_t*)cipher->key + sizeof(DES
IV + 8, 1); _key_schedule)),
DES_ncbc_encrypt(in, out, len, cipher->key, IV + 16, 0); (void*)((uint8_t*)IV + 8), 1);
DES_ncbc_encrypt(in, out, len, cipher->key, (void*)((uint8_t*)IV + 16), 0
);
#ifdef DEBUG_CRYPTO #ifdef DEBUG_CRYPTO
ssh_print_hexa("Decrypt IV after", IV, 24); ssh_print_hexa("Decrypt IV after", IV, 24);
#endif #endif
} }
#endif /* HAS_DES */ #endif /* HAS_DES */
/* the table of supported ciphers */ /*
* 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[] = { static struct crypto_struct ssh_ciphertab[] = {
#ifdef HAS_BLOWFISH #ifdef HAS_BLOWFISH
{ {
.name = "blowfish-cbc", "blowfish-cbc",
.blocksize = 8, 8,
.keylen = sizeof (BF_KEY), sizeof (BF_KEY),
.key = NULL, NULL,
.keysize = 128, 128,
.set_encrypt_key = blowfish_set_key, blowfish_set_key,
.set_decrypt_key = blowfish_set_key, blowfish_set_key,
.cbc_encrypt = blowfish_encrypt, blowfish_encrypt,
.cbc_decrypt = blowfish_decrypt blowfish_decrypt
}, },
#endif /* HAS_BLOWFISH */ #endif /* HAS_BLOWFISH */
#ifdef HAS_AES #ifdef HAS_AES
{ {
.name = "aes128-cbc", "aes128-cbc",
.blocksize = 16, 16,
.keylen = sizeof(AES_KEY), sizeof(AES_KEY),
.key = NULL, NULL,
.keysize = 128, 128,
.set_encrypt_key = aes_set_encrypt_key, aes_set_encrypt_key,
.set_decrypt_key = aes_set_decrypt_key, aes_set_decrypt_key,
.cbc_encrypt = aes_encrypt, aes_encrypt,
.cbc_decrypt = aes_decrypt aes_decrypt
}, },
{ {
.name = "aes192-cbc", "aes192-cbc",
.blocksize = 16, 16,
.keylen = sizeof(AES_KEY), sizeof(AES_KEY),
.key = NULL, NULL,
.keysize = 192, 192,
.set_encrypt_key = aes_set_encrypt_key, aes_set_encrypt_key,
.set_decrypt_key = aes_set_decrypt_key, aes_set_decrypt_key,
.cbc_encrypt = aes_encrypt, aes_encrypt,
.cbc_decrypt = aes_decrypt aes_decrypt
}, },
{ {
.name = "aes256-cbc", "aes256-cbc",
.blocksize = 16, 16,
.keylen = sizeof(AES_KEY), sizeof(AES_KEY),
.key = NULL, NULL,
.keysize = 256, 256,
.set_encrypt_key = aes_set_encrypt_key, aes_set_encrypt_key,
.set_decrypt_key = aes_set_decrypt_key, aes_set_decrypt_key,
.cbc_encrypt = aes_encrypt, aes_encrypt,
.cbc_decrypt = aes_decrypt aes_decrypt
}, },
#endif /* HAS_AES */ #endif /* HAS_AES */
#ifdef HAS_DES #ifdef HAS_DES
{ {
.name = "3des-cbc", "3des-cbc",
.blocksize = 8, 8,
.keylen = sizeof(DES_key_schedule) * 3, sizeof(DES_key_schedule) * 3,
.key = NULL, NULL,
.keysize = 192, 192,
.set_encrypt_key = des3_set_key, des3_set_key,
.set_decrypt_key = des3_set_key, des3_set_key,
.cbc_encrypt = des3_encrypt, des3_encrypt,
.cbc_decrypt = des3_decrypt des3_decrypt
}, },
{ {
.name = "3des-cbc-ssh1", "3des-cbc-ssh1",
.blocksize = 8, 8,
.keylen = sizeof(DES_key_schedule) * 3, sizeof(DES_key_schedule) * 3,
.key = NULL, NULL,
.keysize = 192, 192,
.set_encrypt_key = des3_set_key, des3_set_key,
.set_decrypt_key = des3_set_key, des3_set_key,
.cbc_encrypt = des3_1_encrypt, des3_1_encrypt,
.cbc_decrypt = des3_1_decrypt des3_1_decrypt
}, },
#endif /* HAS_DES */ #endif /* HAS_DES */
{ {
.name = NULL, NULL,
.blocksize = 0, 0,
.keylen = 0, 0,
.key = NULL, NULL,
.keysize = 0, 0,
.set_encrypt_key = NULL, NULL,
.set_decrypt_key = NULL, NULL,
.cbc_encrypt = NULL, NULL,
.cbc_decrypt = NULL NULL
} }
}; };
#endif /* OPENSSL_CRYPTO */ #endif /* OPENSSL_CRYPTO */
/* it allocates a new cipher structure based on its offset into the global table */ /* it allocates a new cipher structure based on its offset into the global table */
static struct crypto_struct *cipher_new(int offset) { static struct crypto_struct *cipher_new(int offset) {
struct crypto_struct *cipher = NULL; struct crypto_struct *cipher = NULL;
cipher = malloc(sizeof(struct crypto_struct)); cipher = malloc(sizeof(struct crypto_struct));
if (cipher == NULL) { if (cipher == NULL) {
skipping to change at line 766 skipping to change at line 773
} }
#elif defined HAVE_LIBCRYPTO #elif defined HAVE_LIBCRYPTO
/* destroy the key */ /* destroy the key */
memset(cipher->key, 0, cipher->keylen); memset(cipher->key, 0, cipher->keylen);
#endif #endif
SAFE_FREE(cipher->key); SAFE_FREE(cipher->key);
} }
SAFE_FREE(cipher); SAFE_FREE(cipher);
} }
CRYPTO *crypto_new(void) { struct ssh_crypto_struct *crypto_new(void) {
CRYPTO *crypto; struct ssh_crypto_struct *crypto;
crypto = malloc(sizeof(CRYPTO)); crypto = malloc(sizeof(struct ssh_crypto_struct));
if (crypto == NULL) { if (crypto == NULL) {
return NULL; return NULL;
} }
ZERO_STRUCTP(crypto);
memset(crypto, 0, sizeof(CRYPTO));
return crypto; return crypto;
} }
void crypto_free(CRYPTO *crypto){ void crypto_free(struct ssh_crypto_struct *crypto){
if (crypto == NULL) { if (crypto == NULL) {
return; return;
} }
SAFE_FREE(crypto->server_pubkey); SAFE_FREE(crypto->server_pubkey);
cipher_free(crypto->in_cipher); cipher_free(crypto->in_cipher);
cipher_free(crypto->out_cipher); cipher_free(crypto->out_cipher);
bignum_free(crypto->e); bignum_free(crypto->e);
skipping to change at line 801 skipping to change at line 806
bignum_free(crypto->x); bignum_free(crypto->x);
bignum_free(crypto->y); bignum_free(crypto->y);
bignum_free(crypto->k); bignum_free(crypto->k);
/* lot of other things */ /* lot of other things */
/* i'm lost in my own code. good work */ /* i'm lost in my own code. good work */
memset(crypto,0,sizeof(*crypto)); memset(crypto,0,sizeof(*crypto));
SAFE_FREE(crypto); SAFE_FREE(crypto);
} }
static int crypt_set_algorithms2(SSH_SESSION *session){ static int crypt_set_algorithms2(ssh_session session){
const char *wanted; const char *wanted;
int i = 0; int i = 0;
/* we must scan the kex entries to find crypto algorithms and set their a ppropriate structure */ /* we must scan the kex entries to find crypto algorithms and set their a ppropriate structure */
/* out */ /* out */
wanted = session->client_kex.methods[SSH_CRYPT_C_S]; wanted = session->client_kex.methods[SSH_CRYPT_C_S];
while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) { while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
i++; i++;
} }
skipping to change at line 858 skipping to change at line 863
if (strstr(session->client_kex.methods[SSH_COMP_C_S], "zlib")) { if (strstr(session->client_kex.methods[SSH_COMP_C_S], "zlib")) {
session->next_crypto->do_compress_out = 1; session->next_crypto->do_compress_out = 1;
} }
if (strstr(session->client_kex.methods[SSH_COMP_S_C], "zlib")) { if (strstr(session->client_kex.methods[SSH_COMP_S_C], "zlib")) {
session->next_crypto->do_compress_in = 1; session->next_crypto->do_compress_in = 1;
} }
return SSH_OK; return SSH_OK;
} }
static int crypt_set_algorithms1(SSH_SESSION *session) { static int crypt_set_algorithms1(ssh_session session) {
int i = 0; int i = 0;
/* 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")) { "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 not found!");
skipping to change at line 887 skipping to change at line 892
session->next_crypto->in_cipher = cipher_new(i); session->next_crypto->in_cipher = cipher_new(i);
if (session->next_crypto->in_cipher == NULL) { if (session->next_crypto->in_cipher == NULL) {
ssh_set_error(session, SSH_FATAL, "No space left"); ssh_set_error(session, SSH_FATAL, "No space left");
return SSH_ERROR; return SSH_ERROR;
} }
return SSH_OK; return SSH_OK;
} }
int crypt_set_algorithms(SSH_SESSION *session) { int crypt_set_algorithms(ssh_session session) {
return (session->version == 1) ? crypt_set_algorithms1(session) : return (session->version == 1) ? crypt_set_algorithms1(session) :
crypt_set_algorithms2(session); crypt_set_algorithms2(session);
} }
// TODO Obviously too much cut and paste here // TODO Obviously too much cut and paste here
int crypt_set_algorithms_server(SSH_SESSION *session){ int crypt_set_algorithms_server(ssh_session session){
char *server = NULL; char *server = NULL;
char *client = NULL; char *client = NULL;
char *match = NULL; char *match = NULL;
int i = 0; int i = 0;
/* we must scan the kex entries to find crypto algorithms and set their appropriate structure */ /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */
enter_function(); enter_function();
/* out */ /* out */
server = session->server_kex.methods[SSH_CRYPT_S_C]; server = session->server_kex.methods[SSH_CRYPT_S_C];
client = session->client_kex.methods[SSH_CRYPT_S_C]; client = session->client_kex.methods[SSH_CRYPT_S_C];
 End of changes. 28 change blocks. 
106 lines changed or deleted 115 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/