/* crypto/rsa/rsa_pmeth.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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/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);
			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_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
		return 1;

		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


	};
