soter_status_t soter_asym_cipher_decrypt(soter_asym_cipher_t* asym_cipher, const void* cipher_data, size_t cipher_data_length, void* plain_data, size_t* plain_data_length)
{
	EVP_PKEY *pkey;
	RSA *rsa;
	int rsa_mod_size;
	size_t output_length;

	if ((!asym_cipher) || (!cipher_data) || (0 == cipher_data_length) || (!plain_data_length))
	{
		return SOTER_INVALID_PARAMETER;
	}

	pkey = EVP_PKEY_CTX_get0_pkey(asym_cipher->pkey_ctx);

	if (!pkey)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_RSA != EVP_PKEY_id(pkey))
	{
		/* We can only do assymetric encryption with RSA algorithm */
		return SOTER_INVALID_PARAMETER;
	}

	rsa = EVP_PKEY_get0(pkey);
	if (NULL == rsa)
	{
		return SOTER_FAIL;
	}

	rsa_mod_size = RSA_size(rsa);

	if (cipher_data_length < rsa_mod_size)
	{
		/* The cipherdata is too small for this key size */
		return SOTER_INVALID_PARAMETER;
	}

	/* Currently we support only OAEP padding for RSA encryption */
	/* TODO: should we support "no padding" or PKCS1.5 padding? */
	if (!EVP_PKEY_decrypt_init(asym_cipher->pkey_ctx))
	{
		return SOTER_FAIL;
	}

	/* TODO: This function automatically sets SHA1 as MGF digest for OAEP padding. Should we change it to SHA256? */
	if (1 > EVP_PKEY_CTX_ctrl(asym_cipher->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING, RSA_PKCS1_OAEP_PADDING, NULL))
	{
		return SOTER_FAIL;
	}

	/* We will check the size of the output buffer first */
	if (EVP_PKEY_decrypt(asym_cipher->pkey_ctx, NULL, &output_length, (const unsigned char *)cipher_data, cipher_data_length))
	{
		if (output_length > *plain_data_length)
		{
			*plain_data_length = output_length;
			return SOTER_BUFFER_TOO_SMALL;
		}
	}
	else
	{
		return SOTER_FAIL;
	}

	if (EVP_PKEY_decrypt(asym_cipher->pkey_ctx, (unsigned char *)plain_data, plain_data_length, (const unsigned char *)cipher_data, cipher_data_length))
	{
		if (plain_data)
		{
			return SOTER_SUCCESS;
		}
		else
		{
			return SOTER_BUFFER_TOO_SMALL;
		}
	}
	else
	{
		return SOTER_FAIL;
	}
}
/* EVP_PLEY_METHOD callback decrypt for
 * GOST R 34.10-94 cryptopro modification
 */
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
	const unsigned char *p = in;
	GOST_KEY_TRANSPORT *gkt = NULL;
	unsigned char wrappedKey[44];
	unsigned char sharedKey[32];
	gost_ctx cctx;
	const struct gost_cipher_info *param=NULL;
	EVP_PKEY *eph_key=NULL, *peerkey=NULL;
	EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); 
	
	if (!key)
		{
		*key_len = 32;
		return 1;
		}	
	
	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
		in_len);
	if (!gkt)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
		return 0;
		}	
	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
	if (eph_key)
		{
		if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_INCOMPATIBLE_PEER_KEY);
			goto err;
			}
		}
	else
		{
		/* Set control "public key from client certificate used" */
		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_CTRL_CALL_FAILED);
			goto err;
			}
		}
	peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
	if (!peerkey)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
			GOST_R_NO_PEER_KEY);
		goto err;
		}

	param = get_encryption_params(gkt->key_agreement_info->cipher);
	gost_init(&cctx,param->sblock);	
	OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
	TINYCLR_SSL_MEMCPY(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
	OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
	TINYCLR_SSL_MEMCPY(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
	OPENSSL_assert(gkt->key_info->imit->length==4);
	TINYCLR_SSL_MEMCPY(wrappedKey+40,gkt->key_info->imit->data,4);	
	make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey);
	if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
			GOST_R_ERROR_COMPUTING_SHARED_KEY);
		goto err;
		}	
				
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return 1;
err:
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}	
int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) 
	{
	GOST_KEY_TRANSPORT *gkt=NULL;
	unsigned char shared_key[32], ukm[8],crypted_key[44];
	const struct gost_cipher_info *param=get_encryption_params(NULL);
	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
	struct gost_pmeth_data *data = (gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
	gost_ctx cctx;
	int key_is_ephemeral=1;
	EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);

	/* Do not use vizir cipher parameters with cryptopro */
	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
		{
		param= gost_cipher_list+1;
		}	

	if (mykey) 
		{
		/* If key already set, it is not ephemeral */
		key_is_ephemeral=0;
		if (!gost_get0_priv_key(mykey)) 
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
			goto err;
			}	
		} 
	else 
		{
		/* Otherwise generate ephemeral key */
		key_is_ephemeral = 1;
		if (out) 
			{
			mykey = EVP_PKEY_new();
			EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new());
			EVP_PKEY_copy_parameters(mykey,pubk);
			if (!gost_sign_keygen((DSA*)EVP_PKEY_get0(mykey))) 
				{
				goto err;
				}	
			}
		}	
	if (out)
		make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key);
	if (data->shared_ukm) 
		{
		TINYCLR_SSL_MEMCPY(ukm,data->shared_ukm,8);
		}
	else if (out) 
		{	
		if (RAND_bytes(ukm,8)<=0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
					GOST_R_RANDOM_GENERATOR_FAILURE);
			goto err;
			}	
		}
		
	if (out) {
		gost_init(&cctx,param->sblock);
		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
	}	
	gkt = GOST_KEY_TRANSPORT_new();
	if (!gkt)
		{
		goto memerr;
		}	
	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
			ukm,8))
		{
		goto memerr;
		}	
	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
		{
		goto memerr;
		}
	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
		{
		goto memerr;
		}
	if (key_is_ephemeral) {	
	if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk))
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
		goto err;
		}
		if (out) EVP_PKEY_free(mykey);
	}	
	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
	*outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL);
	if (*outlen == 0)
		{
		GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
		goto err;
		}
	if (!key_is_ephemeral)
		{
		/* Set control "public key from client certificate used" */
		if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
				GOST_R_CTRL_CALL_FAILED);
			goto err;
			}
		}
	GOST_KEY_TRANSPORT_free(gkt);
	return 1;	
	memerr:
		if (key_is_ephemeral) {
			EVP_PKEY_free(mykey);
		}	
	GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
		GOST_R_MALLOC_FAILURE);
	err:		
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}
Beispiel #4
0
int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
                             int cmd, uint64_t value)
{
    return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value);
}
Beispiel #5
0
static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
			       PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
	{
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;

	int ret = -1;

	pctx = EVP_PKEY_CTX_new(pkey, NULL);
	if (!pctx)
		return -1;

	if (EVP_PKEY_decrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
				EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
				ri->enc_key->data, ri->enc_key->length) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
				ri->enc_key->data, ri->enc_key->length) <= 0)
		{
		ret = 0;
		PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
		goto err;
		}

	ret = 1;

	if (*pek)
		{
		OPENSSL_cleanse(*pek, *peklen);
		OPENSSL_free(*pek);
		}

	*pek = ek;
	*peklen = eklen;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (!ret && ek)
		OPENSSL_free(ek);

	return ret;
	}
Beispiel #6
0
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
  return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
                           (void *)md);
}
Beispiel #7
0
/*  
 * EVP_PKEY_METHOD callback decrypt  
 * Implementation of GOST2001 key transport, cryptopo variation 
 */
int pkey_GOST01cp_decrypt (EVP_PKEY_CTX * pctx, unsigned char *key, size_t * key_len, const unsigned char *in,
                           size_t in_len)
{
    const unsigned char *p = in;

    EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey (pctx);

    GOST_KEY_TRANSPORT *gkt = NULL;

    int ret = 0;

    unsigned char wrappedKey[44];

    unsigned char sharedKey[32];

    gost_ctx ctx;

    const struct gost_cipher_info *param = NULL;

    EVP_PKEY *eph_key = NULL, *peerkey = NULL;

    if (!key)
    {
        *key_len = 32;
        return 1;
    }
    gkt = d2i_GOST_KEY_TRANSPORT (NULL, (const unsigned char **) &p, in_len);
    if (!gkt)
    {
        GOSTerr (GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
        return -1;
    }

    /* If key transport structure contains public key, use it */
    eph_key = X509_PUBKEY_get (gkt->key_agreement_info->ephem_key);
    if (eph_key)
    {
        if (EVP_PKEY_derive_set_peer (pctx, eph_key) <= 0)
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_INCOMPATIBLE_PEER_KEY);
            goto err;
        }
    }
    else
    {
        /* Set control "public key from client certificate used" */
        if (EVP_PKEY_CTX_ctrl (pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_CTRL_CALL_FAILED);
            goto err;
        }
    }
    peerkey = EVP_PKEY_CTX_get0_peerkey (pctx);
    if (!peerkey)
    {
        GOSTerr (GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_NO_PEER_KEY);
        goto err;
    }

    param = get_encryption_params (gkt->key_agreement_info->cipher);
    if (!param)
    {
        goto err;
    }

    gost_init (&ctx, param->sblock);
    OPENSSL_assert (gkt->key_agreement_info->eph_iv->length == 8);
    memcpy (wrappedKey, gkt->key_agreement_info->eph_iv->data, 8);
    OPENSSL_assert (gkt->key_info->encrypted_key->length == 32);
    memcpy (wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
    OPENSSL_assert (gkt->key_info->imit->length == 4);
    memcpy (wrappedKey + 40, gkt->key_info->imit->data, 4);
    VKO_compute_key (sharedKey, 32, EC_KEY_get0_public_key (EVP_PKEY_get0 (peerkey)), EVP_PKEY_get0 (priv), wrappedKey);
    if (!keyUnwrapCryptoPro (&ctx, sharedKey, wrappedKey, key))
    {
        GOSTerr (GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_ERROR_COMPUTING_SHARED_KEY);
        goto err;
    }

    ret = 1;
  err:
    if (eph_key)
        EVP_PKEY_free (eph_key);
    if (gkt)
        GOST_KEY_TRANSPORT_free (gkt);
    return ret;
}
Beispiel #8
0
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
                           EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
}
Beispiel #9
0
int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
                           EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e);
}
Beispiel #10
0
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
                           (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
                           EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL);
}
Beispiel #11
0
int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
                           (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY),
                           EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len);
}
Beispiel #12
0
int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING,
                           0, out_padding);
}
Beispiel #13
0
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING,
                           padding, NULL);
}
Beispiel #14
0
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
	{
	EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
#ifndef OPENSSL_NO_ENGINE
	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
	 * so this context may already have an ENGINE! Try to avoid releasing
	 * the previous handle, re-querying for an ENGINE, and having a
	 * reinitialisation, when it may all be unecessary. */
	if (ctx->engine && ctx->digest && (!type ||
			(type && (type->type == ctx->digest->type))))
		goto skip_to_init;
	if (type)
		{
		/* Ensure an ENGINE left lying around from last time is cleared
		 * (the previous check attempted to avoid this if the same
		 * ENGINE and EVP_MD could be used). */
		if(ctx->engine)
			ENGINE_finish(ctx->engine);
		if(impl)
			{
			if (!ENGINE_init(impl))
				{
				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
				return 0;
				}
			}
		else
			/* Ask if an ENGINE is reserved for this job */
			impl = ENGINE_get_digest_engine(type->type);
		if(impl)
			{
			/* There's an ENGINE for this job ... (apparently) */
			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
			if(!d)
				{
				/* Same comment from evp_enc.c */
				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
				ENGINE_finish(impl);
				return 0;
				}
			/* We'll use the ENGINE's private digest definition */
			type = d;
			/* Store the ENGINE functional reference so we know
			 * 'type' came from an ENGINE and we need to release
			 * it when done. */
			ctx->engine = impl;
			}
		else
			ctx->engine = NULL;
		}
	else
	if(!ctx->digest)
		{
		EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
		return 0;
		}
#endif
	if (ctx->digest != type)
		{
		if (ctx->digest && ctx->digest->ctx_size)
			OPENSSL_free(ctx->md_data);
		ctx->digest=type;
		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
			{
			ctx->update = type->update;
			ctx->md_data=OPENSSL_malloc(type->ctx_size);
			if (ctx->md_data == NULL)
				{
				EVPerr(EVP_F_EVP_DIGESTINIT_EX,
							ERR_R_MALLOC_FAILURE);
				return 0;
				}
			}
		}
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
#endif
	if (ctx->pctx)
		{
		int r;
		r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
					EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
		if (r <= 0 && (r != -2))
			return 0;
		}
	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
		return 1;
#ifdef OPENSSL_FIPS
	if (FIPS_mode())
		{
		if (FIPS_digestinit(ctx, type))
			return 1;
		OPENSSL_free(ctx->md_data);
		ctx->md_data = NULL;
		return 0;
		}
#endif
	return ctx->digest->init(ctx);
	}
Beispiel #15
0
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
        CMS_RecipientInfo *ri)
{
    CMS_KeyTransRecipientInfo *ktri;
    CMS_EncryptedContentInfo *ec;
    EVP_PKEY_CTX *pctx;
    unsigned char *ek = NULL;
    size_t eklen;

    int ret = 0;

    if (ri->type != CMS_RECIPINFO_TRANS) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
        return 0;
    }
    ktri = ri->d.ktri;
    ec = cms->d.envelopedData->encryptedContentInfo;

    pctx = ktri->pctx;

    if (pctx) {
        if (!cms_env_asn1_ctrl(ri, 0))
            goto err;
    } else {
        pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
        if (!pctx)
            return 0;

        if (EVP_PKEY_encrypt_init(pctx) <= 0)
            goto err;
    }

    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
                          EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
        goto err;
    }

    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
        goto err;

    ek = OPENSSL_malloc(eklen);

    if (ek == NULL) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
        goto err;

    ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
    ek = NULL;

    ret = 1;

err:
    EVP_PKEY_CTX_free(pctx);
    ktri->pctx = NULL;
    OPENSSL_free(ek);
    return ret;

}
Beispiel #16
0
int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
                           EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md);
}
Beispiel #17
0
static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
        CMS_RecipientInfo *ri)
{
    CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
    EVP_PKEY *pkey = ktri->pkey;
    unsigned char *ek = NULL;
    size_t eklen;
    int ret = 0;
    CMS_EncryptedContentInfo *ec;
    ec = cms->d.envelopedData->encryptedContentInfo;

    if (ktri->pkey == NULL) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
        return 0;
    }

    ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (!ktri->pctx)
        return 0;

    if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
        goto err;

    if (!cms_env_asn1_ctrl(ri, 1))
        goto err;

    if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
                          EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
        goto err;
    }

    if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
                         ktri->encryptedKey->data,
                         ktri->encryptedKey->length) <= 0)
        goto err;

    ek = OPENSSL_malloc(eklen);

    if (ek == NULL) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
                         ktri->encryptedKey->data,
                         ktri->encryptedKey->length) <= 0) {
        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
        goto err;
    }

    ret = 1;

    OPENSSL_clear_free(ec->key, ec->keylen);
    ec->key = ek;
    ec->keylen = eklen;

err:
    EVP_PKEY_CTX_free(ktri->pctx);
    ktri->pctx = NULL;
    if (!ret)
        OPENSSL_free(ek);

    return ret;
}
Beispiel #18
0
int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
  return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
                           EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
                           EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void*) out_md);
}
Beispiel #19
0
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
  return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD,
                           0, (void *)out_md);
}
Beispiel #20
0
int pkey_GOST01cp_encrypt (EVP_PKEY_CTX * pctx, unsigned char *out, size_t * out_len, const unsigned char *key,
                           size_t key_len)
{
    GOST_KEY_TRANSPORT *gkt = NULL;

    EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey (pctx);

    struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data (pctx);

    const struct gost_cipher_info *param = get_encryption_params (NULL);

    unsigned char ukm[8], shared_key[32], crypted_key[44];

    int ret = 0;

    int key_is_ephemeral = 1;

    gost_ctx cctx;

    EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey (pctx);

    if (data->shared_ukm)
    {
        memcpy (ukm, data->shared_ukm, 8);
    }
    else if (out)
    {

        if (RAND_bytes (ukm, 8) <= 0)
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_RANDOM_GENERATOR_FAILURE);
            return 0;
        }
    }
    /* Check for private key in the peer_key of context */
    if (sec_key)
    {
        key_is_ephemeral = 0;
        if (!gost_get0_priv_key (sec_key))
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
            goto err;
        }
    }
    else
    {
        key_is_ephemeral = 1;
        if (out)
        {
            sec_key = EVP_PKEY_new ();
            EVP_PKEY_assign (sec_key, EVP_PKEY_base_id (pubk), EC_KEY_new ());
            EVP_PKEY_copy_parameters (sec_key, pubk);
            if (!gost2001_keygen (EVP_PKEY_get0 (sec_key)))
            {
                goto err;
            }
        }
    }
    if (!get_gost_engine_param (GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list)
    {
        param = gost_cipher_list + 1;
    }
    if (out)
    {
        VKO_compute_key (shared_key, 32, EC_KEY_get0_public_key (EVP_PKEY_get0 (pubk)), EVP_PKEY_get0 (sec_key), ukm);
        gost_init (&cctx, param->sblock);
        keyWrapCryptoPro (&cctx, shared_key, ukm, key, crypted_key);
    }
    gkt = GOST_KEY_TRANSPORT_new ();
    if (!gkt)
    {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set (gkt->key_agreement_info->eph_iv, ukm, 8))
    {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set (gkt->key_info->imit, crypted_key + 40, 4))
    {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set (gkt->key_info->encrypted_key, crypted_key + 8, 32))
    {
        goto err;
    }
    if (key_is_ephemeral)
    {
        if (!X509_PUBKEY_set (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk))
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
            goto err;
        }
    }
    ASN1_OBJECT_free (gkt->key_agreement_info->cipher);
    gkt->key_agreement_info->cipher = OBJ_nid2obj (param->nid);
    if (key_is_ephemeral && sec_key)
        EVP_PKEY_free (sec_key);
    if (!key_is_ephemeral)
    {
        /* Set control "public key from client certificate used" */
        if (EVP_PKEY_CTX_ctrl (pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
        {
            GOSTerr (GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED);
            goto err;
        }
    }
    if ((*out_len = i2d_GOST_KEY_TRANSPORT (gkt, out ? &out : NULL)) > 0)
        ret = 1;
    GOST_KEY_TRANSPORT_free (gkt);
    return ret;
  err:
    if (key_is_ephemeral && sec_key)
        EVP_PKEY_free (sec_key);
    GOST_KEY_TRANSPORT_free (gkt);
    return -1;
}