/*
 * 
 * cipher.c
 * 
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 * 
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 * 
 * Created: Wed Apr 19 17:41:39 1995 ylo
 * 
 */

#include "includes.h"
RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");

#include "ssh.h"
#include "cipher.h"
#include "config.h"

#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#endif
#ifdef HAVE_SSL
#include <ssl/md5.h>
#endif

/*
 * What kind of tripple DES are these 2 routines?
 *
 * Why is there a redundant initialization vector?
 *
 * If only iv3 was used, then, this would till effect have been
 * outer-cbc. However, there is also a private iv1 == iv2 which
 * perhaps makes differential analysis easier. On the other hand, the
 * private iv1 probably makes the CRC-32 attack ineffective. This is a
 * result of that there is no longer any known iv1 to use when
 * choosing the X block.
 */
void
SSH_3CBC_ENCRYPT(des_key_schedule ks1,
		 des_key_schedule ks2, des_cblock * iv2,
		 des_key_schedule ks3, des_cblock * iv3,
		 unsigned char *dest, unsigned char *src,
		 unsigned int len)
{
	des_cblock iv1;

	memcpy(&iv1, iv2, 8);

	des_cbc_encrypt(src, dest, len, ks1, &iv1, DES_ENCRYPT);
	memcpy(&iv1, dest + len - 8, 8);

	des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_DECRYPT);
	memcpy(iv2, &iv1, 8);	/* Note how iv1 == iv2 on entry and exit. */

	des_cbc_encrypt(dest, dest, len, ks3, iv3, DES_ENCRYPT);
	memcpy(iv3, dest + len - 8, 8);
}

void
SSH_3CBC_DECRYPT(des_key_schedule ks1,
		 des_key_schedule ks2, des_cblock * iv2,
		 des_key_schedule ks3, des_cblock * iv3,
		 unsigned char *dest, unsigned char *src,
		 unsigned int len)
{
	des_cblock iv1;

	memcpy(&iv1, iv2, 8);

	des_cbc_encrypt(src, dest, len, ks3, iv3, DES_DECRYPT);
	memcpy(iv3, src + len - 8, 8);

	des_cbc_encrypt(dest, dest, len, ks2, iv2, DES_ENCRYPT);
	memcpy(iv2, dest + len - 8, 8);

	des_cbc_encrypt(dest, dest, len, ks1, &iv1, DES_DECRYPT);
	/* memcpy(&iv1, iv2, 8); */
	/* Note how iv1 == iv2 on entry and exit. */
}

/*
 * SSH uses a variation on Blowfish, all bytes must be swapped before
 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
 */
static void
swap_bytes(const unsigned char *src, unsigned char *dst_, int n)
{
	/* dst must be properly aligned. */
	u_int32_t *dst = (u_int32_t *) dst_;
	union {
		u_int32_t i;
		char c[4];
	} t;

	/* Process 8 bytes every lap. */
	for (n = n / 8; n > 0; n--) {
		t.c[3] = *src++;
		t.c[2] = *src++;
		t.c[1] = *src++;
		t.c[0] = *src++;
		*dst++ = t.i;

		t.c[3] = *src++;
		t.c[2] = *src++;
		t.c[1] = *src++;
		t.c[0] = *src++;
		*dst++ = t.i;
	}
}

/*
 * Names of all encryption algorithms.
 * These must match the numbers defined in cipher.h.
 */
static char *cipher_names[] =
{
	"none",
	"idea",
	"des",
	"3des",
	"tss",
	"rc4",
	"blowfish",
	"reserved",
	"blowfish-cbc",
	"3des-cbc",
	"arcfour",
	"cast128-cbc"
};

/*
 * Returns a bit mask indicating which ciphers are supported by this
 * implementation.  The bit mask has the corresponding bit set of each
 * supported cipher.
 */

unsigned int 
cipher_mask1()
{
	unsigned int mask = 0;
	mask |= 1 << SSH_CIPHER_3DES;		/* Mandatory */
	mask |= 1 << SSH_CIPHER_BLOWFISH;
	return mask;
}
unsigned int 
cipher_mask2()
{
	unsigned int mask = 0;
	mask |= 1 << SSH_CIPHER_BLOWFISH_CBC;
	mask |= 1 << SSH_CIPHER_3DES_CBC;
	mask |= 1 << SSH_CIPHER_ARCFOUR;
	mask |= 1 << SSH_CIPHER_CAST128_CBC;
	return mask;
}
unsigned int 
cipher_mask()
{
	return cipher_mask1() | cipher_mask2();
}

/* Returns the name of the cipher. */

const char *
cipher_name(int cipher)
{
	if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
	    cipher_names[cipher] == NULL)
		fatal("cipher_name: bad cipher number: %d", cipher);
	return cipher_names[cipher];
}

/*
 * Parses the name of the cipher.  Returns the number of the corresponding
 * cipher, or -1 on error.
 */

int
cipher_number(const char *name)
{
	int i;
	for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++)
		if (strcmp(cipher_names[i], name) == 0 &&
		    (cipher_mask() & (1 << i)))
			return i;
	return -1;
}

/*
 * Selects the cipher, and keys if by computing the MD5 checksum of the
 * passphrase and using the resulting 16 bytes as the key.
 */

void 
cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase)
{
	MD5_CTX md;
	unsigned char digest[16];

	MD5_Init(&md);
	MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
	MD5_Final(digest, &md);

	cipher_set_key(context, cipher, digest, 16);

	memset(digest, 0, sizeof(digest));
	memset(&md, 0, sizeof(md));
}

/* Selects the cipher to use and sets the key. */

void 
cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
    int keylen)
{
	unsigned char padded[32];

	/* Set cipher type. */
	context->type = cipher;

	/* Get 32 bytes of key data.  Pad if necessary.  (So that code
	   below does not need to worry about key size). */
	memset(padded, 0, sizeof(padded));
	memcpy(padded, key, keylen < sizeof(padded) ? keylen : sizeof(padded));

	/* Initialize the initialization vector. */
	switch (cipher) {
	case SSH_CIPHER_NONE:
		/*
		 * Has to stay for authfile saving of private key with no
		 * passphrase
		 */
		break;

	case SSH_CIPHER_3DES:
		/*
		 * Note: the least significant bit of each byte of key is
		 * parity, and must be ignored by the implementation.  16
		 * bytes of key are used (first and last keys are the same).
		 */
		if (keylen < 16)
			error("Key length %d is insufficient for 3DES.", keylen);
		des_set_key((void *) padded, context->u.des3.key1);
		des_set_key((void *) (padded + 8), context->u.des3.key2);
		if (keylen <= 16)
			des_set_key((void *) padded, context->u.des3.key3);
		else
			des_set_key((void *) (padded + 16), context->u.des3.key3);
		memset(context->u.des3.iv2, 0, sizeof(context->u.des3.iv2));
		memset(context->u.des3.iv3, 0, sizeof(context->u.des3.iv3));
		break;

	case SSH_CIPHER_BLOWFISH:
		if (keylen < 16)
			error("Key length %d is insufficient for blowfish.", keylen);
		BF_set_key(&context->u.bf.key, keylen, padded);
		memset(context->u.bf.iv, 0, 8);
		break;

	case SSH_CIPHER_3DES_CBC:
	case SSH_CIPHER_BLOWFISH_CBC:
	case SSH_CIPHER_ARCFOUR:
	case SSH_CIPHER_CAST128_CBC:
		fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher));
		break;

	default:
		fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
	}
	memset(padded, 0, sizeof(padded));
}


void 
cipher_set_key_iv(CipherContext * context, int cipher,
    const unsigned char *key, int keylen, 
    const unsigned char *iv, int ivlen)
{
	/* Set cipher type. */
	context->type = cipher;

	/* Initialize the initialization vector. */
	switch (cipher) {
	case SSH_CIPHER_NONE:
		break;

	case SSH_CIPHER_3DES:
	case SSH_CIPHER_BLOWFISH:
		fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher));
		break;

	case SSH_CIPHER_3DES_CBC:
		if (keylen < 24)
			error("Key length %d is insufficient for 3des-cbc.", keylen);
		des_set_key((void *) key, context->u.des3.key1);
		des_set_key((void *) (key+8), context->u.des3.key2);
		des_set_key((void *) (key+16), context->u.des3.key3);
		if (ivlen < 8)
			error("IV length %d is insufficient for 3des-cbc.", ivlen);
		memcpy(context->u.des3.iv3, (char *)iv, 8);
		break;

	case SSH_CIPHER_BLOWFISH_CBC:
		if (keylen < 16)
			error("Key length %d is insufficient for blowfish.", keylen);
		if (ivlen < 8)
			error("IV length %d is insufficient for blowfish.", ivlen);
		BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key);
		memcpy(context->u.bf.iv, (char *)iv, 8);
		break;

	case SSH_CIPHER_ARCFOUR:
		if (keylen < 16)
			error("Key length %d is insufficient for arcfour.", keylen);
		RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key);
		break;

	case SSH_CIPHER_CAST128_CBC:
		if (keylen < 16)
			error("Key length %d is insufficient for cast128.", keylen);
		if (ivlen < 8)
			error("IV length %d is insufficient for cast128.", ivlen);
		CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key);
		memcpy(context->u.cast.iv, (char *)iv, 8);
		break;

	default:
		fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
	}
}

/* Encrypts data using the cipher. */

void 
cipher_encrypt(CipherContext *context, unsigned char *dest,
	       const unsigned char *src, unsigned int len)
{
	if ((len & 7) != 0)
		fatal("cipher_encrypt: bad plaintext length %d", len);

	switch (context->type) {
	case SSH_CIPHER_NONE:
		memcpy(dest, src, len);
		break;

	case SSH_CIPHER_3DES:
		SSH_3CBC_ENCRYPT(context->u.des3.key1,
				 context->u.des3.key2, &context->u.des3.iv2,
				 context->u.des3.key3, &context->u.des3.iv3,
				 dest, (unsigned char *) src, len);
		break;

	case SSH_CIPHER_BLOWFISH:
		swap_bytes(src, dest, len);
		BF_cbc_encrypt(dest, dest, len,
		               &context->u.bf.key, context->u.bf.iv,
			       BF_ENCRYPT);
		swap_bytes(dest, dest, len);
		break;

	case SSH_CIPHER_BLOWFISH_CBC:
		BF_cbc_encrypt((void *)src, dest, len,
		               &context->u.bf.key, context->u.bf.iv,
			       BF_ENCRYPT);
		break;

	case SSH_CIPHER_3DES_CBC:
		des_ede3_cbc_encrypt(src, dest, len,
		    context->u.des3.key1, context->u.des3.key2,
		    context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT);
		break;

	case SSH_CIPHER_ARCFOUR:
		RC4(&context->u.rc4, len, (unsigned char *)src, dest);
		break;

	case SSH_CIPHER_CAST128_CBC:
		CAST_cbc_encrypt(src, dest, len,
		    &context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT);
		break;

	default:
		fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type));
	}
}

/* Decrypts data using the cipher. */

void 
cipher_decrypt(CipherContext *context, unsigned char *dest,
	       const unsigned char *src, unsigned int len)
{
	if ((len & 7) != 0)
		fatal("cipher_decrypt: bad ciphertext length %d", len);

	switch (context->type) {
	case SSH_CIPHER_NONE:
		memcpy(dest, src, len);
		break;

	case SSH_CIPHER_3DES:
		SSH_3CBC_DECRYPT(context->u.des3.key1,
				 context->u.des3.key2, &context->u.des3.iv2,
				 context->u.des3.key3, &context->u.des3.iv3,
				 dest, (unsigned char *) src, len);
		break;

	case SSH_CIPHER_BLOWFISH:
		swap_bytes(src, dest, len);
		BF_cbc_encrypt((void *) dest, dest, len,
			       &context->u.bf.key, context->u.bf.iv,
			       BF_DECRYPT);
		swap_bytes(dest, dest, len);
		break;

	case SSH_CIPHER_BLOWFISH_CBC:
		BF_cbc_encrypt((void *) src, dest, len,
			       &context->u.bf.key, context->u.bf.iv,
			       BF_DECRYPT);
		break;

	case SSH_CIPHER_3DES_CBC:
		des_ede3_cbc_encrypt(src, dest, len,
		    context->u.des3.key1, context->u.des3.key2,
		    context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT);
		break;

	case SSH_CIPHER_ARCFOUR:
		RC4(&context->u.rc4, len, (unsigned char *)src, dest);
		break;

	case SSH_CIPHER_CAST128_CBC:
		CAST_cbc_encrypt(src, dest, len,
		    &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT);
		break;

	default:
		fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
	}
}
