Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/libp11-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
68 changes: 4 additions & 64 deletions src/p11_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand All @@ -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 */
Expand Down
77 changes: 26 additions & 51 deletions src/p11_eddsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -126,16 +94,19 @@ 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,
size_t *siglen, const unsigned char *tbs, size_t tbslen)
{
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)
Expand All @@ -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)
Expand All @@ -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;
}

Expand Down
Loading
Loading