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;

	if (!key)
		{
		*key_len = 32;
		return 1;
		}	
	gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
		in_len);
	if (!gkt)
		{
		GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
		return -1;
		}	
    
	eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
	if (!eph_key) {
		eph_key = EVP_PKEY_CTX_get0_peerkey(pctx);
		if (! eph_key) {
			GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
				GOST_R_NO_PEER_KEY);
			goto err;
		}
		/* Increment reference count of peer key */
		CRYPTO_add(&(eph_key->references),1 ,CRYPTO_LOCK_EVP_PKEY);
	}	
		
	param = get_encryption_params(gkt->key_agreement_info->cipher);
	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(eph_key)),
		EVP_PKEY_get0(priv),wrappedKey);
	if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key))
		{
		GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,
			GOST_R_ERROR_COMPUTING_SHARED_KEY);
		goto err;
		}	
				
	EVP_PKEY_free(eph_key);
	GOST_KEY_TRANSPORT_free(gkt);
	ret=1;
err:	
	return ret;
	}