/*
 * 
 * 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.18 2000/04/13 02:26:36 damien Exp $");

#include "ssh.h"
#include "cipher.h"
#include "xmalloc.h"

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

/*
 * This is used by SSH1:
 *
 * What kind of triple 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. */
}

/*
 * SSH1 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 name: %d", cipher);
	return cipher_names[cipher];
}

/* Returns 1 if the name of the ciphers are valid. */

#define	CIPHER_SEP	","
int
ciphers_valid(const char *names)
{
	char *ciphers;
	char *p;
	int i;

	if (strcmp(names, "") == 0)
		return 0;
	ciphers = xstrdup(names);
	for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) {
		i = cipher_number(p);
		if (i == -1 || !(cipher_mask2() & (1 << i))) {
			xfree(ciphers);
			return 0;
		}
	}
	xfree(ciphers);
	return 1;
}

/*
 * 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));
	}
}
