/* 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, ossl_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,
					ossl_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)
		return NULL;

	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 */
	if (!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))
		goto err;
	/* 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 */
		if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
		    || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
			return 0;
		}

	*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;

	}
