Blame src/p11_pkey.c

Packit 6b81fa
/* libp11, a simple layer on to of PKCS#11 API
Packit 6b81fa
 * Copyright (C) 2017 Douglas E. Engert <deengert@gmail.com>
Packit 6b81fa
 * Copyright (C) 2017-2018 MichaƂ Trojnara <Michal.Trojnara@stunnel.org>
Packit 6b81fa
 *
Packit 6b81fa
 *  This library is free software; you can redistribute it and/or
Packit 6b81fa
 *  modify it under the terms of the GNU Lesser General Public
Packit 6b81fa
 *  License as published by the Free Software Foundation; either
Packit 6b81fa
 *  version 2.1 of the License, or (at your option) any later version.
Packit 6b81fa
 *
Packit 6b81fa
 *  This library is distributed in the hope that it will be useful,
Packit 6b81fa
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6b81fa
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6b81fa
 *  Lesser General Public License for more details.
Packit 6b81fa
 *
Packit 6b81fa
 *  You should have received a copy of the GNU Lesser General Public
Packit 6b81fa
 *  License along with this library; if not, write to the Free Software
Packit 6b81fa
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
Packit 6b81fa
 */
Packit 6b81fa
Packit 6b81fa
#include "libp11-int.h"
Packit 6b81fa
#include <string.h>
Packit 6b81fa
Packit 6b81fa
static int (*orig_pkey_rsa_sign_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
static int (*orig_pkey_rsa_sign) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
	unsigned char *sig, size_t *siglen,
Packit 6b81fa
	const unsigned char *tbs, size_t tbslen);
Packit 6b81fa
static int (*orig_pkey_rsa_decrypt_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
static int (*orig_pkey_rsa_decrypt) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
	unsigned char *out, size_t *outlen,
Packit 6b81fa
	const unsigned char *in, size_t inlen);
Packit 6b81fa
Packit 6b81fa
#ifndef OPENSSL_NO_EC
Packit 6b81fa
static int (*orig_pkey_ec_sign_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
static int (*orig_pkey_ec_sign) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
	unsigned char *sig, size_t *siglen,
Packit 6b81fa
	const unsigned char *tbs, size_t tbslen);
Packit 6b81fa
#endif /* OPENSSL_NO_EC */
Packit 6b81fa
Packit 6b81fa
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Packit 6b81fa
struct evp_pkey_method_st {
Packit 6b81fa
	int pkey_id;
Packit 6b81fa
	int flags;
Packit 6b81fa
	int (*init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
Packit 6b81fa
	void (*cleanup) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*paramgen_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
Packit 6b81fa
	int (*keygen_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
Packit 6b81fa
	int (*sign_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen);
Packit 6b81fa
	int (*verify_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*verify) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
		const unsigned char *sig, size_t siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen);
Packit 6b81fa
	int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*verify_recover) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
		unsigned char *rout, size_t *routlen,
Packit 6b81fa
		const unsigned char *sig, size_t siglen);
Packit 6b81fa
	int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
Packit 6b81fa
	int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
Packit 6b81fa
		EVP_MD_CTX *mctx);
Packit 6b81fa
	int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
Packit 6b81fa
	int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
Packit 6b81fa
		EVP_MD_CTX *mctx);
Packit 6b81fa
	int (*encrypt_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
Packit 6b81fa
		const unsigned char *in, size_t inlen);
Packit 6b81fa
	int (*decrypt_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
Packit 6b81fa
		const unsigned char *in, size_t inlen);
Packit 6b81fa
	int (*derive_init) (EVP_PKEY_CTX *ctx);
Packit 6b81fa
	int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
Packit 6b81fa
	int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
Packit 6b81fa
	int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
Packit 6b81fa
} /* EVP_PKEY_METHOD */ ;
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
Packit 6b81fa
Packit 6b81fa
typedef struct {
Packit 6b81fa
	int nbits;
Packit 6b81fa
	BIGNUM *pub_exp;
Packit 6b81fa
	int gentmp[2];
Packit 6b81fa
	int pad_mode;
Packit 6b81fa
	const EVP_MD *md;
Packit 6b81fa
	const EVP_MD *mgf1md;
Packit 6b81fa
	int saltlen;
Packit 6b81fa
	unsigned char *tbuf;
Packit 6b81fa
} RSA_PKEY_CTX;
Packit 6b81fa
Packit 6b81fa
static int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
Packit 6b81fa
{
Packit 6b81fa
	RSA_PKEY_CTX *rctx = EVP_PKEY_CTX_get_data(ctx);
Packit 6b81fa
	if (rctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*pmd = rctx->md;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
Packit 6b81fa
{
Packit 6b81fa
	RSA_PKEY_CTX *rctx = EVP_PKEY_CTX_get_data(ctx);
Packit 6b81fa
	if (rctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*pmd = rctx->md;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
#if OPENSSL_VERSION_NUMBER < 0x10001000L
Packit 6b81fa
Packit 6b81fa
static int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
Packit 6b81fa
{
Packit 6b81fa
	RSA_PKEY_CTX *rctx = EVP_PKEY_CTX_get_data(ctx);
Packit 6b81fa
	if (rctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*pmd = rctx->mgf1md;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *padding)
Packit 6b81fa
{
Packit 6b81fa
	RSA_PKEY_CTX *rctx = EVP_PKEY_CTX_get_data(ctx);
Packit 6b81fa
	if (rctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*padding = rctx->pad_mode;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
Packit 6b81fa
{
Packit 6b81fa
	RSA_PKEY_CTX *rctx = EVP_PKEY_CTX_get_data(ctx);
Packit 6b81fa
	if (rctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*saltlen = rctx->saltlen;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
Packit 6b81fa
{
Packit 6b81fa
	memcpy((int *)dst + 2, (int *)src + 2, 25 * sizeof(void (*)()));
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
#if OPENSSL_VERSION_NUMBER < 0x100020d0L || defined(LIBRESSL_VERSION_NUMBER)
Packit 6b81fa
static void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth,
Packit 6b81fa
		int (**psign_init) (EVP_PKEY_CTX *ctx),
Packit 6b81fa
		int (**psign) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
			unsigned char *sig, size_t *siglen,
Packit 6b81fa
			const unsigned char *tbs, size_t tbslen))
Packit 6b81fa
{
Packit 6b81fa
	if (psign_init)
Packit 6b81fa
		*psign_init = pmeth->sign_init;
Packit 6b81fa
	if (psign)
Packit 6b81fa
		*psign = pmeth->sign;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth,
Packit 6b81fa
		int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
Packit 6b81fa
		int (**pdecrypt) (EVP_PKEY_CTX *ctx,
Packit 6b81fa
			unsigned char *out,
Packit 6b81fa
			size_t *outlen,
Packit 6b81fa
			const unsigned char *in,
Packit 6b81fa
			size_t inlen))
Packit 6b81fa
{
Packit 6b81fa
	if (pdecrypt_init)
Packit 6b81fa
		*pdecrypt_init = pmeth->decrypt_init;
Packit 6b81fa
	if (pdecrypt)
Packit 6b81fa
		*pdecrypt = pmeth->decrypt;
Packit 6b81fa
}
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
static CK_MECHANISM_TYPE pkcs11_md2ckm(const EVP_MD *md)
Packit 6b81fa
{
Packit 6b81fa
	switch (EVP_MD_type(md)) {
Packit 6b81fa
	case NID_sha1:
Packit 6b81fa
		return CKM_SHA_1;
Packit 6b81fa
	case NID_sha224:
Packit 6b81fa
		return CKM_SHA224;
Packit 6b81fa
	case NID_sha256:
Packit 6b81fa
		return CKM_SHA256;
Packit 6b81fa
	case NID_sha512:
Packit 6b81fa
		return CKM_SHA512;
Packit 6b81fa
	case NID_sha384:
Packit 6b81fa
		return CKM_SHA384;
Packit 6b81fa
	default:
Packit 6b81fa
		return 0;
Packit 6b81fa
	}
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static CK_RSA_PKCS_MGF_TYPE pkcs11_md2ckg(const EVP_MD *md)
Packit 6b81fa
{
Packit 6b81fa
	switch (EVP_MD_type(md)) {
Packit 6b81fa
	case NID_sha1:
Packit 6b81fa
		return CKG_MGF1_SHA1;
Packit 6b81fa
	case NID_sha224:
Packit 6b81fa
		return CKG_MGF1_SHA224;
Packit 6b81fa
	case NID_sha256:
Packit 6b81fa
		return CKG_MGF1_SHA256;
Packit 6b81fa
	case NID_sha512:
Packit 6b81fa
		return CKG_MGF1_SHA512;
Packit 6b81fa
	case NID_sha384:
Packit 6b81fa
		return CKG_MGF1_SHA384;
Packit 6b81fa
	default:
Packit 6b81fa
		return 0;
Packit 6b81fa
	}
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_params_pss(CK_RSA_PKCS_PSS_PARAMS *pss,
Packit 6b81fa
		EVP_PKEY_CTX *ctx)
Packit 6b81fa
{
Packit 6b81fa
	const EVP_MD *sig_md, *mgf1_md;
Packit 6b81fa
	EVP_PKEY *evp_pkey;
Packit 6b81fa
	int salt_len;
Packit 6b81fa
Packit 6b81fa
	/* retrieve PSS parameters */
Packit 6b81fa
	if (EVP_PKEY_CTX_get_signature_md(ctx, &sig_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	if (EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &salt_len))
Packit 6b81fa
		return -1;
Packit 6b81fa
	switch (salt_len) {
Packit 6b81fa
	case -1:
Packit 6b81fa
		salt_len = EVP_MD_size(sig_md);
Packit 6b81fa
		break;
Packit 6b81fa
	case -2:
Packit 6b81fa
		evp_pkey = EVP_PKEY_CTX_get0_pkey(ctx);
Packit 6b81fa
		if (evp_pkey == NULL)
Packit 6b81fa
			return -1;
Packit 6b81fa
		salt_len = EVP_PKEY_size(evp_pkey) - EVP_MD_size(sig_md) - 2;
Packit 6b81fa
		if (((EVP_PKEY_bits(evp_pkey) - 1) & 0x7) == 0)
Packit 6b81fa
			salt_len--;
Packit 6b81fa
		if (salt_len < 0) /* integer underflow detected */
Packit 6b81fa
			return -1;
Packit 6b81fa
	}
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "salt_len=%d sig_md=%s mdf1_md=%s\n",
Packit 6b81fa
		salt_len, EVP_MD_name(sig_md), EVP_MD_name(mgf1_md));
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	/* fill the CK_RSA_PKCS_PSS_PARAMS structure */
Packit 6b81fa
	memset(pss, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS));
Packit 6b81fa
	pss->hashAlg = pkcs11_md2ckm(sig_md);
Packit 6b81fa
	pss->mgf = pkcs11_md2ckg(mgf1_md);
Packit 6b81fa
	if (!pss->hashAlg || !pss->mgf)
Packit 6b81fa
		return -1;
Packit 6b81fa
	pss->sLen = salt_len;
Packit 6b81fa
	return 0;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_params_oaep(CK_RSA_PKCS_OAEP_PARAMS *oaep,
Packit 6b81fa
		EVP_PKEY_CTX *ctx)
Packit 6b81fa
{
Packit 6b81fa
	const EVP_MD *oaep_md, *mgf1_md;
Packit 6b81fa
Packit 6b81fa
	/* retrieve OAEP parameters */
Packit 6b81fa
	if (EVP_PKEY_CTX_get_rsa_oaep_md(ctx, &oaep_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	if (EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "oaep_md=%s mdf1_md=%s\n",
Packit 6b81fa
		EVP_MD_name(oaep_md), EVP_MD_name(mgf1_md));
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	/* fill the CK_RSA_PKCS_OAEP_PARAMS structure */
Packit 6b81fa
	memset(oaep, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
Packit 6b81fa
	oaep->hashAlg = pkcs11_md2ckm(oaep_md);
Packit 6b81fa
	oaep->mgf = pkcs11_md2ckg(mgf1_md);
Packit 6b81fa
	if (!oaep->hashAlg || !oaep->mgf)
Packit 6b81fa
		return -1;
Packit 6b81fa
	/* we do not support the OAEP "label" parameter yet... */
Packit 6b81fa
	oaep->source = 0UL; /* empty parameter (label) */
Packit 6b81fa
	oaep->pSourceData = NULL;
Packit 6b81fa
	oaep->ulSourceDataLen = 0;
Packit 6b81fa
	return 0;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *sig, size_t *siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen)
Packit 6b81fa
{
Packit 6b81fa
	EVP_PKEY *pkey;
Packit 6b81fa
	RSA *rsa;
Packit 6b81fa
	PKCS11_KEY *key;
Packit 6b81fa
	int rv = 0;
Packit 6b81fa
	CK_ULONG size = *siglen;
Packit 6b81fa
	PKCS11_SLOT *slot;
Packit 6b81fa
	PKCS11_CTX *ctx;
Packit 6b81fa
	PKCS11_KEY_private *kpriv;
Packit 6b81fa
	PKCS11_SLOT_private *spriv;
Packit 6b81fa
	PKCS11_CTX_private *cpriv;
Packit 6b81fa
	const EVP_MD *sig_md;
Packit 6b81fa
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d pkcs11_try_pkey_rsa_sign() "
Packit 6b81fa
		"sig=%p *siglen=%lu tbs=%p tbslen=%lu\n",
Packit 6b81fa
		__FILE__, __LINE__, sig, *siglen, tbs, tbslen);
Packit 6b81fa
#endif
Packit 6b81fa
	pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
Packit 6b81fa
	if (pkey == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	rsa = EVP_PKEY_get0_RSA(pkey);
Packit 6b81fa
	if (rsa == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	key = pkcs11_get_ex_data_rsa(rsa);
Packit 6b81fa
	if (check_key_fork(key) < 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	slot = KEY2SLOT(key);
Packit 6b81fa
	ctx = KEY2CTX(key);
Packit 6b81fa
	kpriv = PRIVKEY(key);
Packit 6b81fa
	spriv = PRIVSLOT(slot);
Packit 6b81fa
	cpriv = PRIVCTX(ctx);
Packit 6b81fa
Packit 6b81fa
	if (evp_pkey_ctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	if (tbslen != (size_t)EVP_MD_size(sig_md))
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (!cpriv->sign_initialized) {
Packit 6b81fa
		int padding;
Packit 6b81fa
		CK_MECHANISM mechanism;
Packit 6b81fa
		CK_RSA_PKCS_PSS_PARAMS pss_params;
Packit 6b81fa
Packit 6b81fa
		memset(&mechanism, 0, sizeof mechanism);
Packit 6b81fa
		EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
Packit 6b81fa
		switch (padding) {
Packit 6b81fa
		case RSA_PKCS1_PSS_PADDING:
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
			fprintf(stderr, "%s:%d padding=RSA_PKCS1_PSS_PADDING\n",
Packit 6b81fa
				__FILE__, __LINE__);
Packit 6b81fa
#endif
Packit 6b81fa
			if (pkcs11_params_pss(&pss_params, evp_pkey_ctx) < 0)
Packit 6b81fa
				return -1;
Packit 6b81fa
			mechanism.mechanism = CKM_RSA_PKCS_PSS;
Packit 6b81fa
			mechanism.pParameter = &pss_params;
Packit 6b81fa
			mechanism.ulParameterLen = sizeof pss_params;
Packit 6b81fa
			break;
Packit 6b81fa
		default:
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
			fprintf(stderr, "%s:%d unsupported padding: %d\n",
Packit 6b81fa
				__FILE__, __LINE__, padding);
Packit 6b81fa
#endif
Packit 6b81fa
			return -1;
Packit 6b81fa
		} /* end switch(padding) */
Packit 6b81fa
Packit 6b81fa
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_SignInit(spriv->session, &mechanism, kpriv->object));
Packit 6b81fa
		if (!rv && kpriv->always_authenticate == CK_TRUE)
Packit 6b81fa
			rv = pkcs11_authenticate(key);
Packit 6b81fa
	}
Packit 6b81fa
	if (!rv)
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_Sign(spriv->session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
Packit 6b81fa
	cpriv->sign_initialized = !rv && sig == NULL;
Packit 6b81fa
	if (!cpriv->sign_initialized)
Packit 6b81fa
		CRYPTO_THREAD_unlock(cpriv->rwlock);
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d C_SignInit or C_Sign rv=%d\n",
Packit 6b81fa
		__FILE__, __LINE__, rv);
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	if (rv != CKR_OK)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*siglen = size;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *sig, size_t *siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen)
Packit 6b81fa
{
Packit 6b81fa
	int ret;
Packit 6b81fa
Packit 6b81fa
	ret = pkcs11_try_pkey_rsa_sign(evp_pkey_ctx, sig, siglen, tbs, tbslen);
Packit 6b81fa
	if (ret < 0)
Packit 6b81fa
		ret = (*orig_pkey_rsa_sign)(evp_pkey_ctx, sig, siglen, tbs, tbslen);
Packit 6b81fa
	return ret;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_try_pkey_rsa_decrypt(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *out, size_t *outlen,
Packit 6b81fa
		const unsigned char *in, size_t inlen)
Packit 6b81fa
{
Packit 6b81fa
	EVP_PKEY *pkey;
Packit 6b81fa
	RSA *rsa;
Packit 6b81fa
	PKCS11_KEY *key;
Packit 6b81fa
	int rv = 0;
Packit 6b81fa
	CK_ULONG size = *outlen;
Packit 6b81fa
	PKCS11_SLOT *slot;
Packit 6b81fa
	PKCS11_CTX *ctx;
Packit 6b81fa
	PKCS11_KEY_private *kpriv;
Packit 6b81fa
	PKCS11_SLOT_private *spriv;
Packit 6b81fa
	PKCS11_CTX_private *cpriv;
Packit 6b81fa
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d pkcs11_try_pkey_rsa_decrypt() "
Packit 6b81fa
		"out=%p *outlen=%lu in=%p inlen=%lu\n",
Packit 6b81fa
		__FILE__, __LINE__, out, *outlen, in, inlen);
Packit 6b81fa
#endif
Packit 6b81fa
	pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
Packit 6b81fa
	if (pkey == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	rsa = EVP_PKEY_get0_RSA(pkey);
Packit 6b81fa
	if (rsa == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
	key = pkcs11_get_ex_data_rsa(rsa);
Packit 6b81fa
	if (check_key_fork(key) < 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
	slot = KEY2SLOT(key);
Packit 6b81fa
	ctx = KEY2CTX(key);
Packit 6b81fa
	kpriv = PRIVKEY(key);
Packit 6b81fa
	spriv = PRIVSLOT(slot);
Packit 6b81fa
	cpriv = PRIVCTX(ctx);
Packit 6b81fa
Packit 6b81fa
	if (evp_pkey_ctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (!cpriv->decrypt_initialized) {
Packit 6b81fa
		int padding;
Packit 6b81fa
		CK_MECHANISM mechanism;
Packit 6b81fa
		CK_RSA_PKCS_OAEP_PARAMS oaep_params;
Packit 6b81fa
Packit 6b81fa
		memset(&mechanism, 0, sizeof mechanism);
Packit 6b81fa
		EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
Packit 6b81fa
		switch (padding) {
Packit 6b81fa
		case RSA_PKCS1_OAEP_PADDING:
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
			fprintf(stderr, "%s:%d padding=RSA_PKCS1_OAEP_PADDING\n",
Packit 6b81fa
				__FILE__, __LINE__);
Packit 6b81fa
#endif
Packit 6b81fa
			if (pkcs11_params_oaep(&oaep_params, evp_pkey_ctx) < 0)
Packit 6b81fa
				return -1;
Packit 6b81fa
			mechanism.mechanism = CKM_RSA_PKCS_OAEP;
Packit 6b81fa
			mechanism.pParameter = &oaep_params;
Packit 6b81fa
			mechanism.ulParameterLen = sizeof oaep_params;
Packit 6b81fa
			break;
Packit 6b81fa
		case CKM_RSA_PKCS:
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
			fprintf(stderr, "%s:%d padding=CKM_RSA_PKCS\n",
Packit 6b81fa
				__FILE__, __LINE__);
Packit 6b81fa
#endif
Packit 6b81fa
			mechanism.pParameter = NULL;
Packit 6b81fa
			mechanism.ulParameterLen = 0;
Packit 6b81fa
			break;
Packit 6b81fa
		default:
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
			fprintf(stderr, "%s:%d unsupported padding: %d\n",
Packit 6b81fa
				__FILE__, __LINE__, padding);
Packit 6b81fa
#endif
Packit 6b81fa
			return -1;
Packit 6b81fa
		} /* end switch(padding) */
Packit 6b81fa
Packit 6b81fa
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_DecryptInit(spriv->session, &mechanism, kpriv->object));
Packit 6b81fa
		if (!rv && kpriv->always_authenticate == CK_TRUE)
Packit 6b81fa
			rv = pkcs11_authenticate(key);
Packit 6b81fa
	}
Packit 6b81fa
	if (!rv)
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_Decrypt(spriv->session, (CK_BYTE_PTR)in, inlen, out, &size));
Packit 6b81fa
	cpriv->decrypt_initialized = !rv && out == NULL;
Packit 6b81fa
	if (!cpriv->decrypt_initialized)
Packit 6b81fa
		CRYPTO_THREAD_unlock(cpriv->rwlock);
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d C_DecryptInit or C_Decrypt rv=%d\n",
Packit 6b81fa
		__FILE__, __LINE__, rv);
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	if (rv != CKR_OK)
Packit 6b81fa
		return -1;
Packit 6b81fa
	*outlen = size;
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_pkey_rsa_decrypt(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *out, size_t *outlen,
Packit 6b81fa
		const unsigned char *in, size_t inlen)
Packit 6b81fa
{
Packit 6b81fa
	int ret;
Packit 6b81fa
Packit 6b81fa
	ret = pkcs11_try_pkey_rsa_decrypt(evp_pkey_ctx, out, outlen, in, inlen);
Packit 6b81fa
	if (ret < 0)
Packit 6b81fa
		ret = (*orig_pkey_rsa_decrypt)(evp_pkey_ctx, out, outlen, in, inlen);
Packit 6b81fa
	return ret;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static EVP_PKEY_METHOD *pkcs11_pkey_method_rsa()
Packit 6b81fa
{
Packit 6b81fa
	EVP_PKEY_METHOD *orig_meth, *new_meth;
Packit 6b81fa
Packit 6b81fa
	orig_meth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(EVP_PKEY_RSA);
Packit 6b81fa
	EVP_PKEY_meth_get_sign(orig_meth,
Packit 6b81fa
		&orig_pkey_rsa_sign_init, &orig_pkey_rsa_sign);
Packit 6b81fa
	EVP_PKEY_meth_get_decrypt(orig_meth,
Packit 6b81fa
		&orig_pkey_rsa_decrypt_init,
Packit 6b81fa
		&orig_pkey_rsa_decrypt);
Packit 6b81fa
Packit 6b81fa
	new_meth = EVP_PKEY_meth_new(EVP_PKEY_RSA,
Packit 6b81fa
		EVP_PKEY_FLAG_AUTOARGLEN);
Packit 6b81fa
Packit 6b81fa
	EVP_PKEY_meth_copy(new_meth, orig_meth);
Packit 6b81fa
Packit 6b81fa
	EVP_PKEY_meth_set_sign(new_meth,
Packit 6b81fa
		orig_pkey_rsa_sign_init, pkcs11_pkey_rsa_sign);
Packit 6b81fa
	EVP_PKEY_meth_set_decrypt(new_meth,
Packit 6b81fa
		orig_pkey_rsa_decrypt_init, pkcs11_pkey_rsa_decrypt);
Packit 6b81fa
Packit 6b81fa
	return new_meth;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
#ifndef OPENSSL_NO_EC
Packit 6b81fa
Packit 6b81fa
static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *sig, size_t *siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen)
Packit 6b81fa
{
Packit 6b81fa
	EVP_PKEY *pkey;
Packit 6b81fa
	EC_KEY *eckey;
Packit 6b81fa
	PKCS11_KEY *key;
Packit 6b81fa
	int rv = 0;
Packit 6b81fa
	CK_ULONG size = *siglen;
Packit 6b81fa
	PKCS11_SLOT *slot;
Packit 6b81fa
	PKCS11_CTX *ctx;
Packit 6b81fa
	PKCS11_KEY_private *kpriv;
Packit 6b81fa
	PKCS11_SLOT_private *spriv;
Packit 6b81fa
	PKCS11_CTX_private *cpriv;
Packit 6b81fa
	const EVP_MD *sig_md;
Packit 6b81fa
	ECDSA_SIG *ossl_sig;
Packit 6b81fa
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d pkcs11_try_pkey_ec_sign() "
Packit 6b81fa
		"sig=%p *siglen=%lu tbs=%p tbslen=%lu\n",
Packit 6b81fa
		__FILE__, __LINE__, sig, *siglen, tbs, tbslen);
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	ossl_sig = ECDSA_SIG_new();
Packit 6b81fa
	if (ossl_sig == NULL)
Packit Service 975729
		return-1;
Packit 6b81fa
Packit 6b81fa
	pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
Packit 6b81fa
	if (pkey == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	eckey = (EC_KEY *)EVP_PKEY_get0_EC_KEY(pkey);
Packit 6b81fa
	if (eckey == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (*siglen < (size_t)ECDSA_size(eckey))
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	key = pkcs11_get_ex_data_ec(eckey);
Packit 6b81fa
	if (check_key_fork(key) < 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	slot = KEY2SLOT(key);
Packit 6b81fa
	ctx = KEY2CTX(key);
Packit 6b81fa
	kpriv = PRIVKEY(key);
Packit 6b81fa
	spriv = PRIVSLOT(slot);
Packit 6b81fa
	cpriv = PRIVCTX(ctx);
Packit 6b81fa
Packit 6b81fa
	if (evp_pkey_ctx == NULL)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (tbslen < (size_t)EVP_MD_size(sig_md))
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	if (!cpriv->sign_initialized) {
Packit Service 975729
		int padding;
Packit 6b81fa
		CK_MECHANISM mechanism;
Packit 6b81fa
		memset(&mechanism, 0, sizeof mechanism);
Packit 6b81fa
Packit 6b81fa
		mechanism.mechanism = CKM_ECDSA;
Packit 6b81fa
Packit 6b81fa
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_SignInit(spriv->session, &mechanism, kpriv->object));
Packit 6b81fa
		if (!rv && kpriv->always_authenticate == CK_TRUE)
Packit 6b81fa
			rv = pkcs11_authenticate(key);
Packit 6b81fa
	}
Packit 6b81fa
	if (!rv)
Packit 6b81fa
		rv = CRYPTOKI_call(ctx,
Packit 6b81fa
			C_Sign(spriv->session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
Packit 6b81fa
Packit 6b81fa
	cpriv->sign_initialized = !rv && sig == NULL;
Packit 6b81fa
	if (!cpriv->sign_initialized)
Packit 6b81fa
		CRYPTO_THREAD_unlock(cpriv->rwlock);
Packit 6b81fa
#ifdef DEBUG
Packit 6b81fa
	fprintf(stderr, "%s:%d C_SignInit or C_Sign rv=%d\n",
Packit 6b81fa
		__FILE__, __LINE__, rv);
Packit 6b81fa
#endif
Packit 6b81fa
Packit 6b81fa
	if (rv == CKR_OK) {
Packit 6b81fa
		BIGNUM *r = BN_bin2bn(sig, size/2, NULL);
Packit 6b81fa
		BIGNUM *s = BN_bin2bn(sig + size/2, size/2, NULL);
Packit 6b81fa
Packit 6b81fa
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
Packit 6b81fa
		ECDSA_SIG_set0(ossl_sig, r, s);
Packit 6b81fa
#else
Packit 6b81fa
		BN_free(ossl_sig->r);
Packit 6b81fa
		ossl_sig->r = r;
Packit 6b81fa
		BN_free(ossl_sig->s);
Packit 6b81fa
		ossl_sig->s = s;
Packit 6b81fa
#endif
Packit 6b81fa
		*siglen = i2d_ECDSA_SIG(ossl_sig, &sig);
Packit 6b81fa
	}
Packit 6b81fa
Packit 6b81fa
	ECDSA_SIG_free(ossl_sig);
Packit 6b81fa
Packit 6b81fa
	if (rv != CKR_OK)
Packit 6b81fa
		return -1;
Packit 6b81fa
Packit 6b81fa
	return 1;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static int pkcs11_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx,
Packit 6b81fa
		unsigned char *sig, size_t *siglen,
Packit 6b81fa
		const unsigned char *tbs, size_t tbslen)
Packit 6b81fa
{
Packit 6b81fa
	int ret;
Packit 6b81fa
Packit 6b81fa
	ret = pkcs11_try_pkey_ec_sign(evp_pkey_ctx, sig, siglen, tbs, tbslen);
Packit 6b81fa
	if (ret < 0)
Packit 6b81fa
		ret = (*orig_pkey_ec_sign)(evp_pkey_ctx, sig, siglen, tbs, tbslen);
Packit 6b81fa
	return ret;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
static EVP_PKEY_METHOD *pkcs11_pkey_method_ec()
Packit 6b81fa
{
Packit 6b81fa
	EVP_PKEY_METHOD *orig_meth, *new_meth;
Packit 6b81fa
Packit 6b81fa
	orig_meth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(EVP_PKEY_EC);
Packit 6b81fa
	EVP_PKEY_meth_get_sign(orig_meth,
Packit 6b81fa
		&orig_pkey_ec_sign_init, &orig_pkey_ec_sign);
Packit 6b81fa
Packit 6b81fa
	new_meth = EVP_PKEY_meth_new(EVP_PKEY_EC,
Packit 6b81fa
		EVP_PKEY_FLAG_AUTOARGLEN);
Packit 6b81fa
Packit 6b81fa
	EVP_PKEY_meth_copy(new_meth, orig_meth);
Packit 6b81fa
Packit 6b81fa
	EVP_PKEY_meth_set_sign(new_meth,
Packit 6b81fa
		orig_pkey_ec_sign_init, pkcs11_pkey_ec_sign);
Packit 6b81fa
Packit 6b81fa
	return new_meth;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
#endif /* OPENSSL_NO_EC */
Packit 6b81fa
Packit 6b81fa
int PKCS11_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
Packit 6b81fa
		const int **nids, int nid)
Packit 6b81fa
{
Packit 6b81fa
	static int pkey_nids[] = {
Packit 6b81fa
		EVP_PKEY_RSA,
Packit 6b81fa
		EVP_PKEY_EC,
Packit 6b81fa
		0
Packit 6b81fa
	};
Packit Service 975729
	static EVP_PKEY_METHOD *pkey_method_rsa = NULL;
Packit Service 975729
	static EVP_PKEY_METHOD *pkey_method_ec = NULL;
Packit 6b81fa
Packit 6b81fa
	(void)e; /* squash the unused parameter warning */
Packit 6b81fa
	/* all PKCS#11 engines currently share the same pkey_meths */
Packit 6b81fa
Packit 6b81fa
	if (!pmeth) { /* get the list of supported nids */
Packit 6b81fa
		*nids = pkey_nids;
Packit 6b81fa
		return sizeof(pkey_nids) / sizeof(int) - 1;
Packit 6b81fa
	}
Packit 6b81fa
Packit 6b81fa
	/* get the EVP_PKEY_METHOD */
Packit 6b81fa
	switch (nid) {
Packit 6b81fa
	case EVP_PKEY_RSA:
Packit Service 975729
		if (pkey_method_rsa == NULL)
Packit Service 975729
			pkey_method_rsa = pkcs11_pkey_method_rsa();
Packit 6b81fa
		if (pkey_method_rsa == NULL)
Packit 6b81fa
			return 0;
Packit 6b81fa
		*pmeth = pkey_method_rsa;
Packit 6b81fa
		return 1; /* success */
Packit 6b81fa
#ifndef OPENSSL_NO_EC
Packit 6b81fa
	case EVP_PKEY_EC:
Packit Service 975729
		if (pkey_method_ec == NULL)
Packit Service 975729
			pkey_method_ec = pkcs11_pkey_method_ec();
Packit 6b81fa
		if (pkey_method_ec == NULL)
Packit 6b81fa
			return 0;
Packit 6b81fa
		*pmeth = pkey_method_ec;
Packit 6b81fa
		return 1; /* success */
Packit 6b81fa
#endif /* OPENSSL_NO_EC */
Packit 6b81fa
	}
Packit 6b81fa
	*pmeth = NULL;
Packit 6b81fa
	return 0;
Packit 6b81fa
}
Packit 6b81fa
Packit 6b81fa
/* vim: set noexpandtab: */