static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
					unsigned char *key, int keylen)
	{
	EVP_PKEY_CTX *pctx = NULL;
	EVP_PKEY *pkey = NULL;
	unsigned char *ek = NULL;
	int ret = 0;
	size_t eklen;

	pkey = X509_get_pubkey(ri->cert);

	if (!pkey)
		return 0;

	pctx = EVP_PKEY_CTX_new(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_PKCS7_ENCRYPT, 0, ri) <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
		goto err;
		}

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

	ek = (unsigned char*)OPENSSL_malloc(eklen);

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

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

	ASN1_STRING_set0(ri->enc_key, ek, eklen);
	ek = NULL;

	ret = 1;

	err:
	if (pkey)
		EVP_PKEY_free(pkey);
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (ek)
		OPENSSL_free(ek);
	return ret;

	}
Esempio n. 2
0
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
                                          CMS_RecipientInfo *ri)
{
    CMS_KeyTransRecipientInfo *ktri;
    CMS_EncryptedContentInfo *ec;
    EVP_PKEY_CTX *pctx = NULL;
    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 = 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:
    if (pctx)
        EVP_PKEY_CTX_free(pctx);
    if (ek)
        OPENSSL_free(ek);
    return ret;

}
Esempio n. 3
0
static int
do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
    unsigned char *out, size_t * poutlen,
    unsigned char *in, size_t inlen)
{
	int rv = 0;
	switch (pkey_op) {
	case EVP_PKEY_OP_VERIFYRECOVER:
		rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
		break;

	case EVP_PKEY_OP_SIGN:
		rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
		break;

	case EVP_PKEY_OP_ENCRYPT:
		rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
		break;

	case EVP_PKEY_OP_DECRYPT:
		rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
		break;

	case EVP_PKEY_OP_DERIVE:
		rv = EVP_PKEY_derive(ctx, out, poutlen);
		break;

	}
	return rv;
}
Esempio n. 4
0
int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
	     int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
	{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int i;
	
	if(type) {
		EVP_CIPHER_CTX_init(ctx);
		if(!EVP_EncryptInit_ex(ctx,type,NULL,NULL,NULL)) return 0;
	}
	if ((npubk <= 0) || !pubk)
		return 1;
	if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
		return 0;
	if (EVP_CIPHER_CTX_iv_length(ctx))
		RAND_pseudo_bytes(iv,EVP_CIPHER_CTX_iv_length(ctx));

	if(!EVP_EncryptInit_ex(ctx,NULL,NULL,key,iv)) return 0;

	for (i=0; i<npubk; i++)
		{
		ekl[i]=EVP_PKEY_encrypt(ek[i],key,EVP_CIPHER_CTX_key_length(ctx),
			pubk[i]);
		if (ekl[i] <= 0) return(-1);
		}
	return(npubk);
	}
Esempio n. 5
0
/* GMSSL: EVP_PKEY_encrypt_old() is modified */
int EVP_PKEY_encrypt_old(unsigned char *out, const unsigned char *in,
	int inlen, EVP_PKEY *pkey)
{
	int ret = 0;
	EVP_PKEY_CTX *ctx = NULL;
	size_t size;

	if (pkey->type == EVP_PKEY_RSA) {
		ret = RSA_public_encrypt(inlen, in, out, pkey->pkey.rsa,
			RSA_PKCS1_PADDING);
	} else {
		if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL))) {
			return 0;
		}
		if (1 != EVP_PKEY_encrypt_init(ctx)) {
			return 0;
		}
		if (1 != EVP_PKEY_encrypt(ctx, out, &size, in, inlen)) {
			goto end;
		}
		ret = (int)size;
	}
end:
	EVP_PKEY_CTX_free(ctx);
	return ret;
}
Esempio n. 6
0
/* 7.3.31 */
int SAF_GenerateKeyWithEPK(
	void *hSymmKeyObj,
	unsigned char *pucPublicKey,
	unsigned int uiPublicKeyLen,
	unsigned char *pucSymmKey,
	unsigned int *puiSymmKeyLen,
	void **phKeyHandle)
{
	int ret = SAR_UnknownErr;
	SAF_KEY *hkey = NULL;
	SAF_SYMMKEYOBJ *obj = (SAF_SYMMKEYOBJ *)hSymmKeyObj;
	const EVP_CIPHER *cipher;
	unsigned char keybuf[32];
	EVP_PKEY *pkey = NULL;
	EVP_PKEY_CTX *pkctx = NULL;
	size_t outlen;

	if (!hSymmKeyObj || !pucPublicKey || !pucSymmKey
		|| !puiSymmKeyLen || !phKeyHandle) {
		SAFerr(SAF_F_SAF_GENERATEKEYWITHEPK, ERR_R_PASSED_NULL_PARAMETER);
		return SAR_IndataErr;
	}

	if (uiPublicKeyLen <= 0 || uiPublicKeyLen > INT_MAX) {
		SAFerr(SAF_F_SAF_GENERATEKEYWITHEPK, SAF_R_INVALID_INPUT_LENGTH);
		return SAR_IndataLenErr;
	}

	outlen = (size_t)*puiSymmKeyLen;
	if (!(cipher = EVP_get_cipherbysgd(obj->uiCryptoAlgID))
		|| !RAND_bytes(keybuf, EVP_CIPHER_key_length(cipher))
		|| !(pkey = d2i_PUBKEY(NULL, (const unsigned char **)&pucPublicKey, (long)uiPublicKeyLen))
		|| !(pkctx = EVP_PKEY_CTX_new(pkey, NULL))
		|| !EVP_PKEY_encrypt_init(pkctx)
		|| !EVP_PKEY_encrypt(pkctx, pucSymmKey, &outlen, keybuf, (size_t)EVP_CIPHER_key_length(cipher))) {
		SAFerr(SAF_F_SAF_GENERATEKEYWITHEPK, SAF_R_ENCRYPT_KEY_FAILURE);
		goto end;
	}

	// init EVP_CIPHER_CTX
	if (!(hkey = OPENSSL_zalloc(sizeof(*hkey)))) {
		SAFerr(SAF_F_SAF_GENERATEKEYWITHEPK, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	*puiSymmKeyLen = (unsigned int)outlen;
	ret = SAR_Ok;

end:
	EVP_PKEY_free(pkey);
	EVP_PKEY_CTX_free(pkctx);
	return ret;
}
Esempio n. 7
0
static LUA_FUNCTION(openssl_pkey_encrypt)
{
  size_t dlen = 0;
  EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey");
  const char *data = luaL_checklstring(L, 2, &dlen);
  int padding = auxiliar_checkoption(L, 3, "pkcs1", sPadding, iPadding);
  size_t clen = EVP_PKEY_size(pkey);
  EVP_PKEY_CTX *ctx = NULL;
  int ret = 0;

  if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA2) {
    luaL_argerror(L, 2, "EVP_PKEY must be of type RSA or RSA2");
    return ret;
  }

  if (openssl_pkey_is_private(pkey) == 0)
  {
    ctx = EVP_PKEY_CTX_new(pkey, pkey->engine);
    if (EVP_PKEY_encrypt_init(ctx) == 1)
    {
      if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1)
      {
        byte* buf = malloc(clen);
        if (EVP_PKEY_encrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1)
        {
          lua_pushlstring(L, (const char*)buf, clen);
          ret = 1;
        }
        else
          ret = openssl_pushresult(L, 0);
        free(buf);
      }
      else
        ret = openssl_pushresult(L, 0);
    }
    else
      ret = openssl_pushresult(L, 0);
    EVP_PKEY_CTX_free(ctx);
  }
  else
  {
    luaL_argerror(L, 2, "EVP_PKEY must be public key");
  }

  return ret;
}
Esempio n. 8
0
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EncryptedContentInfo *ec;
	unsigned char *ek = NULL;
	int 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;

	eklen = EVP_PKEY_size(ktri->pkey);

	ek = OPENSSL_malloc(eklen);

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

	eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey);

	if (eklen <= 0)
		goto err;

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

	ret = 1;

	err:
	if (ek)
		OPENSSL_free(ek);
	return ret;

	}
CK_RV PKCS11_Encryption_OpenSSL::EncryptUpdate(Cryptoki_Session_Context* pSessionCtx, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)   
{
    OPENSSL_HEADER();
    OpenSSLEncryptData *pEnc;
    
    if(pSessionCtx == NULL || pSessionCtx->EncryptionCtx == NULL) return CKR_SESSION_CLOSED;

    pEnc = (OpenSSLEncryptData*)pSessionCtx->EncryptionCtx;
    
    if(pEnc->IsSymmetric)
    {
        int outLen = *pulEncryptedPartLen;
        
        OPENSSL_CHECKRESULT(EVP_EncryptUpdate((EVP_CIPHER_CTX*)pEnc->Key->ctx, pEncryptedPart, &outLen, pPart, ulPartLen));
        
        *pulEncryptedPartLen = outLen;
    }
    else
    {
        size_t encLen = *pulEncryptedPartLen;
        
        OPENSSL_CHECKRESULT(EVP_PKEY_encrypt((EVP_PKEY_CTX*)pEnc->Key->ctx, pEncryptedPart, &encLen, pPart, ulPartLen));

        *pulEncryptedPartLen = encLen;
    }

    OPENSSL_CLEANUP();

    if(retVal != CKR_OK)
    {
        TINYCLR_SSL_FREE(pEnc);
        pSessionCtx->EncryptionCtx = NULL;
    }

    OPENSSL_RETURN();
}
Esempio n. 10
0
int main()
{
	int ret = -1;
	int verbose = 0;
	BIO *out = NULL;

	int id = EVP_PKEY_SM2;
	const EVP_MD *md = EVP_sm3();
	ENGINE *engine = NULL;

	EVP_PKEY_CTX *pkctx = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_MD_CTX *mdctx = NULL;
	EVP_CIPHER_CTX *cpctx = NULL;

	unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
	size_t dgstlen = 32;
	unsigned char sig[256];
	size_t siglen = sizeof(sig);

	unsigned char msg[] = "hello world this is the message";
	size_t msglen = sizeof(msg);
	unsigned char cbuf[512];
	size_t cbuflen = sizeof(cbuf);
	unsigned char mbuf[512];
	size_t mbuflen = sizeof(mbuf);

	int len;
	unsigned int ulen;

	ERR_load_crypto_strings();

	out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen(pkctx, &pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	EVP_PKEY_CTX_free(pkctx);

	if (0) {
		EVP_PKEY_print_public(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
		EVP_PKEY_print_private(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
	}

	if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	/* EVP_PKEY_sign() */

	if (!EVP_PKEY_sign_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(sig, sizeof(sig));
	siglen = sizeof(sig);
	dgstlen = 32;

	if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_verify_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("signature verification success!\n");
	}

	/* EVP_PKEY_encrypt() */

	if (!EVP_PKEY_encrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	cbuflen = sizeof(cbuf);
	if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("ciphertext (%zu bytes) = ", cbuflen);
		for (i = 0; i < cbuflen; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_decrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(mbuf, sizeof(mbuf));
	mbuflen = sizeof(mbuf);
	if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}


	/* EVP_PKEY_encrypt_old */


	if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		int i;
		printf("ciphertext (%d bytes) = ", len);
		for (i = 0; i < len; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	bzero(mbuf, sizeof(mbuf));
	if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}

	if (!(mdctx = EVP_MD_CTX_create())) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	
	/* EVP_SignInit_ex/Update/Final_ex */

	if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}
	siglen = ulen;

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_DigestSignInit/Update/Final() */
	// FIXME: return values might be different, not just 1 or 0
	if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	siglen = sizeof(sig);
	if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	pkctx = NULL;	
	if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */
	/*
	EVP_PKEY *pk[NUM_PKEYS] = {0};
	unsigned char iv[16];
	unsigned char ek[NUM_PKEYS][256];
	int eklen[NUM_PKEYS];

	RAND_pseudo_bytes(iv, sizeof(iv));

	int i;
	for (i = 0; i < NUM_PKEYS; i++) {
	}

	if (!(cpctx = EVP_CIPHER_CTX_new())) {
		goto end;
	}

	if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) {
		goto end;
	}

	if (!EVP_SealUpdate(cpctx, msg, msglen)) {
		goto end;
	}

	if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) {
		goto end;
	}
	*/

	printf("test success!\n");
	ret = 1;
end:
	ERR_print_errors_fp(stderr);
	return ret;
}
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
	{
	int i;
	BIO *out=NULL,*btmp=NULL;
	X509_ALGOR *xa = NULL;
	const EVP_CIPHER *evp_cipher=NULL;
	STACK_OF(X509_ALGOR) *md_sk=NULL;
	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
	X509_ALGOR *xalg=NULL;
	PKCS7_RECIP_INFO *ri=NULL;
	EVP_PKEY *pkey;
	ASN1_OCTET_STRING *os=NULL;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signed:
		md_sk=p7->d.sign->md_algs;
		os = PKCS7_get_octet_string(p7->d.sign->contents);
		break;
	case NID_pkcs7_signedAndEnveloped:
		rsk=p7->d.signed_and_enveloped->recipientinfo;
		md_sk=p7->d.signed_and_enveloped->md_algs;
		xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
		evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_enveloped:
		rsk=p7->d.enveloped->recipientinfo;
		xalg=p7->d.enveloped->enc_data->algorithm;
		evp_cipher=p7->d.enveloped->enc_data->cipher;
		if (evp_cipher == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,
						PKCS7_R_CIPHER_NOT_INITIALIZED);
			goto err;
			}
		break;
	case NID_pkcs7_digest:
		xa = p7->d.digest->md;
		os = PKCS7_get_octet_string(p7->d.digest->contents);
		break;
	default:
		PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
	        goto err;
		}

	for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
		if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
			goto err;

	if (xa && !PKCS7_bio_add_digest(&out, xa))
			goto err;

	if (evp_cipher != NULL)
		{
		unsigned char key[EVP_MAX_KEY_LENGTH];
		unsigned char iv[EVP_MAX_IV_LENGTH];
		int keylen,ivlen;
		int jj,max;
		unsigned char *tmp;
		EVP_CIPHER_CTX *ctx;

		if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
			goto err;
			}
		BIO_get_cipher_ctx(btmp, &ctx);
		keylen=EVP_CIPHER_key_length(evp_cipher);
		ivlen=EVP_CIPHER_iv_length(evp_cipher);
		xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
		if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
		if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
			goto err;
		if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
			goto err;
		if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
			goto err;

		if (ivlen > 0) {
			if (xalg->parameter == NULL) 
						xalg->parameter=ASN1_TYPE_new();
			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
								       goto err;
		}

		/* Lets do the pub key stuff :-) */
		max=0;
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			if (ri->cert == NULL)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
				goto err;
				}
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_size(pkey);
			EVP_PKEY_free(pkey);
			if (max < jj) max=jj;
			}
		if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
			{
			ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
			pkey=X509_get_pubkey(ri->cert);
			jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
			EVP_PKEY_free(pkey);
			if (jj <= 0)
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
				OPENSSL_free(tmp);
				goto err;
				}
			if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAINIT,
					ERR_R_MALLOC_FAILURE);
				OPENSSL_free(tmp);
				goto err;
				}
			}
		OPENSSL_free(tmp);
		OPENSSL_cleanse(key, keylen);

		if (out == NULL)
			out=btmp;
		else
			BIO_push(out,btmp);
		btmp=NULL;
		}

	if (bio == NULL)
		{
		if (PKCS7_is_detached(p7))
			bio=BIO_new(BIO_s_null());
		else if (os && os->length > 0)
			bio = BIO_new_mem_buf(os->data, os->length);
		if(bio == NULL)
			{
			bio=BIO_new(BIO_s_mem());
			BIO_set_mem_eof_return(bio,0);
			}
		}
	BIO_push(out,bio);
	bio=NULL;
	if (0)
		{
err:
		if (out != NULL)
			BIO_free_all(out);
		if (btmp != NULL)
			BIO_free_all(btmp);
		out=NULL;
		}
	return(out);
	}
Esempio n. 12
0
File: rsaes.c Progetto: simo5/jose
static bool
alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe,
             json_t *rcp, const json_t *jwk, json_t *cek)
{
    openssl_auto(EVP_PKEY_CTX) *epc = NULL;
    openssl_auto(EVP_PKEY) *key = NULL;
    const EVP_MD *md = NULL;
    const RSA *rsa = NULL;
    uint8_t *pt = NULL;
    uint8_t *ct = NULL;
    bool ret = false;
    size_t ptl = 0;
    size_t ctl = 0;
    int tmp = 0;
    int pad = 0;

    if (!json_object_get(cek, "k") && !jose_jwk_gen(cfg, cek))
        return false;

    switch (str2enum(alg->name, NAMES, NULL)) {
    case 0: pad = RSA_PKCS1_PADDING;      tmp = 11; md = EVP_sha1(); break;
    case 1: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha1(); break;
    case 2: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha256(); break;
    default: return false;
    }

    key = jose_openssl_jwk_to_EVP_PKEY(cfg, jwk);
    if (!key || EVP_PKEY_base_id(key) != EVP_PKEY_RSA)
        return false;

    ptl = jose_b64_dec(json_object_get(cek, "k"), NULL, 0);
    if (ptl == SIZE_MAX)
        return false;

    rsa = EVP_PKEY_get0_RSA(key);
    if (!rsa)
        return false;

    if ((int) ptl >= RSA_size(rsa) - tmp)
        return false;

    epc = EVP_PKEY_CTX_new(key, NULL);
    if (!epc)
        return false;

    if (EVP_PKEY_encrypt_init(epc) <= 0)
        return false;

    if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0)
        return false;

    if (pad == RSA_PKCS1_OAEP_PADDING) {
        if (EVP_PKEY_CTX_set_rsa_oaep_md(epc, md) <= 0)
            return false;

        if (EVP_PKEY_CTX_set_rsa_mgf1_md(epc, md) <= 0)
            return false;
    }

    pt = malloc(ptl);
    if (!pt)
        return false;

    if (jose_b64_dec(json_object_get(cek, "k"), pt, ptl) != ptl)
        goto egress;

    if (EVP_PKEY_encrypt(epc, NULL, &ctl, pt, ptl) <= 0)
        goto egress;

    ct = malloc(ctl);
    if (!ct)
        goto egress;

    if (EVP_PKEY_encrypt(epc, ct, &ctl, pt, ptl) <= 0)
        goto egress;

    if (json_object_set_new(rcp, "encrypted_key", jose_b64_enc(ct, ctl)) < 0)
        goto egress;

    ret = add_entity(jwe, rcp, "recipients", "header", "encrypted_key", NULL);

egress:
    if (pt) {
        OPENSSL_cleanse(pt, ptl);
        free(pt);
    }

    free(ct);
    return ret;
}
Esempio n. 13
0
static int test_EVP_SM2(void)
{
    int ret = 0;
    EVP_PKEY *pkey = NULL;
    EVP_PKEY *params = NULL;
    EVP_PKEY_CTX *pctx = NULL;
    EVP_PKEY_CTX *kctx = NULL;
    EVP_PKEY_CTX *sctx = NULL;
    size_t sig_len = 0;
    unsigned char *sig = NULL;
    EVP_MD_CTX *md_ctx = NULL;
    EVP_MD_CTX *md_ctx_verify = NULL;
    EVP_PKEY_CTX *cctx = NULL;

    uint8_t ciphertext[128];
    size_t ctext_len = sizeof(ciphertext);

    uint8_t plaintext[8];
    size_t ptext_len = sizeof(plaintext);

    uint8_t sm2_id[] = {1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r'};

    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
    if (!TEST_ptr(pctx))
        goto done;

    if (!TEST_true(EVP_PKEY_paramgen_init(pctx) == 1))
        goto done;

    if (!TEST_true(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2)))
        goto done;

    if (!TEST_true(EVP_PKEY_paramgen(pctx, &params)))
        goto done;

    kctx = EVP_PKEY_CTX_new(params, NULL);
    if (!TEST_ptr(kctx))
        goto done;

    if (!TEST_true(EVP_PKEY_keygen_init(kctx)))
        goto done;

    if (!TEST_true(EVP_PKEY_keygen(kctx, &pkey)))
        goto done;

    if (!TEST_true(EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)))
        goto done;

    if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()))
        goto done;

    if (!TEST_ptr(md_ctx_verify = EVP_MD_CTX_new()))
        goto done;

    if (!TEST_ptr(sctx = EVP_PKEY_CTX_new(pkey, NULL)))
        goto done;

    EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
    EVP_MD_CTX_set_pkey_ctx(md_ctx_verify, sctx);

    if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(sctx, sm2_id, sizeof(sm2_id)), 0))
        goto done;

    if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey)))
        goto done;

    if(!TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))))
        goto done;

    /* Determine the size of the signature. */
    if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len)))
        goto done;

    if (!TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey)))
        goto done;

    if (!TEST_ptr(sig = OPENSSL_malloc(sig_len)))
        goto done;

    if (!TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len)))
        goto done;

    /* Ensure that the signature round-trips. */

    if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sm3(), NULL, pkey)))
        goto done;

    if (!TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg))))
        goto done;

    if (!TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)))
        goto done;

    /* now check encryption/decryption */

    if (!TEST_ptr(cctx = EVP_PKEY_CTX_new(pkey, NULL)))
        goto done;

    if (!TEST_true(EVP_PKEY_encrypt_init(cctx)))
        goto done;

    if (!TEST_true(EVP_PKEY_encrypt(cctx, ciphertext, &ctext_len, kMsg, sizeof(kMsg))))
        goto done;

    if (!TEST_true(EVP_PKEY_decrypt_init(cctx)))
        goto done;

    if (!TEST_true(EVP_PKEY_decrypt(cctx, plaintext, &ptext_len, ciphertext, ctext_len)))
        goto done;

    if (!TEST_true(ptext_len == sizeof(kMsg)))
        goto done;

    if (!TEST_true(memcmp(plaintext, kMsg, sizeof(kMsg)) == 0))
        goto done;

    ret = 1;
done:
    EVP_PKEY_CTX_free(pctx);
    EVP_PKEY_CTX_free(kctx);
    EVP_PKEY_CTX_free(sctx);
    EVP_PKEY_CTX_free(cctx);
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(params);
    EVP_MD_CTX_free(md_ctx);
    EVP_MD_CTX_free(md_ctx_verify);
    OPENSSL_free(sig);
    return ret;
}
Esempio n. 14
0
/**
@fn int soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
@brief Initialize mecevp engine state and create context for
encryption/decryption algorithm using a private/public key or symmetric secret
key.
@param soap context
@param[in,out] data mecevp engine context
@param[in] alg encryption/decryption algorithm
@param[in] pkey public/private key or NULL
@param[in,out] key secret key or encrypted ephemeral secret key set with envelope encryption, or NULL
@param[in,out] keylen secret key length
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_mec_init(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
{ int ok = 1;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_init()\n"));
  soap_ssl_init();
  data->ctx = (EVP_CIPHER_CTX*)SOAP_MALLOC(soap, sizeof(EVP_CIPHER_CTX));
  if (!data->ctx)
    return soap->error = SOAP_EOM;
  EVP_CIPHER_CTX_init(data->ctx);
  data->alg = alg;
  data->state = SOAP_MEC_STATE_NONE;
  if (alg & SOAP_MEC_DES_CBC)
    data->type = EVP_des_ede3_cbc(); /* triple DES CBC */
  else if (alg & SOAP_MEC_AES128_CBC)
    data->type = EVP_get_cipherbyname("AES128");
  else if (alg & SOAP_MEC_AES192_CBC)
    data->type = EVP_get_cipherbyname("AES192");
  else if (alg & SOAP_MEC_AES256_CBC)
    data->type = EVP_get_cipherbyname("AES256");
  else if (alg & SOAP_MEC_AES512_CBC)
    data->type = EVP_get_cipherbyname("AES512");
  else
    data->type = EVP_enc_null();
  data->buf = NULL;
  data->rest = NULL;
  data->restlen = 0;
  if (alg & SOAP_MEC_ENC)
  { if (!data->type)
      return soap_mec_check(soap, data, 0, "soap_mec_init() failed: cannot load cipher");
    EVP_EncryptInit_ex(data->ctx, data->type, NULL, NULL, NULL);
  }
  if (alg & SOAP_MEC_OAEP)
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_OAEP_PADDING);
  else
    EVP_CIPHER_CTX_set_padding(data->ctx, RSA_PKCS1_PADDING);
  switch (alg & SOAP_MEC_MASK)
  { case SOAP_MEC_ENV_ENC_AES128_CBC:
    case SOAP_MEC_ENV_ENC_AES192_CBC:
    case SOAP_MEC_ENV_ENC_AES256_CBC:
    case SOAP_MEC_ENV_ENC_AES512_CBC:
    case SOAP_MEC_ENV_ENC_DES_CBC:
      ok = EVP_CIPHER_CTX_rand_key(data->ctx, data->ekey);
      /* generate ephemeral secret key */
#if (OPENSSL_VERSION_NUMBER >= 0x01000000L)
      *keylen = EVP_PKEY_encrypt_old(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#else
      *keylen = EVP_PKEY_encrypt(key, data->ekey, EVP_CIPHER_CTX_key_length(data->ctx), pkey);
#endif
      key = data->ekey;
      /* fall through to next arm */
    case SOAP_MEC_ENC_DES_CBC:
    case SOAP_MEC_ENC_AES128_CBC:
    case SOAP_MEC_ENC_AES192_CBC:
    case SOAP_MEC_ENC_AES256_CBC:
    case SOAP_MEC_ENC_AES512_CBC:
      data->bufidx = 0;
      data->buflen = 1024; /* > iv in base64 must fit */
      data->buf = (char*)SOAP_MALLOC(soap, data->buflen);
      data->key = key;
      break;
    case SOAP_MEC_ENV_DEC_AES128_CBC:
    case SOAP_MEC_ENV_DEC_AES192_CBC:
    case SOAP_MEC_ENV_DEC_AES256_CBC:
    case SOAP_MEC_ENV_DEC_AES512_CBC:
    case SOAP_MEC_ENV_DEC_DES_CBC:
    case SOAP_MEC_DEC_DES_CBC:
    case SOAP_MEC_DEC_AES128_CBC:
    case SOAP_MEC_DEC_AES192_CBC:
    case SOAP_MEC_DEC_AES256_CBC:
    case SOAP_MEC_DEC_AES512_CBC:
      data->pkey = pkey;
      data->key = key;
      data->keylen = *keylen;
      break;
    default:
      return soap_set_receiver_error(soap, "Unsupported encryption algorithm", NULL, SOAP_SSL_ERROR);
  }
  return soap_mec_check(soap, data, ok, "soap_mec_init() failed");
}
Esempio n. 15
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    ENGINE *eng=ENGINE_get_default_RSA();
    EVP_PKEY _pkey, *pkey; EVP_PKEY_CTX *ctx; 
    int pubkeyin=(strncasecmp(cname,"rsapub",6)==0);
    const unsigned char *scankey=key;
    struct U8_BYTEBUF bb;
    int retval=-1;
    if (pubkeyin) pkey=d2i_PUBKEY(NULL,&scankey,keylen);
    else pkey=d2i_PrivateKey((EVP_PKEY_RSA),NULL,&scankey,keylen);
    if (!(pkey)) ctx=NULL;
    else {
#if (OPENSSL_VERSION_NUMBER>=0x1000204fL)
      ctx=EVP_PKEY_CTX_new(pkey,eng);
#else
      ctx=EVP_PKEY_CTX_new(pkey,NULL);
#endif
    }
    if (ctx) {
      memset(&bb,0,sizeof(bb));
      bb.u8_direction=u8_output_buffer;
      bb.u8_buf=bb.u8_ptr=(u8_byte *)u8_malloc(1024);
      bb.u8_lim=(u8_byte *)(bb.u8_buf+1024);
      bb.u8_growbuf=1;
      fill_bytebuf(&bb,reader,readstate);}
    if (!(ctx)) {}
    else if ((pubkeyin)?
	     ((do_encrypt)?((retval=EVP_PKEY_encrypt_init(ctx))<0):
	      ((retval=EVP_PKEY_verify_recover_init(ctx))<0)):
	     ((do_encrypt)?((retval=EVP_PKEY_sign_init(ctx))<0):
	      ((retval=EVP_PKEY_decrypt_init(ctx))<0))) {}
    else {
      unsigned char *in=bb.u8_buf; size_t inlen=bb.u8_ptr-bb.u8_buf;
      unsigned char *out=NULL; size_t outlen;
      if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,NULL,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,NULL,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,NULL,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,NULL,&outlen,in,inlen);
      if (retval<0) {}
      else if ((out=u8_malloc(outlen))==NULL) {}
      else if (pubkeyin) {
	if (do_encrypt) retval=EVP_PKEY_encrypt(ctx,out,&outlen,in,inlen);
	else retval=EVP_PKEY_verify_recover(ctx,out,&outlen,in,inlen);}
      else if (do_encrypt) retval=EVP_PKEY_sign(ctx,out,&outlen,in,inlen);
      else retval=EVP_PKEY_decrypt(ctx,out,&outlen,in,inlen);
      if (retval<0) {}
      else retval=writer(out,outlen,writestate);
      if (out) u8_free(out);}
    u8_free(bb.u8_buf);
    if (retval<0) {
      unsigned long err=ERR_get_error(); char buf[512];
      buf[0]='\0'; ERR_error_string_n(err,buf,512);
      u8_seterr(u8_InternalCryptoError,OPENSSL_CRYPTIC,u8_fromlibc((char *)buf));
      ERR_clear_error();}
    if (ctx) EVP_PKEY_CTX_free(ctx);
    if (pkey)  EVP_PKEY_free(pkey);
    return retval;}
  else {
    EVP_CIPHER_CTX ctx;
    int inlen, outlen, retval=0;
    ssize_t totalout=0, totalin=0;
    unsigned char inbuf[1024], outbuf[1024+EVP_MAX_BLOCK_LENGTH];
    const EVP_CIPHER *cipher=((cname)?(EVP_get_cipherbyname(cname)):
			      (EVP_aes_128_cbc()));

    if (cipher) {
      int needkeylen=EVP_CIPHER_key_length(cipher);
      int needivlen=EVP_CIPHER_iv_length(cipher);
      int blocksize=EVP_CIPHER_block_size(cipher);
      if (blocksize>1024) blocksize=1024;
      u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	     " %s cipher=%s, keylen=%d/%d, ivlen=%d/%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,needkeylen,ivlen,needivlen,blocksize);

      if ((needivlen)&&(ivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      memset(&ctx,0,sizeof(ctx));

      EVP_CIPHER_CTX_init(&ctx);

      retval=EVP_CipherInit(&ctx, cipher, NULL, NULL, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      retval=EVP_CIPHER_CTX_set_key_length(&ctx,keylen);
      if (retval==0)
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",keylen,needkeylen,cname));

      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      retval=EVP_CipherInit(&ctx, cipher, key, iv, do_encrypt);
      if (retval==0)
	return u8_reterr(u8_CipherInit_Failed,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 u8_strdup(cname));

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),
		 cname,totalin,totalout);
	  break;}
	else totalin=totalin+inlen;
	if (!(EVP_CipherUpdate(&ctx,outbuf,&outlen,inbuf,inlen))) {
	  char *details=u8_malloc(256);
	  unsigned long err=ERR_get_error();
	  ERR_error_string_n(err,details,256);
	  EVP_CIPHER_CTX_cleanup(&ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   details);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}
      if (!(EVP_CipherFinal(&ctx,outbuf,&outlen))) {
	char *details=u8_malloc(256);
	unsigned long err=ERR_get_error();
	ERR_error_string_n(err,details,256);
	EVP_CIPHER_CTX_cleanup(&ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):(OPENSSL_CRYPTIC)),
			 details);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,OPENSSL_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	EVP_CIPHER_CTX_cleanup(&ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else {
      char *details=u8_malloc(256);
      unsigned long err=ERR_get_error();
      ERR_error_string_n(err,details,256);
      return u8_reterr("Unknown cipher",
		       ((caller)?(caller):((u8_context)"u8_cryptic")),
		       details);}
  }
}
Esempio n. 16
0
soter_status_t soter_asym_cipher_encrypt(soter_asym_cipher_t* asym_cipher, const void* plain_data, size_t plain_data_length, void* cipher_data, size_t* cipher_data_length)
{
	EVP_PKEY *pkey;
	RSA *rsa;
	int rsa_mod_size;
	size_t output_length;

	if ((!asym_cipher) || (!plain_data) || (0 == plain_data_length) || (!cipher_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 (plain_data_length > (rsa_mod_size - 2 - (2 * OAEP_HASH_SIZE)))
	{
		/* The plaindata is too large 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_encrypt_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_encrypt(asym_cipher->pkey_ctx, NULL, &output_length, (const unsigned char *)plain_data, plain_data_length))
	{
		if (output_length > *cipher_data_length)
		{
			*cipher_data_length = output_length;
			return SOTER_BUFFER_TOO_SMALL;
		}
	}
	else
	{
		return SOTER_FAIL;
	}

	if (EVP_PKEY_encrypt(asym_cipher->pkey_ctx, (unsigned char *)cipher_data, cipher_data_length, (const unsigned char *)plain_data, plain_data_length))
	{
		if (cipher_data)
		{
			return SOTER_SUCCESS;
		}
		else
		{
			return SOTER_BUFFER_TOO_SMALL;
		}
	}
	else
	{
		return SOTER_FAIL;
	}
}