/* crypto/cms/cms_pwri.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2009 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.
 * ====================================================================
 */

#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include "cms_lcl.h"
#include "asn1_locl.h"

int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
				unsigned char *pass, ssize_t passlen)
	{
	CMS_PasswordRecipientInfo *pwri;
	if (ri->type != CMS_RECIPINFO_PASS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
		return 0;
		}

	pwri = ri->d.pwri;
	pwri->pass = pass;
	if (pass && passlen < 0)
		passlen = strlen((char *)pass);
	pwri->passlen = passlen;
	return 1;
	}

CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
					int iter, int wrap_nid, int pbe_nid,
					unsigned char *pass, ssize_t passlen,
					const EVP_CIPHER *kekciph)
	{
	CMS_RecipientInfo *ri = NULL;
	CMS_EnvelopedData *env;
	CMS_PasswordRecipientInfo *pwri;
	EVP_CIPHER_CTX ctx;
	X509_ALGOR *encalg = NULL;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	int ivlen;
	env = cms_get0_enveloped(cms);
	if (!env)
		goto err;

	if (wrap_nid <= 0)
		wrap_nid = NID_id_alg_PWRI_KEK;

	if (pbe_nid <= 0)
		pbe_nid = NID_id_pbkdf2;

	/* Get from enveloped data */
	if (kekciph == NULL)
		kekciph = env->encryptedContentInfo->cipher;

	if (kekciph == NULL)
		{
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
		return NULL;
		}
	if (wrap_nid != NID_id_alg_PWRI_KEK)
		{
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
		return NULL;
		}

	/* Setup algorithm identifier for cipher */
	encalg = X509_ALGOR_new();
	EVP_CIPHER_CTX_init(&ctx);

	if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0)
		{
		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
		goto err;
		}

	ivlen = EVP_CIPHER_CTX_iv_length(&ctx);

	if (ivlen > 0)
		{
		if (RAND_pseudo_bytes(iv, ivlen) <= 0)
			goto err;
		if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
							ERR_R_EVP_LIB);
			goto err;
			}
		encalg->parameter = ASN1_TYPE_new();
		if (!encalg->parameter)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
			goto err;
			}
		}


	encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));

	EVP_CIPHER_CTX_cleanup(&ctx);

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
	if (!ri->d.pwri)
		goto merr;
	ri->type = CMS_RECIPINFO_PASS;

	pwri = ri->d.pwri;
	/* Since this is overwritten, free up empty structure already there */
	X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
	pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
	if (!pwri->keyEncryptionAlgorithm)
		goto merr;
	pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
	pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
	if (!pwri->keyEncryptionAlgorithm->parameter)
		goto merr;

        if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
	    &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
		goto merr;
        pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;

	X509_ALGOR_free(encalg);
	encalg = NULL;

	/* Setup PBE algorithm */

	pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);

	if (!pwri->keyDerivationAlgorithm)
		goto err;

	CMS_RecipientInfo_set0_password(ri, pass, passlen);
	pwri->version = 0;

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;

	return ri;

	merr:
	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
	err:
	EVP_CIPHER_CTX_cleanup(&ctx);
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	if (encalg)
		X509_ALGOR_free(encalg);
	return NULL;

	}

/* This is an implementation of the key wrapping mechanism in RFC3211,
 * at some point this should go into EVP.
 */

static int kek_unwrap_key(unsigned char *out, size_t *outlen,
		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
	{
	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
	unsigned char *tmp;
	int outl, rv = 0;
	if (inlen < 2 * blocklen)
		{
		/* too small */
		return 0;
		}
	if (inlen % blocklen)
		{
		/* Invalid size */
		return 0;
		}
	tmp = OPENSSL_malloc(inlen);
	/* setup IV by decrypting last two blocks */
	EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
				in  + inlen - 2 * blocklen, blocklen * 2);
	/* Do a decrypt of last decrypted block to set IV to correct value
	 * output it to start of buffer so we don't corrupt decrypted block
	 * this works because buffer is at least two block lengths long.
	 */
	EVP_DecryptUpdate(ctx, tmp, &outl,
				tmp  + inlen - blocklen, blocklen);
	/* Can now decrypt first n - 1 blocks */
	EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);

	/* Reset IV to original value */
	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
	/* Decrypt again */
	EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
	/* Check check bytes */
	if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff)
		{
		/* Check byte failure */
		goto err;
		}
	if (inlen < (size_t)(tmp[0] - 4 ))
		{
		/* Invalid length value */
		goto err;
		}
	*outlen = (size_t)tmp[0];
	memcpy(out, tmp + 4, *outlen);
	rv = 1;
	err:
	OPENSSL_cleanse(tmp, inlen);
	OPENSSL_free(tmp);
	return rv;

	}

static int kek_wrap_key(unsigned char *out, size_t *outlen,
		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
	{
	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
	size_t olen;
	int dummy;
	/* First decide length of output buffer: need header and round up to
	 * multiple of block length.
	 */
	olen = (inlen + 4 + blocklen - 1)/blocklen;
	olen *= blocklen;
	if (olen < 2 * blocklen)
		{
		/* Key too small */
		return 0;
		}
	if (inlen > 0xFF)
		{
		/* Key too large */
		return 0;
		}
	if (out)
		{
		/* Set header */
		out[0] = (unsigned char)inlen;
		out[1] = in[0] ^ 0xFF;
		out[2] = in[1] ^ 0xFF;
		out[3] = in[2] ^ 0xFF;
		memcpy(out + 4, in, inlen);
		/* Add random padding to end */
		if (olen > inlen + 4)
			RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen);
		/* Encrypt twice */
		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
		}

	*outlen = olen;

	return 1;
	}

/* Encrypt/Decrypt content key in PWRI recipient info */

int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
							int en_de)
	{
	CMS_EncryptedContentInfo *ec;
	CMS_PasswordRecipientInfo *pwri;
	const unsigned char *p = NULL;
	int plen;
	int r = 0;
	X509_ALGOR *algtmp, *kekalg = NULL;
	EVP_CIPHER_CTX kekctx;
	const EVP_CIPHER *kekcipher;
	unsigned char *key = NULL;
	size_t keylen;

	ec = cms->d.envelopedData->encryptedContentInfo;

	pwri = ri->d.pwri;
	EVP_CIPHER_CTX_init(&kekctx);

	if (!pwri->pass)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
		return 0;
		}
	algtmp = pwri->keyEncryptionAlgorithm;

	if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
		return 0;
		}

	if (algtmp->parameter->type == V_ASN1_SEQUENCE)
		{
		p = algtmp->parameter->value.sequence->data;
		plen = algtmp->parameter->value.sequence->length;
		kekalg = d2i_X509_ALGOR(NULL, &p, plen);
		}
	if (kekalg == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
				CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
		return 0;
		}

	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
		
	if(!kekcipher)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
				CMS_R_UNKNOWN_CIPHER);
		goto err;
		}

	/* Fixup cipher based on AlgorithmIdentifier to set IV etc */
	if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
		goto err;
	EVP_CIPHER_CTX_set_padding(&kekctx, 0);
	if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
		goto err;
		}

	algtmp = pwri->keyDerivationAlgorithm;

	/* Finish password based key derivation to setup key in "ctx" */

	if (EVP_PBE_CipherInit(algtmp->algorithm,
				(char *)pwri->pass, pwri->passlen,
				algtmp->parameter, &kekctx, en_de) < 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
		goto err;
		}

	/* Finally wrap/unwrap the key */

	if (en_de)
		{

		if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
			goto err;

		key = OPENSSL_malloc(keylen);

		if (!key)
			goto err;

		if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
			goto err;
		pwri->encryptedKey->data = key;
		pwri->encryptedKey->length = keylen;
		}
	else
		{
		key = OPENSSL_malloc(pwri->encryptedKey->length);

		if (!key)
			{
			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
							ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!kek_unwrap_key(key, &keylen,
					pwri->encryptedKey->data,
					pwri->encryptedKey->length, &kekctx))
			{
			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
							CMS_R_UNWRAP_FAILURE);
			goto err;
			}

		ec->key = key;
		ec->keylen = keylen;

		}

	r = 1;

	err:

	EVP_CIPHER_CTX_cleanup(&kekctx);

	if (!r && key)
		OPENSSL_free(key);
	X509_ALGOR_free(kekalg);

	return r;

	}
