diff --git a/src/libp11-int.h b/src/libp11-int.h index 020ad463..59285103 100644 --- a/src/libp11-int.h +++ b/src/libp11-int.h @@ -389,6 +389,10 @@ extern int pkcs11_evp_pkey_rsa_sign(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, const unsigned char *tbs, size_t tbslen); #ifndef OPENSSL_NO_EC +extern ECDSA_SIG *pkcs11_ec_sign_raw(PKCS11_OBJECT_private *key, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + /* Sign digest input with EC private key via PKCS#11 and encode signature as DER */ extern int pkcs11_evp_pkey_ec_sign(PKCS11_OBJECT_private *key, unsigned char *sig, size_t *siglen, diff --git a/src/p11_ec.c b/src/p11_ec.c index 4ddb5f4f..50d18ba2 100644 --- a/src/p11_ec.c +++ b/src/p11_ec.c @@ -415,44 +415,6 @@ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_OBJECT_private *key) /********** ECDSA signing */ -/* Signature size is the issue, will assume the caller has a big buffer! */ -/* No padding or other stuff needed. We can call PKCS11 from here */ -static int pkcs11_ecdsa_sign(const unsigned char *msg, unsigned int msg_len, - unsigned char *sigret, unsigned int *siglen, PKCS11_OBJECT_private *key) -{ - int rv; - PKCS11_SLOT_private *slot = key->slot; - PKCS11_CTX_private *ctx = slot->ctx; - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ULONG ck_sigsize; - - ck_sigsize = *siglen; - - memset(&mechanism, 0, sizeof(mechanism)); - mechanism.mechanism = CKM_ECDSA; - - if (pkcs11_get_session(slot, 0, &session)) - return -1; - - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize)); - pkcs11_put_session(slot, session); - - if (rv) { - CKRerr(CKR_F_PKCS11_ECDSA_SIGN, rv); - return -1; - } - *siglen = ck_sigsize; - - return ck_sigsize; -} - #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) static void pkcs11_ec_finish(EC_KEY *ec) @@ -483,14 +445,10 @@ static void pkcs11_ec_finish(EC_KEY *ec) static ECDSA_SIG *pkcs11_ecdsa_sign_sig(const unsigned char *dgst, int dlen, const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *ec) { - unsigned char sigret[512]; /* HACK for now */ - ECDSA_SIG *sig; + unsigned char sigret[512]; /* existing temporary buffer size */ + size_t siglen = sizeof sigret; PKCS11_OBJECT_private *key; - unsigned int siglen; - BIGNUM *r, *s, *order; - - (void)kinv; /* Precomputed values are not used for PKCS#11 */ - (void)rp; /* Precomputed values are not used for PKCS#11 */ + BIGNUM *order; key = pkcs11_get_ex_data_ec(ec); if (check_object_fork(key) < 0) { @@ -517,25 +475,7 @@ static ECDSA_SIG *pkcs11_ecdsa_sign_sig(const unsigned char *dgst, int dlen, } BN_free(order); } - - siglen = sizeof sigret; - if (pkcs11_ecdsa_sign(dgst, dlen, sigret, &siglen, key) <= 0) - return NULL; - - r = BN_bin2bn(sigret, siglen/2, NULL); - s = BN_bin2bn(sigret + siglen/2, siglen/2, NULL); - sig = ECDSA_SIG_new(); - if (!sig) - return NULL; -#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL ) - ECDSA_SIG_set0(sig, r, s); -#else - BN_free(sig->r); - sig->r = r; - BN_free(sig->s); - sig->s = s; -#endif - return sig; + return pkcs11_ec_sign_raw(key, sigret, &siglen, dgst, dlen); } /********** ECDH key derivation */ diff --git a/src/p11_eddsa.c b/src/p11_eddsa.c index 4c8e17fb..d0f90862 100644 --- a/src/p11_eddsa.c +++ b/src/p11_eddsa.c @@ -50,56 +50,20 @@ int (*orig_ed448_digestsign)(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen #if OPENSSL_VERSION_NUMBER < 0x40000000L -/* PKCS#11 sign implementation for Ed25519 / Ed448 */ -static int pkcs11_eddsa_sign(unsigned char *sigret, unsigned int *siglen, - const unsigned char *tbs, unsigned int tbslen, PKCS11_OBJECT_private *key) -{ - int rv; - PKCS11_SLOT_private *slot = key->slot; - PKCS11_CTX_private *ctx = slot->ctx; - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ULONG ck_siglen = (CK_ULONG)(*siglen); - CK_ULONG ck_tbslen = (CK_ULONG)tbslen; - - /* PureEdDSA, no prehash */ - memset(&mechanism, 0, sizeof(mechanism)); - mechanism.mechanism = CKM_EDDSA; - - if (pkcs11_get_session(slot, 0, &session)) - return -1; - - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE_PTR)tbs, ck_tbslen, sigret, &ck_siglen)); - pkcs11_put_session(slot, session); - - if (rv) { - CKRerr(CKR_F_PKCS11_EDDSA_SIGN, rv); - return -1; - } - *siglen = (unsigned int)ck_siglen; - return (int)ck_siglen; -} - /* * EVP_PKEY method sign wrapper for EdDSA. * This function is invoked internally by EVP_PKEY_sign(). - * If the key belongs to PKCS#11, perform signing via pkcs11_eddsa_sign(). + * If the key belongs to PKCS#11, perform signing via pkcs11_evp_pkey_eddsa_sign(). */ static int pkcs11_eddsa_pmeth_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { EVP_PKEY *pkey; PKCS11_OBJECT_private *key; - int rv; - unsigned int tmp_len; + PKCS11_SLOT_private *slot; + CK_SESSION_HANDLE session; - if (*siglen > UINT_MAX) + if (siglen == NULL || *siglen > UINT_MAX) return 0; pkey = EVP_PKEY_CTX_get0_pkey(ctx); @@ -110,12 +74,16 @@ static int pkcs11_eddsa_pmeth_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, if (!key) return 0; - tmp_len = (unsigned int)*siglen; - rv = pkcs11_eddsa_sign(sig, &tmp_len, tbs, (unsigned int)tbslen, key); - if (rv < 0) + slot = key->slot; + if (!slot) + return 0; + + if (pkcs11_get_session(slot, 0, &session)) + return 0; + + if (!pkcs11_evp_pkey_eddsa_sign(key, sig, siglen, tbs, tbslen)) return 0; - *siglen = tmp_len; return 1; } @@ -126,7 +94,7 @@ static int pkcs11_eddsa_pmeth_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, * 1. Query the required signature length (sig == NULL). * 2. Perform the actual signing when a buffer is provided (sig != NULL). * - * If the key is managed by PKCS#11, the signing is performed via pkcs11_eddsa_sign(). + * If the key is managed by PKCS#11, the signing is performed via pkcs11_evp_pkey_eddsa_sign(). * Otherwise, the call is delegated to the original OpenSSL Ed25519/Ed448 implementation. */ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, @@ -134,8 +102,11 @@ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, { EVP_PKEY *pkey; PKCS11_OBJECT_private *key; - unsigned int tmp_len; - int rv; + PKCS11_SLOT_private *slot; + CK_SESSION_HANDLE session; + + if (siglen == NULL) + return -1; pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); if (!pkey) @@ -145,6 +116,13 @@ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, if (!key) return -1; + slot = key->slot; + if (!slot) + return -1; + + if (pkcs11_get_session(slot, 0, &session)) + return -1; + /* Step 1: caller asks for signature length only */ if (sig == NULL) { if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) @@ -159,12 +137,9 @@ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, } /* Step 2: actual signing */ - tmp_len = (unsigned int)*siglen; - rv = pkcs11_eddsa_sign(sig, &tmp_len, tbs, (unsigned int)tbslen, key); - if (rv < 0) + if (!pkcs11_evp_pkey_eddsa_sign(key, sig, siglen, tbs, tbslen)) return -1; - *siglen = tmp_len; return 1; } diff --git a/src/p11_key.c b/src/p11_key.c index c4a8ea62..3c1f0328 100644 --- a/src/p11_key.c +++ b/src/p11_key.c @@ -1192,76 +1192,6 @@ void free_pkey_ex_index(void) } # endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ -static int pkcs11_params_pss(CK_RSA_PKCS_PSS_PARAMS *pss, - EVP_PKEY_CTX *ctx, PKCS11_CTX_private *pctx) -{ - const EVP_MD *sig_md, *mgf1_md; - EVP_PKEY *evp_pkey; - int salt_len; - - /* retrieve PSS parameters */ - if (EVP_PKEY_CTX_get_signature_md(ctx, &sig_md) <= 0) - return -1; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1_md) <= 0) - return -1; - if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &salt_len)) - return -1; - switch (salt_len) { - case -1: - salt_len = EVP_MD_size(sig_md); - break; - case -2: - if (!ctx) - return -1; - evp_pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!evp_pkey) - return -1; - salt_len = EVP_PKEY_size(evp_pkey) - EVP_MD_size(sig_md) - 2; - if (((EVP_PKEY_bits(evp_pkey) - 1) & 0x7) == 0) - salt_len--; - if (salt_len < 0) /* integer underflow detected */ - return -1; - } - pkcs11_log(pctx, LOG_DEBUG, "salt_len=%d sig_md=%s mdf1_md=%s\n", - salt_len, EVP_MD_name(sig_md), EVP_MD_name(mgf1_md)); - - /* fill the CK_RSA_PKCS_PSS_PARAMS structure */ - memset(pss, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS)); - pss->hashAlg = pkcs11_md2ckm(sig_md); - pss->mgf = pkcs11_md2ckg(mgf1_md); - if (!pss->hashAlg || !pss->mgf) - return -1; - pss->sLen = salt_len; - return 0; -} - -static int pkcs11_params_oaep(CK_RSA_PKCS_OAEP_PARAMS *oaep, - EVP_PKEY_CTX *ctx, PKCS11_CTX_private *pctx) -{ - const EVP_MD *oaep_md, *mgf1_md; - - /* retrieve OAEP parameters */ - if (EVP_PKEY_CTX_get_rsa_oaep_md(ctx, &oaep_md) <= 0) - return -1; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1_md) <= 0) - return -1; - - pkcs11_log(pctx, LOG_DEBUG, "oaep_md=%s mdf1_md=%s\n", - EVP_MD_name(oaep_md), EVP_MD_name(mgf1_md)); - - /* fill the CK_RSA_PKCS_OAEP_PARAMS structure */ - memset(oaep, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS)); - oaep->hashAlg = pkcs11_md2ckm(oaep_md); - oaep->mgf = pkcs11_md2ckg(mgf1_md); - if (!oaep->hashAlg || !oaep->mgf) - return -1; - /* we do not support the OAEP "label" parameter yet... */ - oaep->source = CKZ_DATA_SPECIFIED; - oaep->pSourceData = NULL; /* empty parameter (label) */ - oaep->ulSourceDataLen = 0; - return 0; -} - /* Attempt to sign using the PKCS#11-backed RSA implementation */ static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx, unsigned char *sig, size_t *siglen, @@ -1269,26 +1199,26 @@ static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx, { EVP_PKEY *pkey; RSA *rsa; - int rv = 0, padding; - CK_ULONG size = (CK_ULONG)*siglen; + int padding; PKCS11_OBJECT_private *key; PKCS11_SLOT_private *slot; - PKCS11_CTX_private *ctx; - const EVP_MD *sig_md; + const EVP_MD *md, *mgf1_md; CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_RSA_PKCS_PSS_PARAMS pss_params; + const char *mdname, *mgf1_mdname; + int salt_len; /* RSA method has EVP_PKEY_FLAG_AUTOARGLEN set. OpenSSL core will handle * the size inquiry internally. */ if (!sig) return -1; + if (!evp_pkey_ctx) return -1; pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx); if (!pkey) return -1; + rsa = (RSA *)EVP_PKEY_get0_RSA(pkey); if (!rsa) return -1; @@ -1298,58 +1228,37 @@ static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx, return -1; slot = key->slot; - ctx = slot->ctx; - if (!ctx) + if (!slot) return -1; -#ifdef DEBUG - pkcs11_log(ctx, LOG_DEBUG, "%s:%d pkcs11_try_pkey_rsa_sign() " - "sig=%p *siglen=%lu tbs=%p tbslen=%lu\n", - __FILE__, __LINE__, sig, *siglen, tbs, tbslen); -#endif - if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0) + + if (pkcs11_get_session(slot, 0, &session)) return -1; - if (tbslen != (size_t)EVP_MD_size(sig_md)) + + /* retrieve PSS parameters */ + if (EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding) <= 0) return -1; - memset(&mechanism, 0, sizeof mechanism); - EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding); - switch (padding) { - case RSA_PKCS1_PSS_PADDING: - pkcs11_log(ctx, LOG_DEBUG, "padding=RSA_PKCS1_PSS_PADDING\n"); - if (pkcs11_params_pss(&pss_params, evp_pkey_ctx, ctx) < 0) - return -1; - mechanism.mechanism = CKM_RSA_PKCS_PSS; - mechanism.pParameter = &pss_params; - mechanism.ulParameterLen = sizeof pss_params; - break; - default: + if (padding != RSA_PKCS1_PSS_PADDING) + return -1; /* unsupported */ + + if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &md) <= 0) return -1; - } /* end switch(padding) */ - if (pkcs11_get_session(slot, 0, &session)) + if (tbslen != (size_t)EVP_MD_size(md)) return -1; - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_SignInit rv=%d\n", - __FILE__, __LINE__, rv); - } else if (key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (rv == CKR_OK) { - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE_PTR)tbs, (CK_ULONG)tbslen, sig, &size)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_Sign rv=%d\n", - __FILE__, __LINE__, rv); - } - } - pkcs11_put_session(slot, session); + if (EVP_PKEY_CTX_get_rsa_mgf1_md(evp_pkey_ctx, &mgf1_md) <= 0) + return -1; - if (rv != CKR_OK) + if (EVP_PKEY_CTX_get_rsa_pss_saltlen(evp_pkey_ctx, &salt_len) == 0) return -1; - *siglen = size; - return 1; + + mdname = EVP_MD_name(md); + mgf1_mdname = EVP_MD_name(mgf1_md); + + return pkcs11_evp_pkey_rsa_sign(key, pkey, mdname, padding, + salt_len, mgf1_mdname, NULL, 0, + sig, siglen, tbs, tbslen); } /* Attempt to decrypt using the PKCS#11-backed RSA implementation */ @@ -1359,25 +1268,28 @@ static int pkcs11_try_pkey_rsa_decrypt(EVP_PKEY_CTX *evp_pkey_ctx, { EVP_PKEY *pkey; RSA *rsa; - int rv = 0, padding; - CK_ULONG size = (CK_ULONG)*outlen; + int padding; + CK_ULONG outsize = (CK_ULONG)*outlen; PKCS11_OBJECT_private *key; PKCS11_SLOT_private *slot; - PKCS11_CTX_private *ctx; CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; + const EVP_MD *md, *mgf1_md; + const char *mdname, *mgf1_mdname; + unsigned char *oaep_label = NULL; + int oaep_labellen; /* RSA method has EVP_PKEY_FLAG_AUTOARGLEN set. OpenSSL core will handle * the size inquiry internally. */ if (!out) return -1; + if (!evp_pkey_ctx) return -1; pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx); if (!pkey) return -1; + rsa = (RSA *)EVP_PKEY_get0_RSA(pkey); if (!rsa) return -1; @@ -1386,62 +1298,38 @@ static int pkcs11_try_pkey_rsa_decrypt(EVP_PKEY_CTX *evp_pkey_ctx, if (check_object_fork(key) < 0) return -1; - slot = key->slot; - ctx = slot->ctx; - if (!ctx) + /* check RSA padding */ + if (EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding) <= 0) return -1; -#ifdef DEBUG - pkcs11_log(ctx, LOG_DEBUG, "%s:%d pkcs11_try_pkey_rsa_decrypt() " - "out=%p *outlen=%lu in=%p inlen=%lu\n", - __FILE__, __LINE__, out, *outlen, in, inlen); -#endif - memset(&mechanism, 0, sizeof mechanism); - EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding); - switch (padding) { - case RSA_PKCS1_OAEP_PADDING: - pkcs11_log(ctx, LOG_DEBUG, "padding=RSA_PKCS1_OAEP_PADDING\n"); - if (pkcs11_params_oaep(&oaep_params, evp_pkey_ctx, ctx) < 0) - return -1; - mechanism.mechanism = CKM_RSA_PKCS_OAEP; - mechanism.pParameter = &oaep_params; - mechanism.ulParameterLen = sizeof oaep_params; - break; - case RSA_PKCS1_PADDING: - pkcs11_log(ctx, LOG_DEBUG, "padding=RSA_PKCS1_PADDING\n"); - mechanism.mechanism = CKM_RSA_PKCS; - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - break; - default: - pkcs11_log(ctx, LOG_DEBUG, "%s:%d unsupported padding: %d\n", - __FILE__, __LINE__, padding); + + if (padding != RSA_PKCS1_OAEP_PADDING) + return -1; /* unsupported */ + + /* retrieve OAEP parameters */ + if (EVP_PKEY_CTX_get_rsa_oaep_md(evp_pkey_ctx, &md) <= 0) return -1; - } /* end switch(padding) */ - if (pkcs11_get_session(slot, 0, &session)) + if (EVP_PKEY_CTX_get_rsa_mgf1_md(evp_pkey_ctx, &mgf1_md) <= 0) return -1; - rv = CRYPTOKI_call(ctx, - C_DecryptInit(session, &mechanism, key->object)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_DecryptInit rv=%d\n", - __FILE__, __LINE__, rv); - } else if (key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (rv == CKR_OK) { - rv = CRYPTOKI_call(ctx, - C_Decrypt(session, (CK_BYTE_PTR)in, (CK_ULONG)inlen, out, &size)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_Decrypt rv=%d\n", - __FILE__, __LINE__, rv); - } + oaep_labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(evp_pkey_ctx, &oaep_label); + if (oaep_labellen < 0) { + oaep_labellen = 0; + oaep_label = NULL; } - pkcs11_put_session(slot, session); - if (rv != CKR_OK) + slot = key->slot; + if (!slot) return -1; - *outlen = size; - return 1; + + if (pkcs11_get_session(slot, 0, &session)) + return -1; + + mdname = EVP_MD_name(md); + mgf1_mdname = EVP_MD_name(mgf1_md); + + return pkcs11_evp_pkey_rsa_decrypt(key, pkey, mdname, padding, mgf1_mdname, + oaep_label, oaep_labellen, out, outlen, &outsize, in, inlen); } static int pkcs11_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx, diff --git a/src/p11_pkey.c b/src/p11_pkey.c index c285e13c..077f3b9f 100644 --- a/src/p11_pkey.c +++ b/src/p11_pkey.c @@ -233,7 +233,7 @@ static int pkcs11_oaep_param(CK_RSA_PKCS_OAEP_PARAMS *oaep_params, } /* Setup PKCS#11 mechanisms for signing */ -static int pkcs11_mechanism(CK_MECHANISM *mechanism, +static int pkcs11_set_rsa_mechanism(CK_MECHANISM *mechanism, CK_RSA_PKCS_PSS_PARAMS *pss_params, CK_RSA_PKCS_OAEP_PARAMS *oaep_params, PKCS11_CTX_private *pctx, EVP_PKEY *pkey, @@ -251,15 +251,12 @@ static int pkcs11_mechanism(CK_MECHANISM *mechanism, switch (padding) { case RSA_PKCS1_PADDING: mechanism->mechanism = CKM_RSA_PKCS; - pkcs11_log(pctx, LOG_DEBUG, "padding=RSA_PKCS1_PADDING\n"); break; case RSA_NO_PADDING: mechanism->mechanism = CKM_RSA_X_509; - pkcs11_log(pctx, LOG_DEBUG, "padding=RSA_NO_PADDING\n"); break; case RSA_X931_PADDING: mechanism->mechanism = CKM_RSA_X9_31; - pkcs11_log(pctx, LOG_DEBUG, "padding=RSA_X931_PADDING\n"); break; case RSA_PKCS1_PSS_PADDING: if (pkcs11_params_pss(pss_params, pkey, salt_len, mdname, @@ -268,7 +265,6 @@ static int pkcs11_mechanism(CK_MECHANISM *mechanism, mechanism->mechanism = CKM_RSA_PKCS_PSS; mechanism->pParameter = pss_params; mechanism->ulParameterLen = sizeof(CK_RSA_PKCS_PSS_PARAMS); - pkcs11_log(pctx, LOG_DEBUG, "padding=RSA_PKCS1_PSS_PADDING\n"); break; case RSA_PKCS1_OAEP_PADDING: if (pkcs11_oaep_param(oaep_params, mdname, mgf1_mdname, @@ -277,7 +273,6 @@ static int pkcs11_mechanism(CK_MECHANISM *mechanism, mechanism->mechanism = CKM_RSA_PKCS_OAEP; mechanism->pParameter = oaep_params; mechanism->ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS); - pkcs11_log(pctx, LOG_DEBUG, "padding=RSA_PKCS1_OAEP_PADDING\n"); break; default: pkcs11_log(pctx, LOG_DEBUG, "%s:%d unsupported padding: %d\n", @@ -287,6 +282,30 @@ static int pkcs11_mechanism(CK_MECHANISM *mechanism, return 0; } +const char *pkcs11_mechanism_name(CK_MECHANISM *mechanism) +{ + switch (mechanism->mechanism) { + case CKM_RSA_PKCS: + return "CKM_RSA_PKCS"; + case CKM_RSA_PKCS_PSS: + return "CKM_RSA_PKCS_PSS"; + case CKM_RSA_PKCS_OAEP: + return "CKM_RSA_PKCS_OAEP"; + case CKM_RSA_X_509: + return "CKM_RSA_X_509"; + case CKM_RSA_X9_31: + return "CKM_RSA_X9_31"; + case CKM_ECDSA: + return "CKM_ECDSA"; +#ifdef CKM_EDDSA + case CKM_EDDSA: + return "CKM_EDDSA"; +#endif + default: + return "UNKNOWN_MECHANISM"; + } +} + /* * Execute a PKCS#11 signing operation using the specified mechanism. * @@ -321,8 +340,9 @@ static int pkcs11_sign_with_mechanism(PKCS11_OBJECT_private *key, #ifdef DEBUG pkcs11_log(ctx, LOG_DEBUG, "%s:%d pkcs11_sign_with_mechanism() " - "sig=%p *siglen=%lu tbs=%p tbslen=%lu\n", - __FILE__, __LINE__, sig, *siglen, tbs, tbslen); + "%s sig=%p *siglen=%lu tbs=%p tbslen=%lu\n", + __FILE__, __LINE__, + pkcs11_mechanism_name(mechanism), sig, *siglen, tbs, tbslen); #endif ck_siglen = (CK_ULONG)*siglen; @@ -385,7 +405,7 @@ static int pkcs11_sign_with_mechanism(PKCS11_OBJECT_private *key, * * For RSA_NO_PADDING, the input is passed to the token unchanged. * - * Returns the signature length on success or -1 on failure. + * Returns 1 on success or -1 on failure. */ int pkcs11_evp_pkey_rsa_sign(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, const char *mdname, const int pad_mode, const int salt_len, @@ -397,7 +417,9 @@ int pkcs11_evp_pkey_rsa_sign(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, PKCS11_SLOT_private *slot; PKCS11_CTX_private *ctx; CK_RSA_PKCS_PSS_PARAMS pss_params; - int rv; + + if (key == NULL || sig == NULL || siglen == NULL || tbs == NULL) + return -1; slot = key->slot; if (slot == NULL) @@ -407,87 +429,126 @@ int pkcs11_evp_pkey_rsa_sign(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, if (ctx == NULL) return -1; - if (pkcs11_mechanism(&mechanism, &pss_params, NULL, + if (pkcs11_set_rsa_mechanism(&mechanism, &pss_params, NULL, ctx, pkey, pad_mode, salt_len, mdname, mgf1_mdname, oaep_label, oaep_labellen) < 0) return -1; - rv = pkcs11_sign_with_mechanism(key, &mechanism, sig, siglen, - tbs, tbslen); - - if (rv != CKR_OK) + if (pkcs11_sign_with_mechanism(key, &mechanism, sig, siglen, + tbs, tbslen) != CKR_OK) return -1; - return (int)*siglen; + return 1; } #ifndef OPENSSL_NO_EC -/* Sign digest input with EC private key via PKCS#11 and encode signature as DER */ -int pkcs11_evp_pkey_ec_sign(PKCS11_OBJECT_private *key, +/* + * Sign data via PKCS#11 (CKM_ECDSA) and convert raw r||s output + * into an OpenSSL ECDSA_SIG structure. Returns NULL on failure. + */ +ECDSA_SIG *pkcs11_ec_sign_raw(PKCS11_OBJECT_private *key, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { - ECDSA_SIG *ossl_sig = NULL; CK_MECHANISM mechanism; - size_t raw_siglen; - int rv = -1; + ECDSA_SIG *ecdsa = NULL; + BIGNUM *r = NULL, *s = NULL; + size_t tmp_len; - ossl_sig = ECDSA_SIG_new(); - if (ossl_sig == NULL) - return -1; + if (key == NULL || sig == NULL || siglen == NULL || tbs == NULL) + return NULL; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_ECDSA; - raw_siglen = *siglen; - rv = pkcs11_sign_with_mechanism(key, &mechanism, sig, &raw_siglen, tbs, tbslen); - if (rv == CKR_OK) { - BIGNUM *r = BN_bin2bn(sig, raw_siglen / 2, NULL); - BIGNUM *s = BN_bin2bn(sig + raw_siglen / 2, raw_siglen / 2, NULL); + if (pkcs11_sign_with_mechanism(key, &mechanism, sig, siglen, + tbs, tbslen) != CKR_OK) + return NULL; - if (r == NULL || s == NULL) - goto error; + tmp_len = *siglen; + if (tmp_len == 0 || tmp_len % 2 != 0) + return NULL; - if (ECDSA_SIG_set0(ossl_sig, r, s) != 1) { - BN_free(r); - BN_free(s); - goto error; - } - *siglen = i2d_ECDSA_SIG(ossl_sig, &sig); - rv = (*siglen > 0) ? CKR_OK : CKR_GENERAL_ERROR; - } + r = BN_bin2bn(sig, tmp_len / 2, NULL); + s = BN_bin2bn(sig + tmp_len / 2, tmp_len / 2, NULL); + if (r == NULL || s == NULL) + goto error; + + ecdsa = ECDSA_SIG_new(); + if (ecdsa == NULL) + goto error; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL) + if (ECDSA_SIG_set0(ecdsa, r, s) != 1) + goto error; +#else + BN_free(ecdsa->r); + ecdsa->r = r; + BN_free(ecdsa->s); + ecdsa->s = s; +#endif + /* Ownership of r and s has been transferred to ecdsa */ + r = NULL; + s = NULL; + return ecdsa; error: - ECDSA_SIG_free(ossl_sig); + BN_free(r); + BN_free(s); + ECDSA_SIG_free(ecdsa); + return NULL; +} - if (rv != CKR_OK) +/* + * Sign digest input with EC private key via PKCS#11 and encode signature as DER. + * Returns 1 on success or -1 on failure. + */ +int pkcs11_evp_pkey_ec_sign(PKCS11_OBJECT_private *key, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + ECDSA_SIG *ecdsa; + + if (key == NULL || sig == NULL || siglen == NULL || tbs == NULL) return -1; - return 1; + ecdsa = pkcs11_ec_sign_raw(key, sig, siglen, tbs, tbslen); + if (!ecdsa) + return -1; + + *siglen = i2d_ECDSA_SIG(ecdsa, &sig); + ECDSA_SIG_free(ecdsa); + return (*siglen > 0) ? 1 : -1; } #endif /* OPENSSL_NO_EC */ -/* Sign message input with EdDSA private key via PKCS#11 mechanism */ +/* + * Sign message input with EdDSA private key via PKCS#11 mechanism. + * Returns 1 on success or -1 on failure. + */ int pkcs11_evp_pkey_eddsa_sign(PKCS11_OBJECT_private *key, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { CK_MECHANISM mechanism; - int rv; + + if (key == NULL || sig == NULL || siglen == NULL || tbs == NULL) + return -1; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_EDDSA; - rv = pkcs11_sign_with_mechanism(key, &mechanism, sig, siglen, tbs, tbslen); - if (rv != CKR_OK) + if (pkcs11_sign_with_mechanism(key, &mechanism, sig, siglen, + tbs, tbslen) != CKR_OK) return -1; - return (int)*siglen; + return 1; } /* * Decrypt RSA input via PKCS#11 using configured padding and OAEP parameters. - * EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty encoding parameter (OAEP label) + * EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an encoding parameter + * (OAEP label). */ int pkcs11_evp_pkey_rsa_decrypt(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, const char *mdname, const int pad_mode, @@ -518,7 +579,7 @@ int pkcs11_evp_pkey_rsa_decrypt(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, if (oaep_labellen > 0) pkcs11_log(ctx, LOG_WARNING, "OAEP label may not be supported by PKCS#11 token\n"); - if (pkcs11_mechanism(&mechanism, NULL, &oaep_params, + if (pkcs11_set_rsa_mechanism(&mechanism, NULL, &oaep_params, ctx, pkey, pad_mode, 0, mdname, mgf1_mdname, oaep_label, oaep_labellen) < 0) return -1; @@ -535,7 +596,10 @@ int pkcs11_evp_pkey_rsa_decrypt(PKCS11_OBJECT_private *key, EVP_PKEY *pkey, return -1; rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, key->object)); - if (rv == CKR_OK && key->always_authenticate == CK_TRUE) + if (rv != CKR_OK) + pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_DecryptInit rv=%d\n", + __FILE__, __LINE__, rv); + else if (rv == CKR_OK && key->always_authenticate == CK_TRUE) rv = pkcs11_authenticate(key, session); if (rv == CKR_OK) @@ -564,149 +628,67 @@ static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx, { EVP_PKEY *pkey; EC_KEY *eckey; - int rv = CKR_GENERAL_ERROR; - CK_ULONG size = (CK_ULONG)*siglen; PKCS11_OBJECT_private *key; PKCS11_SLOT_private *slot; - PKCS11_CTX_private *ctx; CK_SESSION_HANDLE session; const EVP_MD *sig_md; - ECDSA_SIG *ossl_sig; - CK_MECHANISM mechanism; - ossl_sig = ECDSA_SIG_new(); - if (!ossl_sig) - goto error; if (!evp_pkey_ctx) - goto error; + return -1; + + if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0) + return -1; + + if (tbslen < (size_t)EVP_MD_size(sig_md)) + return -1; pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx); if (!pkey) - goto error; + return -1; eckey = (EC_KEY *)EVP_PKEY_get0_EC_KEY(pkey); if (!eckey) - goto error; + return -1; if (!sig) { *siglen = (size_t)ECDSA_size(eckey); - rv = CKR_OK; - goto error; + return 1; /* length query */ } if (*siglen < (size_t)ECDSA_size(eckey)) - goto error; + return -1; /* buffer too small */ key = pkcs11_get_ex_data_ec(eckey); if (check_object_fork(key) < 0) - goto error; + return -1; slot = key->slot; - ctx = slot->ctx; - if (!ctx) - goto error; -#ifdef DEBUG - pkcs11_log(ctx, LOG_DEBUG, "%s:%d pkcs11_try_pkey_ec_sign() " - "sig=%p *siglen=%lu tbs=%p tbslen=%lu\n", - __FILE__, __LINE__, sig, *siglen, tbs, tbslen); -#endif - if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0) - goto error; - - if (tbslen < (size_t)EVP_MD_size(sig_md)) - goto error; - - rv = 0; - memset(&mechanism, 0, sizeof mechanism); - mechanism.mechanism = CKM_ECDSA; - - if (pkcs11_get_session(slot, 0, &session)) + if (!slot) return -1; - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_SignInit rv=%d\n", - __FILE__, __LINE__, rv); - } else if (key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (rv == CKR_OK) { - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE_PTR)tbs, (CK_ULONG)tbslen, sig, &size)); - if (rv != CKR_OK) { - pkcs11_log(ctx, LOG_DEBUG, "%s:%d C_Sign rv=%d\n", - __FILE__, __LINE__, rv); - } - } - pkcs11_put_session(slot, session); - - if (rv == CKR_OK) { - BIGNUM *r = BN_bin2bn(sig, size/2, NULL); - BIGNUM *s = BN_bin2bn(sig + size/2, size/2, NULL); - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL ) - ECDSA_SIG_set0(ossl_sig, r, s); -#else - BN_free(ossl_sig->r); - ossl_sig->r = r; - BN_free(ossl_sig->s); - ossl_sig->s = s; -#endif - *siglen = i2d_ECDSA_SIG(ossl_sig, &sig); - } - -error: - ECDSA_SIG_free(ossl_sig); - if (rv != CKR_OK) + if (pkcs11_get_session(slot, 0, &session)) return -1; - return 1; + return pkcs11_evp_pkey_ec_sign(key, sig, siglen, tbs, tbslen); } #endif /* OPENSSL_NO_EC */ #if !defined(OPENSSL_NO_ECX) && OPENSSL_VERSION_NUMBER >= 0x30000000L /* PKCS#11 sign implementation for Ed25519 / Ed448 */ -static int pkcs11_eddsa_sign(unsigned char *sigret, unsigned int *siglen, - const unsigned char *tbs, unsigned int tbslen, PKCS11_OBJECT_private *key) +static int pkcs11_eddsa_sign(unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen, PKCS11_OBJECT_private *key) { - int rv; - PKCS11_SLOT_private *slot = key->slot; - PKCS11_CTX_private *ctx = slot->ctx; + PKCS11_SLOT_private *slot; CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ULONG ck_siglen = (CK_ULONG)(*siglen); - CK_ULONG ck_tbslen = (CK_ULONG)tbslen; - if (!ctx) + slot = key->slot; + if (!slot) return -1; - /* PureEdDSA, no prehash */ - memset(&mechanism, 0, sizeof(mechanism)); - mechanism.mechanism = CKM_EDDSA; - -#ifdef DEBUG - pkcs11_log(ctx, LOG_DEBUG, "%s:%d pkcs11_eddsa_sign() " - "sigret=%p *siglen=%u tbs=%p tbslen=%u\n", - __FILE__, __LINE__, sigret, *siglen, tbs, tbslen); -#endif if (pkcs11_get_session(slot, 0, &session)) return -1; - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE_PTR)tbs, ck_tbslen, sigret, &ck_siglen)); - pkcs11_put_session(slot, session); - - if (rv) { - CKRerr(CKR_F_PKCS11_EDDSA_SIGN, rv); - return -1; - } - *siglen = (unsigned int)ck_siglen; - return (int)ck_siglen; + return pkcs11_evp_pkey_eddsa_sign(key, sig, siglen, tbs, tbslen); } /* @@ -720,7 +702,6 @@ static int pkcs11_eddsa_pmeth_sign(EVP_PKEY_CTX *evp_pkey_ctx, { EVP_PKEY *pkey; PKCS11_OBJECT_private *key; - unsigned int tmp_len; int rv; if (!evp_pkey_ctx) @@ -740,12 +721,10 @@ static int pkcs11_eddsa_pmeth_sign(EVP_PKEY_CTX *evp_pkey_ctx, if (check_object_fork(key) < 0) return -1; - tmp_len = (unsigned int)*siglen; - rv = pkcs11_eddsa_sign(sig, &tmp_len, tbs, (unsigned int)tbslen, key); + rv = pkcs11_eddsa_sign(sig, siglen, tbs, tbslen, key); if (rv < 0) return -1; - *siglen = tmp_len; return 1; } @@ -764,7 +743,6 @@ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, { EVP_PKEY *pkey; PKCS11_OBJECT_private *key; - unsigned int tmp_len; int rv; pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); @@ -789,12 +767,10 @@ static int pkcs11_eddsa_pmeth_digestsign(EVP_MD_CTX *ctx, unsigned char *sig, } /* Step 2: actual signing */ - tmp_len = (unsigned int)*siglen; - rv = pkcs11_eddsa_sign(sig, &tmp_len, tbs, (unsigned int)tbslen, key); + rv = pkcs11_eddsa_sign(sig, siglen, tbs, tbslen, key); if (rv < 0) return 1; - *siglen = tmp_len; return 1; } diff --git a/src/p11_rsa.c b/src/p11_rsa.c index af32e81b..72f7b06a 100644 --- a/src/p11_rsa.c +++ b/src/p11_rsa.c @@ -63,137 +63,72 @@ int pkcs11_sign(int type, const unsigned char *m, unsigned int m_len, return ret; } -/* Setup PKCS#11 mechanisms for encryption/decryption */ -static int pkcs11_mechanism(CK_MECHANISM *mechanism, const int padding) -{ - memset(mechanism, 0, sizeof(CK_MECHANISM)); - switch (padding) { - case RSA_PKCS1_PADDING: - mechanism->mechanism = CKM_RSA_PKCS; - break; - case RSA_PKCS1_OAEP_PADDING: - mechanism->mechanism = CKM_RSA_PKCS_OAEP; - break; - case RSA_NO_PADDING: - mechanism->mechanism = CKM_RSA_X_509; - break; - case RSA_X931_PADDING: - mechanism->mechanism = CKM_RSA_X9_31; - break; - default: - P11err(P11_F_PKCS11_MECHANISM, P11_R_UNSUPPORTED_PADDING_TYPE); - return -1; - } - return 0; -} - -static void -pkcs11_oaep_param(CK_MECHANISM *mechanism, CK_RSA_PKCS_OAEP_PARAMS *oaep_params) -{ - /* Openssl API for RSA_private_decrypt() allows to use - * RSA_PKCS1_OAEP_PADDING nly with SHA_1 hash and and MGF1_SHA1 mask - * gen function. It is not possible to use RFC8017 "Label" or - * PKCS#11 "source data" respectively. - * https://www.openssl.org/docs/man3.0/man3/RSA_private_decrypt.html */ - - mechanism->pParameter = oaep_params; - mechanism->ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS); - oaep_params->mgf = CKG_MGF1_SHA1; - oaep_params->hashAlg = CKM_SHA_1; - oaep_params->source = 0; - oaep_params->pSourceData = NULL; - oaep_params->ulSourceDataLen = 0; -} -/* RSA private key encryption (also invoked by OpenSSL for signing) */ -/* OpenSSL assumes that the output buffer is always big enough */ +/* + * RSA private key encryption (also invoked by OpenSSL for signing) + * OpenSSL assumes that the output buffer is always big enough + */ int pkcs11_private_encrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_OBJECT_private *key, int padding) { - PKCS11_SLOT_private *slot = key->slot; - PKCS11_CTX_private *ctx = slot->ctx; - CK_MECHANISM mechanism; - CK_ULONG size; + PKCS11_SLOT_private *slot; + size_t siglen; CK_SESSION_HANDLE session; - int rv; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; - size = pkcs11_get_key_size(key); - - if (pkcs11_mechanism(&mechanism, padding) < 0) + if (!key) return -1; - if (mechanism.mechanism == CKM_RSA_PKCS_OAEP) - pkcs11_oaep_param(&mechanism, &oaep_params); + slot = key->slot; + if (!slot) + return -1; if (pkcs11_get_session(slot, 0, &session)) return -1; - /* Try signing first, as applications are more likely to use it */ - rv = CRYPTOKI_call(ctx, - C_SignInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Sign(session, (CK_BYTE *)from, flen, to, &size)); - if (rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { - /* OpenSSL may use it for encryption rather than signing */ - rv = CRYPTOKI_call(ctx, - C_EncryptInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Encrypt(session, (CK_BYTE *)from, flen, to, &size)); - } - pkcs11_put_session(slot, session); - - if (rv) { - CKRerr(CKR_F_PKCS11_PRIVATE_ENCRYPT, rv); + siglen = pkcs11_get_key_size(key); + if (!pkcs11_evp_pkey_rsa_sign(key, NULL, NULL, padding, + 0, NULL, /* unsupported PSS parameters */ + NULL, 0, /* unsupported oaep_label */ + to, &siglen, from, flen)) return -1; - } - return size; + return (int)siglen; } /* RSA private key decryption */ -int pkcs11_private_decrypt(int flen, const unsigned char *from, unsigned char *to, +int pkcs11_private_decrypt(int flen, + const unsigned char *from, unsigned char *to, PKCS11_OBJECT_private *key, int padding) { - PKCS11_SLOT_private *slot = key->slot; - PKCS11_CTX_private *ctx = slot->ctx; + PKCS11_SLOT_private *slot; + size_t outlen; CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ULONG size = flen; - CK_RV rv; - CK_RSA_PKCS_OAEP_PARAMS oaep_params; - if (pkcs11_mechanism(&mechanism, padding) < 0) + if (padding != RSA_PKCS1_OAEP_PADDING) + return -1; /* unsupported */ + + if (!key) return -1; - if (mechanism.mechanism == CKM_RSA_PKCS_OAEP) - pkcs11_oaep_param(&mechanism, &oaep_params); + slot = key->slot; + if (!slot) + return -1; if (pkcs11_get_session(slot, 0, &session)) return -1; - rv = CRYPTOKI_call(ctx, - C_DecryptInit(session, &mechanism, key->object)); - if (!rv && key->always_authenticate == CK_TRUE) - rv = pkcs11_authenticate(key, session); - if (!rv) - rv = CRYPTOKI_call(ctx, - C_Decrypt(session, (CK_BYTE *)from, size, - (CK_BYTE_PTR)to, &size)); - pkcs11_put_session(slot, session); - - if (rv) { - CKRerr(CKR_F_PKCS11_PRIVATE_DECRYPT, rv); + /* Openssl API for RSA_private_decrypt() allows to use + * RSA_PKCS1_OAEP_PADDING only with SHA_1 hash and and MGF1_SHA1 mask + * gen function. It is not possible to use RFC8017 "Label" or + * PKCS#11 "source data" respectively. + * https://www.openssl.org/docs/man3.0/man3/RSA_private_decrypt.html */ + outlen = flen; + if (!pkcs11_evp_pkey_rsa_decrypt(key, NULL, "SHA1", padding, "SHA1", + NULL, 0, /* unsupported oaep_label */ + to, &outlen, 0, from, flen)) return -1; - } - return size; + return (int)outlen; } /* TODO: remove this function in libp11 0.5.0 */