/*

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.6 1999/11/16 02:37:16 damien Exp $");

#include "ssh.h"
#include "cipher.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, 
		 void *dest, void *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,
		 void *dest, void *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)
{
  u_int32_t *dst = (u_int32_t *)dst_;	/* dst must be properly aligned. */
  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;
    }
}

void (*cipher_attack_detected)(const char *fmt, ...) = fatal;

static inline
void
detect_cbc_attack(const unsigned char *src,
		  unsigned int len)
{
  return;
  
  log("CRC-32 CBC insertion attack detected");
  cipher_attack_detected("CRC-32 CBC insertion attack detected");
}

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

/* 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_mask()
{
  unsigned int mask = 0;
  mask |= 1 << SSH_CIPHER_3DES;	/* Mandatory */
  mask |= 1 << SSH_CIPHER_BLOWFISH;
  return mask;
}

/* 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, int for_encryption)
{
  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, for_encryption);
  
  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, int for_encryption)
{
  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:
      BF_set_key(&context->u.bf.key, keylen, padded);
      memset(context->u.bf.iv, 0, 8);
      break;

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

/* 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, (void*)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;

    default:
      fatal("cipher_encrypt: unknown cipher: %d", 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:
      /* CRC-32 attack? */
      SSH_3CBC_DECRYPT(context->u.des3.key1,
		       context->u.des3.key2, &context->u.des3.iv2,
		       context->u.des3.key3, &context->u.des3.iv3,
		       dest, (void*)src, len);
      break;

    case SSH_CIPHER_BLOWFISH:
      detect_cbc_attack(src, len);
      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;

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