/* crypto/rsa/rsa_pmeth.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2006.
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include "evp_locl.h"
#include "rsa_locl.h"

/* RSA pkey context structure */

typedef struct
	{
	/* Key gen parameters */
	int nbits;
	BIGNUM *pub_exp;
	/* Keygen callback info */
	int gentmp[2];
	/* RSA padding mode */
	int pad_mode;
	/* message digest */
	const EVP_MD *md;
	/* PSS/OAEP salt length */
	int saltlen;
	/* Temp buffer */
	unsigned char *tbuf;
	} RSA_PKEY_CTX;

static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
	{
	RSA_PKEY_CTX *rctx;
	rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
	if (!rctx)
		return 0;
	rctx->nbits = 1024;
	rctx->pub_exp = NULL;
	rctx->pad_mode = RSA_PKCS1_PADDING;
	rctx->md = NULL;
	rctx->tbuf = NULL;

	rctx->saltlen = -2;

	ctx->data = rctx;
	ctx->keygen_info = rctx->gentmp;
	ctx->keygen_info_count = 2;
	
	return 1;
	}

static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
	{
	RSA_PKEY_CTX *dctx, *sctx;
	if (!pkey_rsa_init(dst))
		return 0;
       	sctx = src->data;
	dctx = dst->data;
	dctx->nbits = sctx->nbits;
	if (sctx->pub_exp)
		{
		dctx->pub_exp = BN_dup(sctx->pub_exp);
		if (!dctx->pub_exp)
			return 0;
		}
	dctx->pad_mode = sctx->pad_mode;
	dctx->md = sctx->md;
	return 1;
	}

static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
	{
	if (ctx->tbuf)
		return 1;
	ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
	if (!ctx->tbuf)
		return 0;
	return 1;
	}

static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
	{
	RSA_PKEY_CTX *rctx = ctx->data;
	if (rctx)
		{
		if (rctx->pub_exp)
			BN_free(rctx->pub_exp);
		if (rctx->tbuf)
			OPENSSL_free(rctx->tbuf);
		OPENSSL_free(rctx);
		}
	}

static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
					const unsigned char *tbs, size_t tbslen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;

	if (rctx->md)
		{
		if (tbslen != (size_t)EVP_MD_size(rctx->md))
			{
			RSAerr(RSA_F_PKEY_RSA_SIGN,
					RSA_R_INVALID_DIGEST_LENGTH);
			return -1;
			}
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			memcpy(rctx->tbuf, tbs, tbslen);
			rctx->tbuf[tbslen] =
				RSA_X931_hash_id(EVP_MD_type(rctx->md));
			ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
						sig, rsa, RSA_X931_PADDING);
			}
		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
			{
			unsigned int sltmp;
			ret = RSA_sign(EVP_MD_type(rctx->md),
						tbs, tbslen, sig, &sltmp, rsa);
			if (ret <= 0)
				return ret;
			ret = sltmp;
			}
		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
						rctx->md, rctx->saltlen))
				return -1;
			ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
						sig, rsa, RSA_NO_PADDING);
			}
		else
			return -1;
		}
	else
		ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*siglen = ret;
	return 1;
	}


static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
					unsigned char *rout, size_t *routlen,
					const unsigned char *sig, size_t siglen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = ctx->data;

	if (rctx->md)
		{
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (!setup_tbuf(rctx, ctx))
				return -1;
			ret = RSA_public_decrypt(siglen, sig,
						rctx->tbuf, ctx->pkey->pkey.rsa,
						RSA_X931_PADDING);
			if (ret < 1)
				return 0;
			ret--;
			if (rctx->tbuf[ret] !=
				RSA_X931_hash_id(EVP_MD_type(rctx->md)))
				{
				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
						RSA_R_ALGORITHM_MISMATCH);
				return 0;
				}
			if (ret != EVP_MD_size(rctx->md))
				{
				RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
					RSA_R_INVALID_DIGEST_LENGTH);
				return 0;
				}
			if (rout)
				memcpy(rout, rctx->tbuf, ret);
			}
		else if (rctx->pad_mode == RSA_PKCS1_PADDING)
			{
			size_t sltmp;
			ret = int_rsa_verify(EVP_MD_type(rctx->md),
						NULL, 0, rout, &sltmp,
					sig, siglen, ctx->pkey->pkey.rsa);
			if (ret <= 0)
				return 0;
			ret = sltmp;
			}
		else
			return -1;
		}
	else
		ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*routlen = ret;
	return 1;
	}

static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
					const unsigned char *sig, size_t siglen,
					const unsigned char *tbs, size_t tbslen)
	{
	RSA_PKEY_CTX *rctx = ctx->data;
	RSA *rsa = ctx->pkey->pkey.rsa;
	size_t rslen;
	if (rctx->md)
		{
		if (rctx->pad_mode == RSA_PKCS1_PADDING)
			return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
					sig, siglen, rsa);
		if (rctx->pad_mode == RSA_X931_PADDING)
			{
			if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
					sig, siglen) <= 0)
				return 0;
			}
		else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
			{
			int ret;
			if (!setup_tbuf(rctx, ctx))
				return -1;
			ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
							rsa, RSA_NO_PADDING);
			if (ret <= 0)
				return 0;
			ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
						rctx->tbuf, rctx->saltlen);
			if (ret <= 0)
				return 0;
			return 1;
			}
		else
			return -1;
		}
	else
		{
		if (!setup_tbuf(rctx, ctx))
			return -1;
		rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
						rsa, rctx->pad_mode);
		if (rslen == 0)
			return 0;
		}

	if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
		return 0;

	return 1;
			
	}
	

static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
					unsigned char *out, size_t *outlen,
					const unsigned char *in, size_t inlen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = ctx->data;
	ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*outlen = ret;
	return 1;
	}

static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
					unsigned char *out, size_t *outlen,
					const unsigned char *in, size_t inlen)
	{
	int ret;
	RSA_PKEY_CTX *rctx = ctx->data;
	ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
							rctx->pad_mode);
	if (ret < 0)
		return ret;
	*outlen = ret;
	return 1;
	}

static int check_padding_md(const EVP_MD *md, int padding)
	{
	if (!md)
		return 1;

	if (padding == RSA_NO_PADDING)
		{
		RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
		return 0;
		}

	if (padding == RSA_X931_PADDING)
		{
		if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
			{
			RSAerr(RSA_F_CHECK_PADDING_MD,
						RSA_R_INVALID_X931_DIGEST);
			return 0;
			}
		return 1;
		}

	return 1;
	}
			

static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
	{
	RSA_PKEY_CTX *rctx = ctx->data;
	switch (type)
		{
		case EVP_PKEY_CTRL_RSA_PADDING:
		if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
			{
			if (!check_padding_md(rctx->md, p1))
				return 0;
			if (p1 == RSA_PKCS1_PSS_PADDING) 
				{
				if (!(ctx->operation &
				     (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
					goto bad_pad;
				if (!rctx->md)
					rctx->md = EVP_sha1();
				}
			if (p1 == RSA_PKCS1_OAEP_PADDING) 
				{
				if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
					goto bad_pad;
				if (!rctx->md)
					rctx->md = EVP_sha1();
				}
			rctx->pad_mode = p1;
			return 1;
			}
		bad_pad:
		RSAerr(RSA_F_PKEY_RSA_CTRL,
				RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
		return -2;

		case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
		if (p1 < -2)
			return -2;
		if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
			{
			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
			return -2;
			}
		rctx->saltlen = p1;
		return 1;

		case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
		if (p1 < 256)
			{
			RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
			return -2;
			}
		rctx->nbits = p1;
		return 1;

		case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
		if (!p2)
			return -2;
		rctx->pub_exp = p2;
		return 1;

		case EVP_PKEY_CTRL_MD:
		if (!check_padding_md(p2, rctx->pad_mode))
			return 0;
		rctx->md = p2;
		return 1;

		case EVP_PKEY_CTRL_DIGESTINIT:
		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
#ifndef OPENSSL_NO_CMS
		case EVP_PKEY_CTRL_CMS_ENCRYPT:
		case EVP_PKEY_CTRL_CMS_DECRYPT:
		case EVP_PKEY_CTRL_CMS_SIGN:
#endif
		return 1;
		case EVP_PKEY_CTRL_PEER_KEY:
			RSAerr(RSA_F_PKEY_RSA_CTRL,
			RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
			return -2;	

		default:
		return -2;

		}
	}
			
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
			const char *type, const char *value)
	{
	if (!value)
		{
		RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
		return 0;
		}
	if (!strcmp(type, "rsa_padding_mode"))
		{
		int pm;
		if (!strcmp(value, "pkcs1"))
			pm = RSA_PKCS1_PADDING;
		else if (!strcmp(value, "sslv23"))
			pm = RSA_SSLV23_PADDING;
		else if (!strcmp(value, "none"))
			pm = RSA_NO_PADDING;
		else if (!strcmp(value, "oeap"))
			pm = RSA_PKCS1_OAEP_PADDING;
		else if (!strcmp(value, "x931"))
			pm = RSA_X931_PADDING;
		else if (!strcmp(value, "pss"))
			pm = RSA_PKCS1_PSS_PADDING;
		else
			{
			RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
						RSA_R_UNKNOWN_PADDING_TYPE);
			return -2;
			}
		return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
		}

	if (!strcmp(type, "rsa_pss_saltlen"))
		{
		int saltlen;
		saltlen = atoi(value);
		return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
		}

	if (!strcmp(type, "rsa_keygen_bits"))
		{
		int nbits;
		nbits = atoi(value);
		return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
		}

	if (!strcmp(type, "rsa_keygen_pubexp"))
		{
		int ret;
		BIGNUM *pubexp = NULL;
		if (!BN_asc2bn(&pubexp, value))
			return 0;
		ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
		if (ret <= 0)
			BN_free(pubexp);
		return ret;
		}

	return -2;
	}

static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	RSA *rsa = NULL;
	RSA_PKEY_CTX *rctx = ctx->data;
	BN_GENCB *pcb, cb;
	int ret;
	if (!rctx->pub_exp)
		{
		rctx->pub_exp = BN_new();
		if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
			return 0;
		}
	rsa = RSA_new();
	if (!rsa)
		return 0;
	if (ctx->pkey_gencb)
		{
		pcb = &cb;
		evp_pkey_set_cb_translate(pcb, ctx);
		}
	else
		pcb = NULL;
	ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
	if (ret > 0)
		EVP_PKEY_assign_RSA(pkey, rsa);
	else
		RSA_free(rsa);
	return ret;
	}

const EVP_PKEY_METHOD rsa_pkey_meth = 
	{
	EVP_PKEY_RSA,
	EVP_PKEY_FLAG_AUTOARGLEN,
	pkey_rsa_init,
	pkey_rsa_copy,
	pkey_rsa_cleanup,

	0,0,

	0,
	pkey_rsa_keygen,

	0,
	pkey_rsa_sign,

	0,
	pkey_rsa_verify,

	0,
	pkey_rsa_verifyrecover,


	0,0,0,0,

	0,
	pkey_rsa_encrypt,

	0,
	pkey_rsa_decrypt,

	0,0,

	pkey_rsa_ctrl,
	pkey_rsa_ctrl_str


	};
