/*

rsa.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Fri Mar  3 22:07:06 1995 ylo

Description of the RSA algorithm can be found e.g. from the following sources:

  Bruce Schneier: Applied Cryptography.  John Wiley & Sons, 1994.

  Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to 
    Computer Security.  Prentice-Hall, 1989.

  Man Young Rhee: Cryptography and Secure Data Communications.  McGraw-Hill, 
    1994.

  R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications
    System and Method.  US Patent 4,405,829, 1983.

  Hans Riesel: Prime Numbers and Computer Methods for Factorization.  
    Birkhauser, 1994.

  The RSA Frequently Asked Questions document by RSA Data Security, Inc., 1995.

  RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as included
    below:

    gone - had to be deleted - what a pity

*/

#include "includes.h"
RCSID("$Id: rsa.c,v 1.1.1.1 1999/10/27 03:42:44 damien Exp $");

#include "rsa.h"
#include "ssh.h"
#include "xmalloc.h"

int rsa_verbose = 1;

int
rsa_alive()
{
  RSA *key;

  key = RSA_generate_key(32, 3, NULL, NULL);
  if (key == NULL)
    return (0);
  RSA_free(key);
  return (1);
}

/* Generates RSA public and private keys.  This initializes the data
   structures; they should be freed with rsa_clear_private_key and
   rsa_clear_public_key. */

void
rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits)
{
  RSA *key;

  if (rsa_verbose) {
    printf("Generating RSA keys:  "); 
    fflush(stdout);
  }

  key = RSA_generate_key(bits, 35, NULL, NULL);

  assert(key != NULL);

  /* Copy public key parameters */
  pub->n = BN_new();
  BN_copy(pub->n, key->n);
  pub->e = BN_new();
  BN_copy(pub->e, key->e);

  /* Copy private key parameters */
  prv->n = BN_new();
  BN_copy(prv->n, key->n);
  prv->e = BN_new();
  BN_copy(prv->e, key->e);
  prv->d = BN_new();
  BN_copy(prv->d, key->d);
  prv->p = BN_new();
  BN_copy(prv->p, key->p);
  prv->q = BN_new();
  BN_copy(prv->q, key->q);

  prv->dmp1 = BN_new();
  BN_copy(prv->dmp1, key->dmp1);

  prv->dmq1 = BN_new();
  BN_copy(prv->dmq1, key->dmq1);

  prv->iqmp = BN_new();
  BN_copy(prv->iqmp, key->iqmp);

  RSA_free(key);
  
  if (rsa_verbose)
    printf("Key generation complete.\n");
}

void
rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA* key)
{
  char *inbuf, *outbuf;
  int len;

  if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
    fatal("rsa_public_encrypt() exponent too small or not odd");

  len = BN_num_bytes(key->n);
  outbuf = xmalloc(len);

  len = BN_num_bytes(in);
  inbuf = xmalloc(len);
  BN_bn2bin(in, inbuf);

  if ((len = RSA_public_encrypt(len, inbuf, outbuf, key,
				RSA_PKCS1_PADDING)) <= 0)
    fatal("rsa_public_encrypt() failed");

  BN_bin2bn(outbuf, len, out);

  xfree(outbuf);
  xfree(inbuf);
}

void
rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{
  char *inbuf, *outbuf;
  int len;

  len = BN_num_bytes(key->n);
  outbuf = xmalloc(len);

  len = BN_num_bytes(in);
  inbuf = xmalloc(len);
  BN_bn2bin(in, inbuf);

  if ((len = RSA_private_decrypt(len, inbuf, outbuf, key,
				 RSA_SSLV23_PADDING)) <= 0)
    fatal("rsa_private_decrypt() failed");

  BN_bin2bn(outbuf, len, out);

  xfree(outbuf);
  xfree(inbuf);
}

/* Set whether to output verbose messages during key generation. */

void
rsa_set_verbose(int verbose)
{
  rsa_verbose = verbose;
}
