Blame SOURCES/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch

2c1758
commit 50e3f06823696c74eea90a77e16b28da1f79cd47
2c1758
Author: Ingo Franzki <ifranzki@linux.ibm.com>
2c1758
Date:   Wed Jun 30 14:33:33 2021 +0200
2c1758
2c1758
    SOFT: Remove deprecated OpenSSL functions
2c1758
    
2c1758
    All low level RSA, EC_KEY, and DH functions are deprecated in OpenSSL 3.0.
2c1758
    Update the code to not use any of those.
2c1758
    
2c1758
    Change the digest operation context to store the OpenSSL digest context,
2c1758
    instead of the deprecated way of retrieving and restoring the digest state.
2c1758
    This makes the digest operation context 'non savable'.
2c1758
    
2c1758
    Also remove support for OpenSSL < v1.1.1. This code used even more
2c1758
    low level OpenSSL functions.
2c1758
    
2c1758
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2c1758
2c1758
diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c
2c1758
index 5ca22693..43fd17c3 100644
2c1758
--- a/usr/lib/soft_stdll/soft_specific.c
2c1758
+++ b/usr/lib/soft_stdll/soft_specific.c
2c1758
@@ -26,10 +26,6 @@
2c1758
 
2c1758
 #include <openssl/opensslv.h>
2c1758
 
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-#define NO_EC 1
2c1758
-#endif
2c1758
-
2c1758
 #include "pkcs11types.h"
2c1758
 #include "defs.h"
2c1758
 #include "host_defs.h"
2c1758
@@ -54,14 +50,10 @@
2c1758
 #include <openssl/crypto.h>
2c1758
 #include <openssl/cmac.h>
2c1758
 #include <openssl/ec.h>
2c1758
-
2c1758
-/*
2c1758
- * In order to make opencryptoki compatible with
2c1758
- * OpenSSL 1.1 API Changes and backward compatible
2c1758
- * we need to check for its version
2c1758
- */
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-#define OLDER_OPENSSL
2c1758
+#include <openssl/bn.h>
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+#include <openssl/core_names.h>
2c1758
+#include <openssl/param_build.h>
2c1758
 #endif
2c1758
 
2c1758
 #define MAX_GENERIC_KEY_SIZE 256
2c1758
@@ -76,7 +68,10 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = {
2c1758
 #if !(NODSA)
2c1758
     {CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}},
2c1758
 #endif
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    /* OpenSSL 3.0 supports single-DES only with the legacy provider */
2c1758
     {CKM_DES_KEY_GEN, {8, 8, CKF_GENERATE}},
2c1758
+#endif
2c1758
     {CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}},
2c1758
 #if !(NOCDMF)
2c1758
     {CKM_CDMF_KEY_GEN, {0, 0, CKF_GENERATE}},
2c1758
@@ -120,10 +115,13 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = {
2c1758
     {CKM_DH_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR}},
2c1758
 #endif
2c1758
 /* End code contributed by Corrent corp. */
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    /* OpenSSL 3.0 supports single-DES only with the legacy provider */
2c1758
     {CKM_DES_ECB, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
2c1758
     {CKM_DES_CBC, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
2c1758
     {CKM_DES_CBC_PAD,
2c1758
      {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
2c1758
+#endif
2c1758
 #if !(NOCDMF)
2c1758
     {CKM_CDMF_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
2c1758
     {CKM_CDMF_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
2c1758
@@ -286,58 +284,6 @@ CK_RV token_specific_des_ecb(STDLL_TokData_t *tokdata,
2c1758
                              CK_ULONG *out_data_len,
2c1758
                              OBJECT *key, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    CK_RV rc;
2c1758
-    DES_key_schedule des_key2;
2c1758
-    const_DES_cblock key_val_SSL, in_key_data;
2c1758
-    DES_cblock out_key_data;
2c1758
-    unsigned int i, j;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    // get the key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // Create the key schedule
2c1758
-    memcpy(&key_val_SSL, attr->pValue, 8);
2c1758
-    DES_set_key_unchecked(&key_val_SSL, &des_key2);
2c1758
-
2c1758
-    // the des decrypt will only fail if the data length is not evenly divisible
2c1758
-    // by 8
2c1758
-    if (in_data_len % DES_BLOCK_SIZE) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2c1758
-        return CKR_DATA_LEN_RANGE;
2c1758
-    }
2c1758
-    // Both the encrypt and the decrypt are done 8 bytes at a time
2c1758
-    if (encrypt) {
2c1758
-        for (i = 0; i < in_data_len; i = i + 8) {
2c1758
-            memcpy(in_key_data, in_data + i, 8);
2c1758
-            DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
2c1758
-                            DES_ENCRYPT);
2c1758
-            memcpy(out_data + i, out_key_data, 8);
2c1758
-        }
2c1758
-
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    } else {
2c1758
-
2c1758
-        for (j = 0; j < in_data_len; j = j + 8) {
2c1758
-            memcpy(in_key_data, in_data + j, 8);
2c1758
-            DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
2c1758
-                            DES_DECRYPT);
2c1758
-            memcpy(out_data + j, out_key_data, 8);
2c1758
-        }
2c1758
-
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    }
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     const EVP_CIPHER *cipher = EVP_des_ecb();
2c1758
     EVP_CIPHER_CTX *ctx = NULL;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
@@ -384,7 +330,6 @@ done:
2c1758
     OPENSSL_cleanse(dkey, sizeof(dkey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata,
2c1758
@@ -394,47 +339,6 @@ CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata,
2c1758
                              CK_ULONG *out_data_len,
2c1758
                              OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    CK_RV rc;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    DES_cblock ivec;
2c1758
-    DES_key_schedule des_key2;
2c1758
-    const_DES_cblock key_val_SSL;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    // get the key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // Create the key schedule
2c1758
-    memcpy(&key_val_SSL, attr->pValue, 8);
2c1758
-    DES_set_key_unchecked(&key_val_SSL, &des_key2);
2c1758
-
2c1758
-    memcpy(&ivec, init_v, 8);
2c1758
-    // the des decrypt will only fail if the data length is not evenly divisible
2c1758
-    // by 8
2c1758
-    if (in_data_len % DES_BLOCK_SIZE) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2c1758
-        return CKR_DATA_LEN_RANGE;
2c1758
-    }
2c1758
-
2c1758
-    if (encrypt) {
2c1758
-        DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
2c1758
-                         DES_ENCRYPT);
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    } else {
2c1758
-        DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
2c1758
-                         DES_DECRYPT);
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    }
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     const EVP_CIPHER *cipher = EVP_des_cbc();
2c1758
     EVP_CIPHER_CTX *ctx = NULL;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
@@ -481,7 +385,6 @@ done:
2c1758
     OPENSSL_cleanse(dkey, sizeof(dkey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata,
2c1758
@@ -491,80 +394,6 @@ CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata,
2c1758
                               CK_ULONG *out_data_len,
2c1758
                               OBJECT *key, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    CK_RV rc;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    CK_BYTE key_value[3 * DES_KEY_SIZE];
2c1758
-    CK_KEY_TYPE keytype;
2c1758
-    unsigned int k, j;
2c1758
-    DES_key_schedule des_key1;
2c1758
-    DES_key_schedule des_key2;
2c1758
-    DES_key_schedule des_key3;
2c1758
-    const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data;
2c1758
-    DES_cblock out_key_data;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    // get the key type
2c1758
-    rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    // get the key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    if (keytype == CKK_DES2) {
2c1758
-        memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
2c1758
-        memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
2c1758
-    } else {
2c1758
-        memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
2c1758
-    }
2c1758
-
2c1758
-    // The key as passed is a 24 byte long string containing three des keys
2c1758
-    // pick them apart and create the 3 corresponding key schedules
2c1758
-    memcpy(&key_SSL1, key_value, 8);
2c1758
-    memcpy(&key_SSL2, key_value + 8, 8);
2c1758
-    memcpy(&key_SSL3, key_value + 16, 8);
2c1758
-    DES_set_key_unchecked(&key_SSL1, &des_key1);
2c1758
-    DES_set_key_unchecked(&key_SSL2, &des_key2);
2c1758
-    DES_set_key_unchecked(&key_SSL3, &des_key3);
2c1758
-
2c1758
-    // the des decrypt will only fail if the data length is not evenly divisible
2c1758
-    // by 8
2c1758
-    if (in_data_len % DES_BLOCK_SIZE) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2c1758
-        return CKR_DATA_LEN_RANGE;
2c1758
-    }
2c1758
-    // the encrypt and decrypt are done 8 bytes at a time
2c1758
-    if (encrypt) {
2c1758
-        for (k = 0; k < in_data_len; k = k + 8) {
2c1758
-            memcpy(in_key_data, in_data + k, 8);
2c1758
-            DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
2c1758
-                             (DES_cblock *) & out_key_data,
2c1758
-                             &des_key1, &des_key2, &des_key3, DES_ENCRYPT);
2c1758
-            memcpy(out_data + k, out_key_data, 8);
2c1758
-        }
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    } else {
2c1758
-        for (j = 0; j < in_data_len; j = j + 8) {
2c1758
-            memcpy(in_key_data, in_data + j, 8);
2c1758
-            DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
2c1758
-                             (DES_cblock *) & out_key_data,
2c1758
-                             &des_key1, &des_key2, &des_key3, DES_DECRYPT);
2c1758
-            memcpy(out_data + j, out_key_data, 8);
2c1758
-        }
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    }
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     const EVP_CIPHER *cipher = EVP_des_ede3_ecb();
2c1758
     EVP_CIPHER_CTX *ctx = NULL;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
@@ -624,7 +453,6 @@ done:
2c1758
     OPENSSL_cleanse(dkey, sizeof(dkey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata,
2c1758
@@ -634,78 +462,6 @@ CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata,
2c1758
                               CK_ULONG *out_data_len,
2c1758
                               OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    CK_RV rc = CKR_OK;
2c1758
-    CK_BYTE key_value[3 * DES_KEY_SIZE];
2c1758
-    CK_KEY_TYPE keytype;
2c1758
-    DES_key_schedule des_key1;
2c1758
-    DES_key_schedule des_key2;
2c1758
-    DES_key_schedule des_key3;
2c1758
-    const_DES_cblock key_SSL1, key_SSL2, key_SSL3;
2c1758
-    DES_cblock ivec;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    // get the key type
2c1758
-    rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    // get the key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    if (keytype == CKK_DES2) {
2c1758
-        memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
2c1758
-        memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
2c1758
-    } else {
2c1758
-        memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
2c1758
-    }
2c1758
-
2c1758
-    // The key as passed in is a 24 byte string containing 3 keys
2c1758
-    // pick it apart and create the key schedules
2c1758
-    memcpy(&key_SSL1, key_value, 8);
2c1758
-    memcpy(&key_SSL2, key_value + 8, 8);
2c1758
-    memcpy(&key_SSL3, key_value + 16, 8);
2c1758
-    DES_set_key_unchecked(&key_SSL1, &des_key1);
2c1758
-    DES_set_key_unchecked(&key_SSL2, &des_key2);
2c1758
-    DES_set_key_unchecked(&key_SSL3, &des_key3);
2c1758
-
2c1758
-    memcpy(ivec, init_v, sizeof(ivec));
2c1758
-
2c1758
-    // the des decrypt will only fail if the data length is not evenly divisible
2c1758
-    // by 8
2c1758
-    if (in_data_len % DES_BLOCK_SIZE) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
2c1758
-        return CKR_DATA_LEN_RANGE;
2c1758
-    }
2c1758
-    // Encrypt or decrypt the data
2c1758
-    if (encrypt) {
2c1758
-        DES_ede3_cbc_encrypt(in_data,
2c1758
-                             out_data,
2c1758
-                             in_data_len,
2c1758
-                             &des_key1,
2c1758
-                             &des_key2, &des_key3, &ivec, DES_ENCRYPT);
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    } else {
2c1758
-        DES_ede3_cbc_encrypt(in_data,
2c1758
-                             out_data,
2c1758
-                             in_data_len,
2c1758
-                             &des_key1,
2c1758
-                             &des_key2, &des_key3, &ivec, DES_DECRYPT);
2c1758
-
2c1758
-        *out_data_len = in_data_len;
2c1758
-        rc = CKR_OK;
2c1758
-    }
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
2c1758
     EVP_CIPHER_CTX *ctx = NULL;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
@@ -765,7 +521,6 @@ done:
2c1758
     OPENSSL_cleanse(dkey, sizeof(dkey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
@@ -795,14 +550,20 @@ CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
 // convert from the local PKCS11 template representation to
2c1758
 // the underlying requirement
2c1758
 // returns the pointer to the local key representation
2c1758
-static void *rsa_convert_public_key(OBJECT *key_obj)
2c1758
+static EVP_PKEY *rsa_convert_public_key(OBJECT *key_obj)
2c1758
 {
2c1758
     CK_BBOOL rc;
2c1758
     CK_ATTRIBUTE *modulus = NULL;
2c1758
     CK_ATTRIBUTE *pub_exp = NULL;
2c1758
-
2c1758
-    RSA *rsa;
2c1758
+    EVP_PKEY *pkey = NULL;
2c1758
     BIGNUM *bn_mod, *bn_exp;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    EVP_PKEY_CTX *pctx = NULL;
2c1758
+    OSSL_PARAM_BLD *tmpl = NULL;
2c1758
+    OSSL_PARAM *params = NULL;
2c1758
+#else
2c1758
+    RSA *rsa;
2c1758
+#endif
2c1758
 
2c1758
     rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
2c1758
                                           &modulus);
2c1758
@@ -813,12 +574,7 @@ static void *rsa_convert_public_key(OBJECT *key_obj)
2c1758
     if (rc != CKR_OK)
2c1758
         return NULL;
2c1758
 
2c1758
-    // Create an RSA key struct to return
2c1758
-    rsa = RSA_new();
2c1758
-    if (rsa == NULL)
2c1758
-        return NULL;
2c1758
-
2c1758
-    // Create and init BIGNUM structs to stick in the RSA struct
2c1758
+    // Create and init BIGNUM structs
2c1758
     bn_mod = BN_new();
2c1758
     bn_exp = BN_new();
2c1758
 
2c1758
@@ -827,24 +583,74 @@ static void *rsa_convert_public_key(OBJECT *key_obj)
2c1758
             free(bn_mod);
2c1758
         if (bn_exp)
2c1758
             free(bn_exp);
2c1758
-        RSA_free(rsa);
2c1758
         return NULL;
2c1758
     }
2c1758
-    // Convert from strings to BIGNUMs and stick them in the RSA struct
2c1758
+    // Convert from strings to BIGNUMs
2c1758
     BN_bin2bn((unsigned char *) modulus->pValue, modulus->ulValueLen, bn_mod);
2c1758
     BN_bin2bn((unsigned char *) pub_exp->pValue, pub_exp->ulValueLen, bn_exp);
2c1758
 
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    rsa->n = bn_mod;
2c1758
-    rsa->e = bn_exp;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    // Create an RSA key struct to return
2c1758
+    rsa = RSA_new();
2c1758
+    if (rsa == NULL) {
2c1758
+        if (bn_mod)
2c1758
+             free(bn_mod);
2c1758
+         if (bn_exp)
2c1758
+             free(bn_exp);
2c1758
+        return NULL;
2c1758
+    }
2c1758
+
2c1758
     RSA_set0_key(rsa, bn_mod, bn_exp, NULL);
2c1758
+
2c1758
+    pkey = EVP_PKEY_new();
2c1758
+    if (pkey == NULL) {
2c1758
+       RSA_free(rsa);
2c1758
+       return NULL;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
2c1758
+        RSA_free(rsa);
2c1758
+        EVP_PKEY_free(pkey);
2c1758
+        return NULL;
2c1758
+    }
2c1758
+#else
2c1758
+    tmpl = OSSL_PARAM_BLD_new();
2c1758
+    if (tmpl == NULL)
2c1758
+        goto out;
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
2c1758
+        !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_exp))
2c1758
+        goto out;
2c1758
+
2c1758
+    params = OSSL_PARAM_BLD_to_param(tmpl);
2c1758
+    if (params == NULL)
2c1758
+        goto out;
2c1758
+
2c1758
+    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
2c1758
+    if (pctx == NULL)
2c1758
+        goto out;
2c1758
+
2c1758
+    if (!EVP_PKEY_fromdata_init(pctx) ||
2c1758
+        !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params))
2c1758
+        goto out;
2c1758
+
2c1758
+out:
2c1758
+    if (pctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(pctx);
2c1758
+    if (tmpl != NULL)
2c1758
+        OSSL_PARAM_BLD_free(tmpl);
2c1758
+    if (params != NULL)
2c1758
+        OSSL_PARAM_free(params);
2c1758
+    if (bn_mod != NULL)
2c1758
+        BN_free(bn_mod);
2c1758
+    if (bn_exp != NULL)
2c1758
+        BN_free(bn_exp);
2c1758
 #endif
2c1758
 
2c1758
-    return (void *) rsa;
2c1758
+    return pkey;
2c1758
 }
2c1758
 
2c1758
-static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
+static EVP_PKEY *rsa_convert_private_key(OBJECT *key_obj)
2c1758
 {
2c1758
     CK_ATTRIBUTE *modulus = NULL;
2c1758
     CK_ATTRIBUTE *pub_exp = NULL;
2c1758
@@ -854,9 +660,15 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
     CK_ATTRIBUTE *exp1 = NULL;
2c1758
     CK_ATTRIBUTE *exp2 = NULL;
2c1758
     CK_ATTRIBUTE *coeff = NULL;
2c1758
-
2c1758
+    EVP_PKEY *pkey = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    EVP_PKEY_CTX *pctx = NULL;
2c1758
+    OSSL_PARAM_BLD *tmpl = NULL;
2c1758
+    OSSL_PARAM *params = NULL;
2c1758
+#else
2c1758
     RSA *rsa;
2c1758
     RSA_METHOD *meth;
2c1758
+#endif
2c1758
     BIGNUM *bn_mod, *bn_pub_exp, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2,
2c1758
         *bn_cf;
2c1758
 
2c1758
@@ -873,6 +685,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
     if (!prime2 && !modulus) {
2c1758
         return NULL;
2c1758
     }
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     // Create and init all the RSA and BIGNUM structs we need.
2c1758
     rsa = RSA_new();
2c1758
     if (rsa == NULL)
2c1758
@@ -884,17 +698,6 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
      * Token doesn't implement RSA and, instead, calls OpenSSL for it.
2c1758
      * So to avoid it we set RSA methods to the default rsa methods.
2c1758
      */
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    if (rsa->engine) {
2c1758
-        meth = (RSA_METHOD *) rsa->meth;
2c1758
-        const RSA_METHOD *meth2 = RSA_PKCS1_SSLeay();
2c1758
-        meth->rsa_pub_enc = meth2->rsa_pub_enc;
2c1758
-        meth->rsa_pub_dec = meth2->rsa_pub_dec;
2c1758
-        meth->rsa_priv_enc = meth2->rsa_priv_enc;
2c1758
-        meth->rsa_priv_dec = meth2->rsa_priv_dec;
2c1758
-        meth->rsa_mod_exp = meth2->rsa_mod_exp;
2c1758
-        meth->bn_mod_exp = meth2->bn_mod_exp;
2c1758
-#else
2c1758
 /*
2c1758
  * XXX I dont see a better way than to ignore this warning for now.
2c1758
  * Note that the GCC pragma also works for clang.
2c1758
@@ -912,8 +715,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
         RSA_meth_set_mod_exp(meth, RSA_meth_get_mod_exp(meth2));
2c1758
         RSA_meth_set_bn_mod_exp(meth, RSA_meth_get_bn_mod_exp(meth2));
2c1758
 # pragma GCC diagnostic pop
2c1758
-#endif
2c1758
     }
2c1758
+#endif
2c1758
 
2c1758
     bn_mod = BN_new();
2c1758
     bn_pub_exp = BN_new();
2c1758
@@ -926,33 +729,14 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
 
2c1758
     if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) ||
2c1758
         (bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) ||
2c1758
-        (bn_pub_exp == NULL) || (bn_mod == NULL)) {
2c1758
-        if (rsa)
2c1758
-            RSA_free(rsa);
2c1758
-        if (bn_mod)
2c1758
-            BN_free(bn_mod);
2c1758
-        if (bn_pub_exp)
2c1758
-            BN_free(bn_pub_exp);
2c1758
-        if (bn_priv_exp)
2c1758
-            BN_free(bn_priv_exp);
2c1758
-        if (bn_p1)
2c1758
-            BN_free(bn_p1);
2c1758
-        if (bn_p2)
2c1758
-            BN_free(bn_p2);
2c1758
-        if (bn_e1)
2c1758
-            BN_free(bn_e1);
2c1758
-        if (bn_e2)
2c1758
-            BN_free(bn_e2);
2c1758
-        if (bn_cf)
2c1758
-            BN_free(bn_cf);
2c1758
-        return NULL;
2c1758
-    }
2c1758
+        (bn_pub_exp == NULL) || (bn_mod == NULL))
2c1758
+        goto out;
2c1758
 
2c1758
     // CRT key?
2c1758
     if (prime1) {
2c1758
-        if (!prime2 || !exp1 || !exp2 || !coeff) {
2c1758
-            return NULL;
2c1758
-        }
2c1758
+        if (!prime2 || !exp1 || !exp2 || !coeff)
2c1758
+            goto out;
2c1758
+
2c1758
         // Even though this is CRT key, OpenSSL requires the
2c1758
         // modulus and exponents filled in or encrypt and decrypt will
2c1758
         // not work
2c1758
@@ -969,20 +753,44 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
         BN_bin2bn((unsigned char *) exp1->pValue, exp1->ulValueLen, bn_e1);
2c1758
         BN_bin2bn((unsigned char *) exp2->pValue, exp2->ulValueLen, bn_e2);
2c1758
         BN_bin2bn((unsigned char *) coeff->pValue, coeff->ulValueLen, bn_cf);
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-        rsa->n = bn_mod;
2c1758
-        rsa->d = bn_priv_exp;
2c1758
-        rsa->p = bn_p1;
2c1758
-        rsa->q = bn_p2;
2c1758
-        rsa->dmp1 = bn_e1;
2c1758
-        rsa->dmq1 = bn_e2;
2c1758
-        rsa->iqmp = bn_cf;
2c1758
-#else
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp);
2c1758
+        bn_mod = NULL;
2c1758
+        bn_pub_exp = NULL;
2c1758
+        bn_priv_exp = NULL;
2c1758
         RSA_set0_factors(rsa, bn_p1, bn_p2);
2c1758
+        bn_p1 = NULL;
2c1758
+        bn_p2 = NULL;
2c1758
         RSA_set0_crt_params(rsa, bn_e1, bn_e2, bn_cf);
2c1758
+        bn_e1 = NULL;
2c1758
+        bn_e2 = NULL;
2c1758
+        bn_cf = NULL;
2c1758
+
2c1758
+        pkey = EVP_PKEY_new();
2c1758
+        if (pkey == NULL)
2c1758
+            goto out;
2c1758
+
2c1758
+        if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
2c1758
+            goto out;
2c1758
+#else
2c1758
+        tmpl = OSSL_PARAM_BLD_new();
2c1758
+        if (tmpl == NULL)
2c1758
+            goto out;
2c1758
+
2c1758
+        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR1, bn_p1) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR2, bn_p2) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT1,
2c1758
+                                                                       bn_e1) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT2,
2c1758
+                                                                       bn_e2) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
2c1758
+                                                                       bn_cf))
2c1758
+            goto out;
2c1758
 #endif
2c1758
-        return rsa;
2c1758
     } else {                    // must be a non-CRT key
2c1758
         if (!priv_exp) {
2c1758
             return NULL;
2c1758
@@ -993,15 +801,90 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
2c1758
                   bn_pub_exp);
2c1758
         BN_bin2bn((unsigned char *) priv_exp->pValue, priv_exp->ulValueLen,
2c1758
                   bn_priv_exp);
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-        rsa->n = bn_mod;
2c1758
-        rsa->d = bn_priv_exp;
2c1758
-#else
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp);
2c1758
+        bn_mod = NULL;
2c1758
+        bn_pub_exp = NULL;
2c1758
+        bn_priv_exp = NULL;
2c1758
+
2c1758
+        pkey = EVP_PKEY_new();
2c1758
+        if (pkey == NULL)
2c1758
+            goto out;
2c1758
+
2c1758
+        if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
2c1758
+            goto out;
2c1758
+#else
2c1758
+        tmpl = OSSL_PARAM_BLD_new();
2c1758
+        if (tmpl == NULL)
2c1758
+            goto out;
2c1758
+
2c1758
+        if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) ||
2c1758
+            !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp))
2c1758
+            goto out;
2c1758
 #endif
2c1758
     }
2c1758
 
2c1758
-    return (void *) rsa;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    params = OSSL_PARAM_BLD_to_param(tmpl);
2c1758
+    if (params == NULL)
2c1758
+        goto out;
2c1758
+
2c1758
+    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
2c1758
+    if (pctx == NULL)
2c1758
+        goto out;
2c1758
+
2c1758
+    if (!EVP_PKEY_fromdata_init(pctx) ||
2c1758
+        !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params))
2c1758
+        goto out;
2c1758
+
2c1758
+    EVP_PKEY_CTX_free(pctx);
2c1758
+    OSSL_PARAM_BLD_free(tmpl);
2c1758
+    OSSL_PARAM_free(params);
2c1758
+    BN_free(bn_mod);
2c1758
+    BN_free(bn_pub_exp);
2c1758
+    BN_free(bn_priv_exp);
2c1758
+    BN_free(bn_p1);
2c1758
+    BN_free(bn_p2);
2c1758
+    BN_free(bn_e1);
2c1758
+    BN_free(bn_e2);
2c1758
+    BN_free(bn_cf);
2c1758
+#endif
2c1758
+
2c1758
+    return pkey;
2c1758
+out:
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (rsa)
2c1758
+        RSA_free(rsa);
2c1758
+#else
2c1758
+    if (pctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(pctx);
2c1758
+    if (tmpl != NULL)
2c1758
+        OSSL_PARAM_BLD_free(tmpl);
2c1758
+    if (params != NULL)
2c1758
+        OSSL_PARAM_free(params);
2c1758
+#endif
2c1758
+    if (pkey)
2c1758
+        EVP_PKEY_free(pkey);
2c1758
+    if (bn_mod)
2c1758
+        BN_free(bn_mod);
2c1758
+    if (bn_pub_exp)
2c1758
+        BN_free(bn_pub_exp);
2c1758
+    if (bn_priv_exp)
2c1758
+        BN_free(bn_priv_exp);
2c1758
+    if (bn_p1)
2c1758
+        BN_free(bn_p1);
2c1758
+    if (bn_p2)
2c1758
+        BN_free(bn_p2);
2c1758
+    if (bn_e1)
2c1758
+        BN_free(bn_e1);
2c1758
+    if (bn_e2)
2c1758
+        BN_free(bn_e2);
2c1758
+    if (bn_cf)
2c1758
+        BN_free(bn_cf);
2c1758
+
2c1758
+    return NULL;
2c1758
 }
2c1758
 
2c1758
 static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
@@ -1012,14 +895,16 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     CK_BBOOL flag;
2c1758
     CK_RV rc;
2c1758
     CK_ULONG BNLength;
2c1758
-    RSA *rsa = NULL;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    const RSA *rsa = NULL;
2c1758
     const BIGNUM *bignum = NULL;
2c1758
+#else
2c1758
+    BIGNUM *bignum = NULL;
2c1758
+#endif
2c1758
     CK_BYTE *ssl_ptr = NULL;
2c1758
     BIGNUM *e = NULL;
2c1758
-#ifndef OLDER_OPENSSL
2c1758
     EVP_PKEY *pkey = NULL;
2c1758
     EVP_PKEY_CTX *ctx = NULL;
2c1758
-#endif
2c1758
 
2c1758
     rc = template_attribute_get_ulong(publ_tmpl, CKA_MODULUS_BITS, &mod_bits);
2c1758
     if (rc != CKR_OK) {
2c1758
@@ -1052,20 +937,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     }
2c1758
     BN_bin2bn(publ_exp->pValue, publ_exp->ulValueLen, e);
2c1758
 
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    rsa = RSA_new();
2c1758
-    if (rsa == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        return CKR_HOST_MEMORY;
2c1758
-    }
2c1758
-
2c1758
-    if (!RSA_generate_key_ex(rsa, mod_bits, e, NULL)) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
-    }
2c1758
-    bignum = rsa->n;
2c1758
-#else
2c1758
     ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
2c1758
     if (ctx == NULL) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
@@ -1084,22 +955,36 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto done;
2c1758
     }
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, e) != 1) {
2c1758
+#else
2c1758
+    if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) != 1) {
2c1758
+#endif
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto done;
2c1758
     }
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    e = NULL; // will be freed as part of the context
2c1758
+#endif
2c1758
     if (EVP_PKEY_keygen(ctx, &pkey) != 1) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto done;
2c1758
     }
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto done;
2c1758
     }
2c1758
     RSA_get0_key(rsa, &bignum, NULL, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1122,12 +1007,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     }
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // Public Exponent
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->e;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_key(rsa, NULL, &bignum, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1166,6 +1059,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     }
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // local = TRUE
2c1758
     //
2c1758
@@ -1189,10 +1086,14 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     // to force the system to not return this for RSA keys..
2c1758
 
2c1758
     // Add the modulus to the private key information
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->n;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_key(rsa, &bignum, NULL, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1215,12 +1116,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     }
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // Private Exponent
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->d;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_key(rsa, NULL, NULL, &bignum);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1245,13 +1154,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // prime #1: p
2c1758
-    //
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->p;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_factors(rsa, &bignum, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1276,13 +1192,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // prime #2: q
2c1758
-    //
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->q;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_factors(rsa, NULL, &bignum);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1307,13 +1230,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // exponent 1: d mod(p-1)
2c1758
-    //
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->dmp1;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_crt_params(rsa, &bignum, NULL, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1338,13 +1268,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // exponent 2: d mod(q-1)
2c1758
-    //
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->dmq1;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_crt_params(rsa, NULL, &bignum, NULL);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1369,13 +1306,21 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // CRT coefficient:  q_inverse mod(p)
2c1758
-    //
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    bignum = rsa->iqmp;
2c1758
-#else
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     RSA_get0_crt_params(rsa, NULL, NULL, &bignum);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
2c1758
+                               &bignum)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
 #endif
2c1758
     BNLength = BN_num_bytes(bignum);
2c1758
     ssl_ptr = malloc(BNLength);
2c1758
@@ -1400,6 +1345,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
     free(ssl_ptr);
2c1758
     ssl_ptr = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(bignum);
2c1758
+    bignum = NULL;
2c1758
+#endif
2c1758
 
2c1758
     flag = TRUE;
2c1758
     rc = build_attribute(CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr);
2c1758
@@ -1415,16 +1364,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
2c1758
     }
2c1758
 
2c1758
 done:
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    if (e != NULL)
2c1758
-        BN_free(e);
2c1758
-    if (rsa != NULL)
2c1758
-        RSA_free(rsa);
2c1758
-    if (ssl_ptr != NULL) {
2c1758
-        OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
-        free(ssl_ptr);
2c1758
-    }
2c1758
-#else
2c1758
     if (ssl_ptr != NULL) {
2c1758
         OPENSSL_cleanse(ssl_ptr, BNLength);
2c1758
         free(ssl_ptr);
2c1758
@@ -1433,6 +1372,11 @@ done:
2c1758
         EVP_PKEY_free(pkey);
2c1758
     if (ctx != NULL)
2c1758
         EVP_PKEY_CTX_free(ctx);
2c1758
+    if (e != NULL)
2c1758
+        BN_free(e);
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (bignum != NULL)
2c1758
+        BN_free(bignum);
2c1758
 #endif
2c1758
     return rc;
2c1758
 }
2c1758
@@ -1457,60 +1401,17 @@ static CK_RV os_specific_rsa_encrypt(CK_BYTE *in_data,
2c1758
                                      CK_ULONG in_data_len,
2c1758
                                      CK_BYTE *out_data, OBJECT *key_obj)
2c1758
 {
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    CK_RV rc;
2c1758
-    RSA *rsa;
2c1758
-    int size;
2c1758
-
2c1758
-    // Convert the local representation to an RSA representation
2c1758
-    rsa = (RSA *) rsa_convert_public_key(key_obj);
2c1758
-    if (rsa == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // Do an RSA public encryption
2c1758
-    size =
2c1758
-        RSA_public_encrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING);
2c1758
-    if (size == -1) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_ARGUMENTS_BAD;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    rc = CKR_OK;
2c1758
-
2c1758
-done:
2c1758
-    RSA_free(rsa);
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     EVP_PKEY_CTX *ctx = NULL;
2c1758
     EVP_PKEY *pkey = NULL;
2c1758
-    RSA *rsa = NULL;
2c1758
     CK_RV rc;
2c1758
     size_t outlen = in_data_len;
2c1758
 
2c1758
-    rsa = (RSA *)rsa_convert_public_key(key_obj);
2c1758
-    if (rsa == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    pkey = EVP_PKEY_new();
2c1758
+    pkey = rsa_convert_public_key(key_obj);
2c1758
     if (pkey == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        rc = CKR_HOST_MEMORY;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
+        return rc;
2c1758
     }
2c1758
-    rsa = NULL; /* freed together with pkey */
2c1758
 
2c1758
     ctx = EVP_PKEY_CTX_new(pkey, NULL);
2c1758
     if (ctx == NULL) {
2c1758
@@ -1538,76 +1439,28 @@ done:
2c1758
 
2c1758
     rc = CKR_OK;
2c1758
 done:
2c1758
-    if (rsa != NULL)
2c1758
-        RSA_free(rsa);
2c1758
     if (pkey != NULL)
2c1758
         EVP_PKEY_free(pkey);
2c1758
     if (ctx != NULL)
2c1758
         EVP_PKEY_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 static CK_RV os_specific_rsa_decrypt(CK_BYTE *in_data,
2c1758
                                      CK_ULONG in_data_len,
2c1758
                                      CK_BYTE *out_data, OBJECT *key_obj)
2c1758
 {
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-    CK_RV rc;
2c1758
-    RSA *rsa;
2c1758
-    int size;
2c1758
-
2c1758
-    // Convert the local key representation to an RSA key representaion
2c1758
-    rsa = (RSA *) rsa_convert_private_key(key_obj);
2c1758
-    if (rsa == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // Do the private decryption
2c1758
-    size =
2c1758
-        RSA_private_decrypt(in_data_len, in_data, out_data, rsa,
2c1758
-                            RSA_NO_PADDING);
2c1758
-
2c1758
-    if (size == -1) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    rc = CKR_OK;
2c1758
-
2c1758
-done:
2c1758
-    RSA_free(rsa);
2c1758
-
2c1758
-    return rc;
2c1758
-#else
2c1758
     EVP_PKEY_CTX *ctx = NULL;
2c1758
     EVP_PKEY *pkey = NULL;
2c1758
-    RSA *rsa = NULL;
2c1758
     size_t outlen = in_data_len;
2c1758
     CK_RV rc;
2c1758
 
2c1758
-    rsa = (RSA *)rsa_convert_private_key(key_obj);
2c1758
-    if (rsa == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rc = CKR_FUNCTION_FAILED;
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    pkey = EVP_PKEY_new();
2c1758
+    pkey = rsa_convert_private_key(key_obj);
2c1758
     if (pkey == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        rc = CKR_HOST_MEMORY;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
+        return rc;
2c1758
     }
2c1758
-    rsa = NULL; /* freed together with pkey */
2c1758
 
2c1758
     ctx = EVP_PKEY_CTX_new(pkey, NULL);
2c1758
     if (ctx == NULL) {
2c1758
@@ -1635,14 +1488,11 @@ done:
2c1758
 
2c1758
     rc = CKR_OK;
2c1758
 done:
2c1758
-    if (rsa != NULL)
2c1758
-        RSA_free(rsa);
2c1758
     if (pkey != NULL)
2c1758
         EVP_PKEY_free(pkey);
2c1758
     if (ctx != NULL)
2c1758
         EVP_PKEY_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_rsa_encrypt(STDLL_TokData_t *tokdata, CK_BYTE *in_data,
2c1758
@@ -2407,48 +2257,6 @@ CK_RV token_specific_aes_ecb(STDLL_TokData_t *tokdata,
2c1758
                              CK_ULONG *out_data_len,
2c1758
                              OBJECT *key, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    AES_KEY ssl_aes_key;
2c1758
-    unsigned int i;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0,
2c1758
-     * so this is fine */
2c1758
-    CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE);
2c1758
-    CK_RV rc;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    memset(&ssl_aes_key, 0, sizeof(AES_KEY));
2c1758
-
2c1758
-    // get key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // AES_ecb_encrypt encrypts only a single block, so we have to break up the
2c1758
-    // input data here
2c1758
-    if (encrypt) {
2c1758
-        AES_set_encrypt_key((unsigned char *) attr->pValue,
2c1758
-                            (attr->ulValueLen * 8), &ssl_aes_key);
2c1758
-        for (i = 0; i < loops; i++) {
2c1758
-            AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
2c1758
-                            (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
2c1758
-                            &ssl_aes_key, AES_ENCRYPT);
2c1758
-        }
2c1758
-    } else {
2c1758
-        AES_set_decrypt_key((unsigned char *) attr->pValue,
2c1758
-                            (attr->ulValueLen * 8), &ssl_aes_key);
2c1758
-        for (i = 0; i < loops; i++) {
2c1758
-            AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
2c1758
-                            (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
2c1758
-                            &ssl_aes_key, AES_DECRYPT);
2c1758
-        }
2c1758
-    }
2c1758
-    *out_data_len = in_data_len;
2c1758
-
2c1758
-    return CKR_OK;
2c1758
-#else
2c1758
     CK_RV rc;
2c1758
     int outlen;
2c1758
     unsigned char akey[32];
2c1758
@@ -2505,7 +2313,6 @@ done:
2c1758
     OPENSSL_cleanse(akey, sizeof(akey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata,
2c1758
@@ -2515,38 +2322,6 @@ CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata,
2c1758
                              CK_ULONG *out_data_len,
2c1758
                              OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
-    AES_KEY ssl_aes_key;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    CK_RV rc;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    memset(&ssl_aes_key, 0, sizeof(AES_KEY));
2c1758
-
2c1758
-    // get key value
2c1758
-    rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_VALUE for the key\n");
2c1758
-        return rc;
2c1758
-    }
2c1758
-    // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike
2c1758
-    // AES_ecb_encrypt, so no looping required.
2c1758
-    if (encrypt) {
2c1758
-        AES_set_encrypt_key((unsigned char *) attr->pValue,
2c1758
-                            (attr->ulValueLen * 8), &ssl_aes_key);
2c1758
-        AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
2c1758
-                        in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT);
2c1758
-    } else {
2c1758
-        AES_set_decrypt_key((unsigned char *) attr->pValue,
2c1758
-                            (attr->ulValueLen * 8), &ssl_aes_key);
2c1758
-        AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
2c1758
-                        in_data_len, &ssl_aes_key, init_v, AES_DECRYPT);
2c1758
-    }
2c1758
-    *out_data_len = in_data_len;
2c1758
-
2c1758
-    return CKR_OK;
2c1758
-#else
2c1758
     CK_RV rc;
2c1758
     int outlen;
2c1758
     unsigned char akey[32];
2c1758
@@ -2603,7 +2378,6 @@ done:
2c1758
     OPENSSL_cleanse(akey, sizeof(akey));
2c1758
     EVP_CIPHER_CTX_free(ctx);
2c1758
     return rc;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 CK_RV token_specific_aes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
@@ -2716,275 +2490,145 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
2c1758
                                           TEMPLATE *publ_tmpl,
2c1758
                                           TEMPLATE *priv_tmpl)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2c1758
     CK_RV rv;
2c1758
     CK_BBOOL rc;
2c1758
     CK_ATTRIBUTE *prime_attr = NULL;
2c1758
     CK_ATTRIBUTE *base_attr = NULL;
2c1758
     CK_ATTRIBUTE *temp_attr = NULL;
2c1758
     CK_ATTRIBUTE *value_bits_attr = NULL;
2c1758
-    CK_BYTE *temp_byte;
2c1758
+    CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL;
2c1758
     CK_ULONG temp_bn_len;
2c1758
-    DH *dh;
2c1758
-    BIGNUM *bn_p;
2c1758
-    BIGNUM *bn_g;
2c1758
-    const BIGNUM *temp_bn;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    DH *dh = NULL;
2c1758
+#else
2c1758
+    EVP_PKEY_CTX *pctx = NULL;
2c1758
+    OSSL_PARAM_BLD *tmpl = NULL;
2c1758
+    OSSL_PARAM *osparams = NULL;
2c1758
+#endif
2c1758
+    BIGNUM *bn_p = NULL;
2c1758
+    BIGNUM *bn_g = NULL;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    const BIGNUM *temp_bn = NULL;
2c1758
+#else
2c1758
+    BIGNUM *temp_bn = NULL;
2c1758
+#endif
2c1758
+    EVP_PKEY *params = NULL, *pkey = NULL;
2c1758
+    EVP_PKEY_CTX *ctx = NULL;
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
     rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr);
2c1758
     if (rv != CKR_OK) {
2c1758
         TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
2c1758
-        return rv;
2c1758
+        goto done;
2c1758
     }
2c1758
     rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr);
2c1758
     if (rv != CKR_OK) {
2c1758
         TRACE_ERROR("Could not find CKA_BASE for the key.\n");
2c1758
-        return rv;
2c1758
+        goto done;
2c1758
     }
2c1758
 
2c1758
     if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) {
2c1758
         TRACE_ERROR("CKA_PRIME attribute value is invalid.\n");
2c1758
-        return CKR_ATTRIBUTE_VALUE_INVALID;
2c1758
+        rv = CKR_ATTRIBUTE_VALUE_INVALID;
2c1758
+        goto done;
2c1758
     }
2c1758
 
2c1758
-    dh = DH_new();
2c1758
-    if (dh == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-    // Create and init BIGNUM structs to stick in the DH struct
2c1758
+    // Create and init BIGNUM structs
2c1758
     bn_p = BN_new();
2c1758
     bn_g = BN_new();
2c1758
     if (bn_g == NULL || bn_p == NULL) {
2c1758
-        if (bn_g)
2c1758
-            BN_free(bn_g);
2c1758
-        if (bn_p)
2c1758
-            BN_free(bn_p);
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        return CKR_HOST_MEMORY;
2c1758
+        rv = CKR_HOST_MEMORY;
2c1758
+        goto done;
2c1758
     }
2c1758
-    // Convert from strings to BIGNUMs and stick them in the DH struct
2c1758
+    // Convert from strings to BIGNUMs
2c1758
     BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen,
2c1758
               bn_p);
2c1758
     BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g);
2c1758
-    dh->p = bn_p;
2c1758
-    dh->g = bn_g;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    dh = DH_new();
2c1758
+    if (dh == NULL) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rv = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
+
2c1758
+    DH_set0_pqg(dh, bn_p, NULL, bn_g);
2c1758
+    /* bn_p and bn_q freed together with dh */
2c1758
+    bn_p = NULL;
2c1758
+    bn_g = NULL;
2c1758
+
2c1758
+    params = EVP_PKEY_new();
2c1758
+    if (params == NULL) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
+        rv = CKR_HOST_MEMORY;
2c1758
+        goto done;
2c1758
+    }
2c1758
 
2c1758
-    // Generate the DH Key
2c1758
-    if (!DH_generate_key(dh)) {
2c1758
+    if (EVP_PKEY_assign_DH(params, dh) != 1) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        DH_free(dh);
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
+        rv = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
+    dh = NULL; /* freed together with params */
2c1758
+#else
2c1758
+    tmpl = OSSL_PARAM_BLD_new();
2c1758
+    if (tmpl == NULL)
2c1758
+        goto done;
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, bn_p) ||
2c1758
+        !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, bn_g))
2c1758
+        goto done;
2c1758
+
2c1758
+    osparams = OSSL_PARAM_BLD_to_param(tmpl);
2c1758
+    if (osparams == NULL)
2c1758
+        goto done;
2c1758
+
2c1758
+    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2c1758
+    if (pctx == NULL)
2c1758
+        goto done;
2c1758
+
2c1758
+    if (!EVP_PKEY_fromdata_init(pctx) ||
2c1758
+        !EVP_PKEY_fromdata(pctx, &params, EVP_PKEY_PUBLIC_KEY, osparams))
2c1758
+        goto done;
2c1758
+#endif
2c1758
+
2c1758
+    ctx = EVP_PKEY_CTX_new(params, NULL);
2c1758
+    if (ctx == NULL) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
+        rv = CKR_HOST_MEMORY;
2c1758
+        goto done;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_keygen_init(ctx) != 1
2c1758
+        || EVP_PKEY_keygen(ctx, &pkey) != 1
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+        /* dh is freed together with pkey */
2c1758
+        || (dh = (DH *)EVP_PKEY_get0_DH(pkey)) == NULL) {
2c1758
+#else
2c1758
+        ) {
2c1758
+#endif
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rv = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
     }
2c1758
+
2c1758
     // Extract the public and private key components from the DH struct,
2c1758
     // and insert them in the publ_tmpl and priv_tmpl
2c1758
 
2c1758
     //
2c1758
     // pub_key
2c1758
     //
2c1758
-    //temp_bn = BN_new();
2c1758
-    temp_bn = dh->pub_key;
2c1758
-    temp_bn_len = BN_num_bytes(temp_bn);
2c1758
-    temp_byte = malloc(temp_bn_len);
2c1758
-    temp_bn_len = BN_bn2bin(temp_bn, temp_byte);
2c1758
-    // in bytes
2c1758
-    rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_DEVEL("build_attribute failed\n");
2c1758
-        DH_free(dh);
2c1758
-        free(temp_byte);
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-    rc = template_update_attribute(publ_tmpl, temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("template_update_attribute failed\n");
2c1758
-        free(temp_attr);
2c1758
-        DH_free(dh);
2c1758
-        free(temp_byte);
2c1758
-        return rc;
2c1758
-    }
2c1758
-    free(temp_byte);
2c1758
-
2c1758
-    //
2c1758
-    // priv_key
2c1758
-    //
2c1758
-    //temp_bn = BN_new();
2c1758
-    temp_bn = dh->priv_key;
2c1758
-    temp_bn_len = BN_num_bytes(temp_bn);
2c1758
-    temp_byte = malloc(temp_bn_len);
2c1758
-    temp_bn_len = BN_bn2bin(temp_bn, temp_byte);
2c1758
-    // in bytes
2c1758
-    rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_DEVEL("build_attribute failed\n");
2c1758
-        DH_free(dh);
2c1758
-        free(temp_byte);
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-    rc = template_update_attribute(priv_tmpl, temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("template_update_attribute failed\n");
2c1758
-        free(temp_attr);
2c1758
-        DH_free(dh);
2c1758
-        free(temp_byte);
2c1758
-        return rc;
2c1758
-    }
2c1758
-    free(temp_byte);
2c1758
-
2c1758
-    // Update CKA_VALUE_BITS attribute in the private key
2c1758
-    value_bits_attr =
2c1758
-        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
2c1758
-    if (value_bits_attr == NULL) {
2c1758
-        TRACE_ERROR("malloc failed\n");
2c1758
-        DH_free(dh);
2c1758
-        return CKR_HOST_MEMORY;
2c1758
-    }
2c1758
-    value_bits_attr->type = CKA_VALUE_BITS;
2c1758
-    value_bits_attr->ulValueLen = sizeof(CK_ULONG);
2c1758
-    value_bits_attr->pValue =
2c1758
-        (CK_BYTE *) value_bits_attr + sizeof(CK_ATTRIBUTE);
2c1758
-    *(CK_ULONG *) value_bits_attr->pValue = 8 * temp_bn_len;
2c1758
-    rc = template_update_attribute(priv_tmpl, value_bits_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("template_update_attribute failed\n");
2c1758
-        free(value_bits_attr);
2c1758
-        DH_free(dh);
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    // Add prime and base to the private key template
2c1758
-    rc = build_attribute(CKA_PRIME,
2c1758
-                         (unsigned char *) prime_attr->pValue,
2c1758
-                         prime_attr->ulValueLen, &temp_attr);  // in bytes
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_DEVEL("build_attribute failed\n");
2c1758
-        DH_free(dh);
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-    rc = template_update_attribute(priv_tmpl, temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("template_update_attribute failed\n");
2c1758
-        free(temp_attr);
2c1758
-        DH_free(dh);
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    rc = build_attribute(CKA_BASE,
2c1758
-                         (unsigned char *) base_attr->pValue,
2c1758
-                         base_attr->ulValueLen, &temp_attr);     // in bytes
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_DEVEL("build_attribute failed\n");
2c1758
-        DH_free(dh);
2c1758
-        return CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-    rc = template_update_attribute(priv_tmpl, temp_attr);
2c1758
-    if (rc != CKR_OK) {
2c1758
-        TRACE_ERROR("template_update_attribute failed\n");
2c1758
-        free(temp_attr);
2c1758
-        DH_free(dh);
2c1758
-        return rc;
2c1758
-    }
2c1758
-
2c1758
-    // Cleanup DH key
2c1758
-    DH_free(dh);
2c1758
-
2c1758
-    return CKR_OK;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    DH_get0_key(dh, &temp_bn, NULL);
2c1758
 #else
2c1758
-    CK_RV rv;
2c1758
-    CK_BBOOL rc;
2c1758
-    CK_ATTRIBUTE *prime_attr = NULL;
2c1758
-    CK_ATTRIBUTE *base_attr = NULL;
2c1758
-    CK_ATTRIBUTE *temp_attr = NULL;
2c1758
-    CK_ATTRIBUTE *value_bits_attr = NULL;
2c1758
-    CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL;
2c1758
-    CK_ULONG temp_bn_len;
2c1758
-    DH *dh = NULL;
2c1758
-    BIGNUM *bn_p = NULL;
2c1758
-    BIGNUM *bn_g = NULL;
2c1758
-    const BIGNUM *temp_bn = NULL;
2c1758
-    EVP_PKEY *params = NULL, *pkey = NULL;
2c1758
-    EVP_PKEY_CTX *ctx = NULL;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr);
2c1758
-    if (rv != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
2c1758
-        goto done;
2c1758
-    }
2c1758
-    rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr);
2c1758
-    if (rv != CKR_OK) {
2c1758
-        TRACE_ERROR("Could not find CKA_BASE for the key.\n");
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) {
2c1758
-        TRACE_ERROR("CKA_PRIME attribute value is invalid.\n");
2c1758
-        rv = CKR_ATTRIBUTE_VALUE_INVALID;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    dh = DH_new();
2c1758
-    if (dh == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rv = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
-    }
2c1758
-    // Create and init BIGNUM structs to stick in the DH struct
2c1758
-    bn_p = BN_new();
2c1758
-    bn_g = BN_new();
2c1758
-    if (bn_g == NULL || bn_p == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        rv = CKR_HOST_MEMORY;
2c1758
-        goto done;
2c1758
-    }
2c1758
-    // Convert from strings to BIGNUMs and stick them in the DH struct
2c1758
-    BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen,
2c1758
-              bn_p);
2c1758
-    BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g);
2c1758
-    DH_set0_pqg(dh, bn_p, NULL, bn_g);
2c1758
-    /* bn_p and bn_q freed together with dh */
2c1758
-    bn_p = NULL;
2c1758
-    bn_g = NULL;
2c1758
-
2c1758
-    params = EVP_PKEY_new();
2c1758
-    if (params == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        rv = CKR_HOST_MEMORY;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    if (EVP_PKEY_assign_DH(params, dh) != 1) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rv = CKR_FUNCTION_FAILED;
2c1758
-        goto done;
2c1758
-    }
2c1758
-    dh = NULL; /* freed together with params */
2c1758
-
2c1758
-    ctx = EVP_PKEY_CTX_new(params, NULL);
2c1758
-    if (ctx == NULL) {
2c1758
-        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-        rv = CKR_HOST_MEMORY;
2c1758
-        goto done;
2c1758
-    }
2c1758
-
2c1758
-    if (EVP_PKEY_keygen_init(ctx) != 1
2c1758
-        || EVP_PKEY_keygen(ctx, &pkey) != 1
2c1758
-        /* dh is freed together with pkey */
2c1758
-        || (dh = EVP_PKEY_get0_DH(pkey)) == NULL) {
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &temp_bn)) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
-        rv = CKR_FUNCTION_FAILED;
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
         goto done;
2c1758
     }
2c1758
-
2c1758
-    // Extract the public and private key components from the DH struct,
2c1758
-    // and insert them in the publ_tmpl and priv_tmpl
2c1758
-
2c1758
-    //
2c1758
-    // pub_key
2c1758
-    //
2c1758
-    DH_get0_key(dh, &temp_bn, NULL);
2c1758
+#endif
2c1758
 
2c1758
     temp_bn_len = BN_num_bytes(temp_bn);
2c1758
     temp_byte = malloc(temp_bn_len);
2c1758
@@ -3001,11 +2645,23 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
2c1758
         free(temp_attr);
2c1758
         goto done;
2c1758
     }
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(temp_bn);
2c1758
+    temp_bn = NULL;
2c1758
+#endif
2c1758
 
2c1758
     //
2c1758
     // priv_key
2c1758
     //
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     DH_get0_key(dh, NULL, &temp_bn);
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &temp_bn)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto done;
2c1758
+    }
2c1758
+#endif
2c1758
     temp_bn_len = BN_num_bytes(temp_bn);
2c1758
     temp_byte2 = malloc(temp_bn_len);
2c1758
     temp_bn_len = BN_bn2bin(temp_bn, temp_byte2);
2c1758
@@ -3022,6 +2678,10 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
2c1758
         free(temp_attr);
2c1758
         goto done;
2c1758
     }
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    BN_free(temp_bn);
2c1758
+    temp_bn = NULL;
2c1758
+#endif
2c1758
 
2c1758
     // Update CKA_VALUE_BITS attribute in the private key
2c1758
     value_bits_attr =
2c1758
@@ -3086,8 +2746,17 @@ done:
2c1758
         EVP_PKEY_free(params);
2c1758
     free(temp_byte);
2c1758
     free(temp_byte2);
2c1758
-    return rv;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (pctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(pctx);
2c1758
+    if (tmpl != NULL)
2c1758
+        OSSL_PARAM_BLD_free(tmpl);
2c1758
+    if (osparams != NULL)
2c1758
+        OSSL_PARAM_free(osparams);
2c1758
+    if (temp_bn != NULL)
2c1758
+        BN_free(temp_bn);
2c1758
 #endif
2c1758
+    return rv;
2c1758
 }                               /* end token_specific_dh_key_pair_gen() */
2c1758
 #endif
2c1758
 /* End code contributed by Corrent corp. */
2c1758
@@ -3106,11 +2775,6 @@ CK_RV token_specific_get_mechanism_info(STDLL_TokData_t *tokdata,
2c1758
     return ock_generic_get_mechanism_info(tokdata, type, pInfo);
2c1758
 }
2c1758
 
2c1758
-#ifdef OLDER_OPENSSL
2c1758
-#define EVP_MD_meth_get_app_datasize(md)        md->ctx_size
2c1758
-#define EVP_MD_CTX_md_data(ctx)                 ctx->md_data
2c1758
-#endif
2c1758
-
2c1758
 static const EVP_MD *md_from_mech(CK_MECHANISM *mech)
2c1758
 {
2c1758
     const EVP_MD *md = NULL;
2c1758
@@ -3168,16 +2832,13 @@ static const EVP_MD *md_from_mech(CK_MECHANISM *mech)
2c1758
     return md;
2c1758
 }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
 static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
2c1758
 {
2c1758
     const EVP_MD *md;
2c1758
     EVP_MD_CTX *md_ctx;
2c1758
 
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    md_ctx = EVP_MD_CTX_create();
2c1758
-#else
2c1758
     md_ctx = EVP_MD_CTX_new();
2c1758
-#endif
2c1758
     if (md_ctx == NULL)
2c1758
         return NULL;
2c1758
 
2c1758
@@ -3185,11 +2846,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
2c1758
     if (md == NULL ||
2c1758
         !EVP_DigestInit_ex(md_ctx, md, NULL)) {
2c1758
         TRACE_ERROR("md_from_mech or EVP_DigestInit_ex failed\n");
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-        EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
         EVP_MD_CTX_free(md_ctx);
2c1758
-#endif
2c1758
         return NULL;
2c1758
     }
2c1758
 
2c1758
@@ -3198,11 +2855,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
2c1758
         ctx->context = malloc(ctx->context_len);
2c1758
         if (ctx->context == NULL) {
2c1758
             TRACE_ERROR("malloc failed\n");
2c1758
-    #if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-            EVP_MD_CTX_destroy(md_ctx);
2c1758
-    #else
2c1758
             EVP_MD_CTX_free(md_ctx);
2c1758
-    #endif
2c1758
             ctx->context_len = 0;
2c1758
             return NULL;
2c1758
         }
2c1758
@@ -3221,27 +2874,60 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
2c1758
 
2c1758
     return md_ctx;
2c1758
 }
2c1758
+#endif
2c1758
+
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+static void token_specific_sha_free(STDLL_TokData_t *tokdata, SESSION *sess,
2c1758
+                                    CK_BYTE *context, CK_ULONG context_len)
2c1758
+{
2c1758
+    UNUSED(tokdata);
2c1758
+    UNUSED(sess);
2c1758
+    UNUSED(context_len);
2c1758
+
2c1758
+    EVP_MD_CTX_free((EVP_MD_CTX *)context);
2c1758
+}
2c1758
+#endif
2c1758
 
2c1758
 CK_RV token_specific_sha_init(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
                               CK_MECHANISM *mech)
2c1758
 {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     EVP_MD_CTX *md_ctx;
2c1758
+#else
2c1758
+    const EVP_MD *md;
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
     ctx->mech.ulParameterLen = mech->ulParameterLen;
2c1758
     ctx->mech.mechanism = mech->mechanism;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     md_ctx = md_ctx_from_context(ctx);
2c1758
     if (md_ctx == NULL) {
2c1758
         TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
         return CKR_HOST_MEMORY;
2c1758
     }
2c1758
 
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
     EVP_MD_CTX_free(md_ctx);
2c1758
+#else
2c1758
+    ctx->context_len = 1;
2c1758
+    ctx->context = (CK_BYTE *)EVP_MD_CTX_new();
2c1758
+    if (ctx->context == NULL) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
+        return CKR_HOST_MEMORY;
2c1758
+    }
2c1758
+
2c1758
+    md = md_from_mech(&ctx->mech);
2c1758
+    if (md == NULL ||
2c1758
+        !EVP_DigestInit_ex((EVP_MD_CTX *)ctx->context, md, NULL)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
2c1758
+        return CKR_FUNCTION_FAILED;
2c1758
+    }
2c1758
+
2c1758
+    ctx->state_unsaveable = CK_TRUE;
2c1758
+    ctx->context_free_func = token_specific_sha_free;
2c1758
 #endif
2c1758
 
2c1758
     return CKR_OK;
2c1758
@@ -3253,7 +2939,9 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
 {
2c1758
     unsigned int len;
2c1758
     CK_RV rc = CKR_OK;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     EVP_MD_CTX *md_ctx;
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
@@ -3263,6 +2951,7 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
     if (!in_data || !out_data)
2c1758
         return CKR_ARGUMENTS_BAD;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     /* Recreate the OpenSSL MD context from the saved context */
2c1758
     md_ctx = md_ctx_from_context(ctx);
2c1758
     if (md_ctx == NULL) {
2c1758
@@ -3275,21 +2964,38 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
 
2c1758
     if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len) ||
2c1758
         !EVP_DigestFinal(md_ctx, out_data, &len)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
     *out_data_len = len;
2c1758
+#else
2c1758
+    if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
2c1758
+        return CKR_BUFFER_TOO_SMALL;
2c1758
+    }
2c1758
+
2c1758
+    len = *out_data_len;
2c1758
+    if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len) ||
2c1758
+        !EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        return CKR_FUNCTION_FAILED;
2c1758
+    }
2c1758
+
2c1758
+    *out_data_len = len;
2c1758
+#endif
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
 out:
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
     EVP_MD_CTX_free(md_ctx);
2c1758
-#endif
2c1758
     free(ctx->context);
2c1758
+#else
2c1758
+    EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
2c1758
+#endif
2c1758
     ctx->context = NULL;
2c1758
     ctx->context_len = 0;
2c1758
+    ctx->context_free_func = NULL;
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
@@ -3297,7 +3003,9 @@ out:
2c1758
 CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
                                 CK_BYTE *in_data, CK_ULONG in_data_len)
2c1758
 {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     EVP_MD_CTX *md_ctx;
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
@@ -3307,6 +3015,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
     if (!in_data)
2c1758
         return CKR_ARGUMENTS_BAD;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     /* Recreate the OpenSSL MD context from the saved context */
2c1758
     md_ctx = md_ctx_from_context(ctx);
2c1758
     if (md_ctx == NULL) {
2c1758
@@ -3315,24 +3024,24 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
     }
2c1758
 
2c1758
     if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len)) {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-        EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
         EVP_MD_CTX_free(md_ctx);
2c1758
-#endif
2c1758
         free(ctx->context);
2c1758
         ctx->context = NULL;
2c1758
         ctx->context_len = 0;
2c1758
+        ctx->context_free_func = NULL;
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
         return CKR_FUNCTION_FAILED;
2c1758
     }
2c1758
 
2c1758
     /* Save context data for later use */
2c1758
     memcpy(ctx->context,  EVP_MD_CTX_md_data(md_ctx), ctx->context_len);
2c1758
 
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
     EVP_MD_CTX_free(md_ctx);
2c1758
+#else
2c1758
+    if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        return CKR_FUNCTION_FAILED;
2c1758
+    }
2c1758
 #endif
2c1758
 
2c1758
     return CKR_OK;
2c1758
@@ -3343,7 +3052,9 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
 {
2c1758
     unsigned int len;
2c1758
     CK_RV rc = CKR_OK;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     EVP_MD_CTX *md_ctx;
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
@@ -3353,6 +3064,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
     if (!out_data)
2c1758
         return CKR_ARGUMENTS_BAD;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     /* Recreate the OpenSSL MD context from the saved context */
2c1758
     md_ctx = md_ctx_from_context(ctx);
2c1758
     if (md_ctx == NULL) {
2c1758
@@ -3370,14 +3082,30 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
2c1758
     *out_data_len = len;
2c1758
 
2c1758
 out:
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    EVP_MD_CTX_destroy(md_ctx);
2c1758
-#else
2c1758
     EVP_MD_CTX_free(md_ctx);
2c1758
-#endif
2c1758
     free(ctx->context);
2c1758
     ctx->context = NULL;
2c1758
     ctx->context_len = 0;
2c1758
+    ctx->context_free_func = NULL;
2c1758
+#else
2c1758
+    if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
2c1758
+        return CKR_BUFFER_TOO_SMALL;
2c1758
+    }
2c1758
+
2c1758
+    len = *out_data_len;
2c1758
+    if (!EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) {
2c1758
+        TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+        return CKR_FUNCTION_FAILED;
2c1758
+    }
2c1758
+
2c1758
+    *out_data_len = len;
2c1758
+
2c1758
+    EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
2c1758
+    ctx->context = NULL;
2c1758
+    ctx->context_len = 0;
2c1758
+    ctx->context_free_func = NULL;
2c1758
+#endif
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
@@ -3897,99 +3625,26 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
                                CK_ULONG message_len, OBJECT *key, CK_BYTE *mac,
2c1758
                                CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
     int rc;
2c1758
-    CK_RV rv = CKR_OK;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    CK_KEY_TYPE keytype;
2c1758
-    CMAC_CTX *cmac_ctx;
2c1758
-    const EVP_CIPHER *cipher;
2c1758
-    size_t maclen;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    if (first) {
2c1758
-        // get the key type
2c1758
-        rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
2c1758
-        if (rc != CKR_OK) {
2c1758
-            TRACE_ERROR("Could not find CKA_KEY_TYPE for the key.\n");
2c1758
-            return CKR_FUNCTION_FAILED;
2c1758
-        }
2c1758
-
2c1758
-        // get the key value
2c1758
-        rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-        if (rc != CKR_OK) {
2c1758
-            TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
2c1758
-            return rc;
2c1758
-        }
2c1758
-        switch (keytype) {
2c1758
-        case CKK_DES2:
2c1758
-            cipher = EVP_des_ede_cbc();
2c1758
-            break;
2c1758
-        case CKK_DES3:
2c1758
-            cipher = EVP_des_ede3_cbc();
2c1758
-            break;
2c1758
-        default:
2c1758
-            TRACE_ERROR("Invalid key type: %lu\n", keytype);
2c1758
-            return CKR_KEY_TYPE_INCONSISTENT;
2c1758
-        }
2c1758
-        if (cipher == NULL) {
2c1758
-            TRACE_ERROR("Failed to allocate cipher\n");
2c1758
-            return CKR_HOST_MEMORY;
2c1758
-        }
2c1758
-
2c1758
-        cmac_ctx = CMAC_CTX_new();
2c1758
-        if (cmac_ctx == NULL) {
2c1758
-            TRACE_ERROR("Failed to allocate CMAC context\n");
2c1758
-            return CKR_HOST_MEMORY;
2c1758
-        }
2c1758
-
2c1758
-        rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL);
2c1758
-        if (rc != 1) {
2c1758
-            TRACE_ERROR("CMAC_Init failed\n");
2c1758
-            CMAC_CTX_free(cmac_ctx);
2c1758
-            return CKR_FUNCTION_FAILED;
2c1758
-        }
2c1758
-
2c1758
-        *ctx = cmac_ctx;
2c1758
-    }
2c1758
-
2c1758
-    cmac_ctx = (CMAC_CTX *)*ctx;
2c1758
-
2c1758
-    rc = CMAC_Update(cmac_ctx, message, message_len);
2c1758
-    if (rc != 1) {
2c1758
-        TRACE_ERROR("CMAC_Update failed\n");
2c1758
-        rv =  CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-
2c1758
-    if (last) {
2c1758
-        maclen = AES_BLOCK_SIZE;
2c1758
-        rc = CMAC_Final(cmac_ctx, mac, &maclen);
2c1758
-        if (rc != 1) {
2c1758
-            TRACE_ERROR("CMAC_Final failed\n");
2c1758
-            rv = CKR_FUNCTION_FAILED;
2c1758
-        }
2c1758
-    }
2c1758
-
2c1758
-    if (last || (first && rv != CKR_OK)) {
2c1758
-        CMAC_CTX_free(cmac_ctx);
2c1758
-        *ctx = NULL;
2c1758
-    }
2c1758
-
2c1758
-    return rv;
2c1758
-#else
2c1758
-    int rc;
2c1758
-    size_t maclen;
2c1758
+    size_t maclen;
2c1758
     CK_RV rv = CKR_OK;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
     CK_KEY_TYPE keytype;
2c1758
     const EVP_CIPHER *cipher;
2c1758
     struct cmac_ctx {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         EVP_MD_CTX *mctx;
2c1758
         EVP_PKEY_CTX *pctx;
2c1758
         EVP_PKEY *pkey;
2c1758
+#else
2c1758
+        EVP_MAC *mac;
2c1758
+        EVP_MAC_CTX *mctx;
2c1758
+#endif
2c1758
     };
2c1758
     struct cmac_ctx *cmac = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    OSSL_PARAM params[2];
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
@@ -4031,10 +3686,11 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
             goto err;
2c1758
         }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         cmac->mctx = EVP_MD_CTX_new();
2c1758
         if (cmac->mctx == NULL) {
2c1758
             TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
-            rv = ERR_HOST_MEMORY;
2c1758
+            rv = CKR_HOST_MEMORY;
2c1758
             goto err;
2c1758
         }
2c1758
 
2c1758
@@ -4053,6 +3709,31 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
             rv = CKR_FUNCTION_FAILED;
2c1758
             goto err;
2c1758
         }
2c1758
+#else
2c1758
+        cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
2c1758
+        if (cmac->mac == NULL) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+            rv = CKR_FUNCTION_FAILED;
2c1758
+            goto err;
2c1758
+        }
2c1758
+
2c1758
+        cmac->mctx = EVP_MAC_CTX_new(cmac->mac);
2c1758
+        if (cmac->mctx == NULL) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
+            rv = CKR_HOST_MEMORY;
2c1758
+            goto err;
2c1758
+        }
2c1758
+
2c1758
+        params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
2c1758
+                                      (char *)EVP_CIPHER_get0_name(cipher), 0);
2c1758
+        params[1] = OSSL_PARAM_construct_end();
2c1758
+
2c1758
+        if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+            rv = CKR_FUNCTION_FAILED;
2c1758
+            goto err;
2c1758
+        }
2c1758
+#endif
2c1758
 
2c1758
         *ctx = cmac;
2c1758
     }
2c1758
@@ -4064,9 +3745,17 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
         goto err;
2c1758
     }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len);
2c1758
+#else
2c1758
+    rc = EVP_MAC_update(cmac->mctx, message, message_len);
2c1758
+#endif
2c1758
     if (rc != 1 || message_len > INT_MAX) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         TRACE_ERROR("EVP_DigestSignUpdate failed\n");
2c1758
+#else
2c1758
+        TRACE_ERROR("EVP_MAC_update failed\n");
2c1758
+#endif
2c1758
         rv =  CKR_FUNCTION_FAILED;
2c1758
         goto err;
2c1758
     }
2c1758
@@ -4074,15 +3763,28 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
     if (last) {
2c1758
         maclen = AES_BLOCK_SIZE;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen);
2c1758
+#else
2c1758
+        rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen);
2c1758
+#endif
2c1758
         if (rc != 1) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
             TRACE_ERROR("EVP_DigestSignFinal failed\n");
2c1758
+#else
2c1758
+            TRACE_ERROR("EVP_MAC_final failed\n");
2c1758
+#endif
2c1758
             rv = CKR_FUNCTION_FAILED;
2c1758
             goto err;
2c1758
         }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
2c1758
         EVP_PKEY_free(cmac->pkey);
2c1758
+#else
2c1758
+        EVP_MAC_CTX_free(cmac->mctx);
2c1758
+        EVP_MAC_free(cmac->mac);
2c1758
+#endif
2c1758
         free(cmac);
2c1758
         *ctx = NULL;
2c1758
     }
2c1758
@@ -4090,15 +3792,21 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
     return CKR_OK;
2c1758
 err:
2c1758
     if (cmac != NULL) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         if (cmac->mctx != NULL)
2c1758
             EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
2c1758
         if (cmac->pkey != NULL)
2c1758
             EVP_PKEY_free(cmac->pkey);
2c1758
+#else
2c1758
+        if (cmac->mctx != NULL)
2c1758
+            EVP_MAC_CTX_free(cmac->mctx);
2c1758
+        if (cmac->mac != NULL)
2c1758
+            EVP_MAC_free(cmac->mac);
2c1758
+#endif
2c1758
         free(cmac);
2c1758
     }
2c1758
     *ctx = NULL;
2c1758
     return rv;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 
2c1758
@@ -4106,93 +3814,25 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
                               CK_ULONG message_len, OBJECT *key, CK_BYTE *mac,
2c1758
                               CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx)
2c1758
 {
2c1758
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
2c1758
-    int rc;
2c1758
-    CK_RV rv = CKR_OK;
2c1758
-    CK_ATTRIBUTE *attr = NULL;
2c1758
-    CMAC_CTX *cmac_ctx;
2c1758
-    const EVP_CIPHER *cipher;
2c1758
-    size_t maclen;
2c1758
-
2c1758
-    UNUSED(tokdata);
2c1758
-
2c1758
-    if (first) {
2c1758
-        rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
2c1758
-        if (rc != CKR_OK) {
2c1758
-            TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
2c1758
-            return rc;
2c1758
-        }
2c1758
-
2c1758
-        switch (attr->ulValueLen * 8) {
2c1758
-        case 128:
2c1758
-            cipher = EVP_aes_128_cbc();
2c1758
-            break;
2c1758
-        case 192:
2c1758
-            cipher = EVP_aes_192_cbc();
2c1758
-            break;
2c1758
-        case 256:
2c1758
-            cipher = EVP_aes_256_cbc();
2c1758
-            break;
2c1758
-        default:
2c1758
-            TRACE_ERROR("Invalid key size: %lu\n", attr->ulValueLen);
2c1758
-            return CKR_KEY_TYPE_INCONSISTENT;
2c1758
-        }
2c1758
-        if (cipher == NULL) {
2c1758
-            TRACE_ERROR("Failed to allocate cipher\n");
2c1758
-            return CKR_HOST_MEMORY;
2c1758
-        }
2c1758
-
2c1758
-        cmac_ctx = CMAC_CTX_new();
2c1758
-        if (cmac_ctx == NULL) {
2c1758
-            TRACE_ERROR("Failed to allocate CMAC context\n");
2c1758
-            return CKR_HOST_MEMORY;
2c1758
-        }
2c1758
-
2c1758
-        rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL);
2c1758
-        if (rc != 1) {
2c1758
-            TRACE_ERROR("CMAC_Init failed\n");
2c1758
-            CMAC_CTX_free(cmac_ctx);
2c1758
-            return CKR_FUNCTION_FAILED;
2c1758
-        }
2c1758
-
2c1758
-        *ctx = cmac_ctx;
2c1758
-    }
2c1758
-
2c1758
-    cmac_ctx = (CMAC_CTX *)*ctx;
2c1758
-
2c1758
-    rc = CMAC_Update(cmac_ctx, message, message_len);
2c1758
-    if (rc != 1) {
2c1758
-        TRACE_ERROR("CMAC_Update failed\n");
2c1758
-        rv =  CKR_FUNCTION_FAILED;
2c1758
-    }
2c1758
-
2c1758
-    if (last) {
2c1758
-        maclen = AES_BLOCK_SIZE;
2c1758
-        rc = CMAC_Final(cmac_ctx, mac, &maclen);
2c1758
-        if (rc != 1) {
2c1758
-            TRACE_ERROR("CMAC_Final failed\n");
2c1758
-            rv = CKR_FUNCTION_FAILED;
2c1758
-        }
2c1758
-    }
2c1758
-
2c1758
-    if (last || (first && rv != CKR_OK)) {
2c1758
-        CMAC_CTX_free(cmac_ctx);
2c1758
-        *ctx = NULL;
2c1758
-    }
2c1758
-
2c1758
-    return rv;
2c1758
-#else
2c1758
     int rc;
2c1758
     size_t maclen;
2c1758
     CK_RV rv = CKR_OK;
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
     const EVP_CIPHER *cipher;
2c1758
     struct cmac_ctx {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         EVP_MD_CTX *mctx;
2c1758
         EVP_PKEY_CTX *pctx;
2c1758
         EVP_PKEY *pkey;
2c1758
+#else
2c1758
+        EVP_MAC *mac;
2c1758
+        EVP_MAC_CTX *mctx;
2c1758
+#endif
2c1758
     };
2c1758
     struct cmac_ctx *cmac = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    OSSL_PARAM params[2];
2c1758
+#endif
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
@@ -4229,6 +3869,7 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
             goto err;
2c1758
         }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         cmac->mctx = EVP_MD_CTX_new();
2c1758
         if (cmac->mctx == NULL) {
2c1758
             TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
@@ -4251,6 +3892,31 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
             rv = CKR_FUNCTION_FAILED;
2c1758
             goto err;
2c1758
         }
2c1758
+#else
2c1758
+        cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
2c1758
+        if (cmac->mac == NULL) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+            rv = CKR_FUNCTION_FAILED;
2c1758
+            goto err;
2c1758
+        }
2c1758
+
2c1758
+        cmac->mctx = EVP_MAC_CTX_new(cmac->mac);
2c1758
+        if (cmac->mctx == NULL) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2c1758
+            rv = CKR_HOST_MEMORY;
2c1758
+            goto err;
2c1758
+        }
2c1758
+
2c1758
+        params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
2c1758
+                                      (char *)EVP_CIPHER_get0_name(cipher), 0);
2c1758
+        params[1] = OSSL_PARAM_construct_end();
2c1758
+
2c1758
+        if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) {
2c1758
+            TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2c1758
+            rv = CKR_FUNCTION_FAILED;
2c1758
+            goto err;
2c1758
+        }
2c1758
+#endif
2c1758
 
2c1758
         *ctx = cmac;
2c1758
     }
2c1758
@@ -4262,9 +3928,17 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
         goto err;
2c1758
     }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len);
2c1758
+#else
2c1758
+    rc = EVP_MAC_update(cmac->mctx, message, message_len);
2c1758
+#endif
2c1758
     if (rc != 1 || message_len > INT_MAX) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         TRACE_ERROR("EVP_DigestSignUpdate failed\n");
2c1758
+#else
2c1758
+        TRACE_ERROR("EVP_MAC_update failed\n");
2c1758
+#endif
2c1758
         rv =  CKR_FUNCTION_FAILED;
2c1758
         goto err;
2c1758
     }
2c1758
@@ -4272,15 +3946,28 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
     if (last) {
2c1758
         maclen = AES_BLOCK_SIZE;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen);
2c1758
+#else
2c1758
+        rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen);
2c1758
+#endif
2c1758
         if (rc != 1) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
             TRACE_ERROR("EVP_DigestSignFinal failed\n");
2c1758
+#else
2c1758
+            TRACE_ERROR("EVP_MAC_final failed\n");
2c1758
+#endif
2c1758
             rv = CKR_FUNCTION_FAILED;
2c1758
             goto err;
2c1758
         }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
2c1758
         EVP_PKEY_free(cmac->pkey);
2c1758
+#else
2c1758
+        EVP_MAC_CTX_free(cmac->mctx);
2c1758
+        EVP_MAC_free(cmac->mac);
2c1758
+#endif
2c1758
         free(cmac);
2c1758
         *ctx = NULL;
2c1758
     }
2c1758
@@ -4288,37 +3975,90 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
2c1758
     return CKR_OK;
2c1758
 err:
2c1758
     if (cmac != NULL) {
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         if (cmac->mctx != NULL)
2c1758
             EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
2c1758
         if (cmac->pkey != NULL)
2c1758
             EVP_PKEY_free(cmac->pkey);
2c1758
+#else
2c1758
+        if (cmac->mctx != NULL)
2c1758
+            EVP_MAC_CTX_free(cmac->mctx);
2c1758
+        if (cmac->mac != NULL)
2c1758
+            EVP_MAC_free(cmac->mac);
2c1758
+#endif
2c1758
         free(cmac);
2c1758
     }
2c1758
     *ctx = NULL;
2c1758
     return rv;
2c1758
-#endif
2c1758
 }
2c1758
 
2c1758
 #ifndef NO_EC
2c1758
 
2c1758
-static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
2c1758
-                                     EC_KEY **key)
2c1758
+static int curve_nid_from_params(const CK_BYTE *params, CK_ULONG params_len)
2c1758
 {
2c1758
     const unsigned char *oid;
2c1758
     ASN1_OBJECT *obj = NULL;
2c1758
-    EC_KEY *ec_key = NULL;
2c1758
     int nid;
2c1758
-    CK_RV rc = CKR_OK;
2c1758
 
2c1758
     oid = params;
2c1758
     obj = d2i_ASN1_OBJECT(NULL, &oid, params_len);
2c1758
     if (obj == NULL) {
2c1758
         TRACE_ERROR("curve not supported by OpenSSL.\n");
2c1758
-        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
-        goto out;
2c1758
+        return NID_undef;
2c1758
     }
2c1758
 
2c1758
     nid = OBJ_obj2nid(obj);
2c1758
+    ASN1_OBJECT_free(obj);
2c1758
+
2c1758
+    return nid;
2c1758
+}
2c1758
+
2c1758
+static int ec_prime_len_from_nid(int nid)
2c1758
+{
2c1758
+    EC_GROUP *group;
2c1758
+    int primelen;
2c1758
+
2c1758
+    group = EC_GROUP_new_by_curve_name(nid);
2c1758
+    if (group == NULL)
2c1758
+        return -1;
2c1758
+
2c1758
+    primelen = EC_GROUP_order_bits(group);
2c1758
+
2c1758
+    EC_GROUP_free(group);
2c1758
+
2c1758
+    if ((primelen % 8) == 0)
2c1758
+        return primelen / 8;
2c1758
+    else
2c1758
+        return (primelen / 8) + 1;
2c1758
+}
2c1758
+
2c1758
+int ec_prime_len_from_pkey(EVP_PKEY *pkey)
2c1758
+{
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    return (EC_GROUP_order_bits(EC_KEY_get0_group(
2c1758
+                             EVP_PKEY_get0_EC_KEY(pkey))) + 7) / 8;
2c1758
+#else
2c1758
+    size_t curve_len;
2c1758
+    char curve[80];
2c1758
+
2c1758
+    if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
2c1758
+                                        curve, sizeof(curve), &curve_len))
2c1758
+        return -1;
2c1758
+
2c1758
+    return ec_prime_len_from_nid(OBJ_sn2nid(curve));
2c1758
+#endif
2c1758
+}
2c1758
+
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
2c1758
+                                     EC_KEY **key)
2c1758
+{
2c1758
+    EC_KEY *ec_key = NULL;
2c1758
+    int nid;
2c1758
+    CK_RV rc = CKR_OK;
2c1758
+
2c1758
+    nid = curve_nid_from_params(params, params_len);
2c1758
     if (nid == NID_undef) {
2c1758
         TRACE_ERROR("curve not supported by OpenSSL.\n");
2c1758
         rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
@@ -4333,9 +4073,6 @@ static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
2c1758
     }
2c1758
 
2c1758
 out:
2c1758
-    if (obj != NULL)
2c1758
-        ASN1_OBJECT_free(obj);
2c1758
-
2c1758
     if (rc != CKR_OK) {
2c1758
         if (ec_key != NULL)
2c1758
             EC_KEY_free(ec_key);
2c1758
@@ -4347,16 +4084,97 @@ out:
2c1758
 
2c1758
     return CKR_OK;
2c1758
 }
2c1758
+#endif
2c1758
+
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+static CK_RV build_pkey_from_params(OSSL_PARAM_BLD *tmpl, int selection,
2c1758
+                                    EVP_PKEY **pkey)
2c1758
+{
2c1758
+
2c1758
+    OSSL_PARAM *params = NULL;
2c1758
+    EVP_PKEY_CTX *pctx = NULL;
2c1758
+    CK_RV rc = CKR_OK;
2c1758
+
2c1758
+    params = OSSL_PARAM_BLD_to_param(tmpl);
2c1758
+    if (params == NULL) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_to_param failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
2c1758
+    if (pctx == NULL) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_new_id failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!EVP_PKEY_fromdata_init(pctx) ||
2c1758
+        !EVP_PKEY_fromdata(pctx, pkey, selection, params)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_fromdata failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    EVP_PKEY_CTX_free(pctx);
2c1758
+    pctx = EVP_PKEY_CTX_new(*pkey, NULL);
2c1758
+    if (pctx == NULL) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
2c1758
+        if (EVP_PKEY_check(pctx) != 1) {
2c1758
+            TRACE_ERROR("EVP_PKEY_check failed\n");
2c1758
+            rc = CKR_FUNCTION_FAILED;
2c1758
+            goto out;
2c1758
+        }
2c1758
+    } else {
2c1758
+        if (EVP_PKEY_public_check(pctx) != 1) {
2c1758
+            TRACE_ERROR("EVP_PKEY_public_check failed\n");
2c1758
+            rc = CKR_FUNCTION_FAILED;
2c1758
+            goto out;
2c1758
+        }
2c1758
+    }
2c1758
+
2c1758
+out:
2c1758
+    if (pctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(pctx);
2c1758
+    if (params != NULL)
2c1758
+        OSSL_PARAM_free(params);
2c1758
+
2c1758
+    if (rc != 0 && *pkey != NULL) {
2c1758
+        EVP_PKEY_free(*pkey);
2c1758
+        *pkey = NULL;
2c1758
+    }
2c1758
+
2c1758
+    return rc;
2c1758
+}
2c1758
+#endif
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
 static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
2c1758
-                                     CK_ULONG data_len, CK_BBOOL allow_raw)
2c1758
+                                     CK_ULONG data_len, CK_BBOOL allow_raw,
2c1758
+                                     int nid, EVP_PKEY **ec_pkey)
2c1758
+#else
2c1758
+static CK_RV fill_ec_key_from_pubkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data,
2c1758
+                                     CK_ULONG data_len, CK_BBOOL allow_raw,
2c1758
+                                     int nid, EVP_PKEY **ec_pkey)
2c1758
+#endif
2c1758
 {
2c1758
     CK_BYTE *ecpoint = NULL;
2c1758
     CK_ULONG ecpoint_len, privlen;
2c1758
     CK_BBOOL allocated = FALSE;
2c1758
+
2c1758
     CK_RV rc;
2c1758
 
2c1758
-    privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
2c1758
+    privlen = ec_prime_len_from_nid(nid);
2c1758
+    if (privlen <= 0) {
2c1758
+        TRACE_ERROR("ec_prime_len_from_nid failed\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
+        goto out;
2c1758
+    }
2c1758
 
2c1758
     rc = ec_point_from_public_data(data, data_len, privlen, allow_raw,
2c1758
                                    &allocated, &ecpoint, &ecpoint_len);
2c1758
@@ -4365,6 +4183,7 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     if (!EC_KEY_oct2key(ec_key, ecpoint, ecpoint_len, NULL)) {
2c1758
         TRACE_ERROR("EC_KEY_oct2key failed\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
@@ -4377,6 +4196,34 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+    *ec_pkey = EVP_PKEY_new();
2c1758
+    if (*ec_pkey == NULL) {
2c1758
+       TRACE_ERROR("EVP_PKEY_CTX_new failed.\n");
2c1758
+       rc = CKR_HOST_MEMORY;
2c1758
+       goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#else
2c1758
+    if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
2c1758
+                                          OSSL_PKEY_PARAM_PUB_KEY,
2c1758
+                                          ecpoint, ecpoint_len)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    rc = build_pkey_from_params(tmpl, EVP_PKEY_PUBLIC_KEY, ec_pkey);
2c1758
+    if (rc != CKR_OK) {
2c1758
+        TRACE_ERROR("build_pkey_from_params failed\n");
2c1758
+        goto out;
2c1758
+    }
2c1758
+ #endif
2c1758
+
2c1758
 out:
2c1758
     if (allocated && ecpoint != NULL)
2c1758
         free(ecpoint);
2c1758
@@ -4384,12 +4231,26 @@ out:
2c1758
     return rc;
2c1758
 }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
 static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data,
2c1758
-                                      CK_ULONG data_len)
2c1758
+                                      CK_ULONG data_len, EVP_PKEY **ec_pkey)
2c1758
+#else
2c1758
+static CK_RV fill_ec_key_from_privkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data,
2c1758
+                                      CK_ULONG data_len, int nid,
2c1758
+                                      EVP_PKEY **ec_pkey)
2c1758
+#endif
2c1758
 {
2c1758
     EC_POINT *point = NULL;
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    EC_GROUP *group = NULL;
2c1758
+    BIGNUM *bn_priv = NULL;
2c1758
+    unsigned char *pub_key = NULL;
2c1758
+    unsigned int pub_key_len;
2c1758
+    point_conversion_form_t form;
2c1758
+#endif
2c1758
     CK_RV rc = CKR_OK;
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     if (!EC_KEY_oct2priv(ec_key, data, data_len)) {
2c1758
         TRACE_ERROR("EC_KEY_oct2priv failed\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
@@ -4422,18 +4283,102 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data,
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+    *ec_pkey = EVP_PKEY_new();
2c1758
+    if (*ec_pkey == NULL) {
2c1758
+       TRACE_ERROR("EVP_PKEY_CTX_new failed.\n");
2c1758
+       rc = CKR_HOST_MEMORY;
2c1758
+       goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#else
2c1758
+    group = EC_GROUP_new_by_curve_name(nid);
2c1758
+    if (group == NULL) {
2c1758
+        TRACE_ERROR("EC_GROUP_new_by_curve_name failed\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    point = EC_POINT_new(group);
2c1758
+    if (point == NULL) {
2c1758
+        TRACE_ERROR("EC_POINT_new failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    bn_priv = BN_bin2bn(data, data_len, NULL);
2c1758
+    if (bn_priv == NULL) {
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!EC_POINT_mul(group, point, bn_priv, NULL, NULL, NULL)) {
2c1758
+        TRACE_ERROR("EC_POINT_mul failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    form = EC_GROUP_get_point_conversion_form(group);
2c1758
+    pub_key_len = EC_POINT_point2buf(group, point, form, &pub_key,
2c1758
+                                     NULL);
2c1758
+    if (pub_key_len == 0) {
2c1758
+        TRACE_ERROR("EC_POINT_point2buf failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
2c1758
+                                          pub_key, pub_key_len)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, bn_priv)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_BN failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    rc = build_pkey_from_params(tmpl, EVP_PKEY_KEYPAIR, ec_pkey);
2c1758
+    if (rc != CKR_OK) {
2c1758
+        TRACE_ERROR("build_pkey_from_params failed\n");
2c1758
+        goto out;
2c1758
+    }
2c1758
+#endif
2c1758
+
2c1758
 out:
2c1758
     if (point != NULL)
2c1758
         EC_POINT_free(point);
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (group != NULL)
2c1758
+        EC_GROUP_free(group);
2c1758
+    if (bn_priv != NULL)
2c1758
+        BN_free(bn_priv);
2c1758
+    if (pub_key != NULL)
2c1758
+        OPENSSL_free(pub_key);
2c1758
+#endif
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
 
2c1758
-static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
2c1758
+
2c1758
+
2c1758
+static CK_RV make_ec_key_from_template(TEMPLATE *template, EVP_PKEY **pkey)
2c1758
 {
2c1758
     CK_ATTRIBUTE *attr = NULL;
2c1758
     CK_OBJECT_CLASS keyclass;
2c1758
+    EVP_PKEY *ec_pkey = NULL;
2c1758
+    int nid;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     EC_KEY *ec_key = NULL;
2c1758
+#else
2c1758
+    OSSL_PARAM_BLD *tmpl = NULL;
2c1758
+#endif
2c1758
     CK_RV rc;
2c1758
 
2c1758
     rc = template_attribute_get_ulong(template, CKA_CLASS, &keyclass);
2c1758
@@ -4448,9 +4393,32 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+    nid = curve_nid_from_params(attr->pValue, attr->ulValueLen);
2c1758
+    if (nid == NID_undef) {
2c1758
+        TRACE_ERROR("curve not supported by OpenSSL.\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key);
2c1758
     if (rc != CKR_OK)
2c1758
         goto out;
2c1758
+#else
2c1758
+    tmpl = OSSL_PARAM_BLD_new();
2c1758
+    if (tmpl == NULL) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
2c1758
+                                         OBJ_nid2sn(nid), 0)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#endif
2c1758
 
2c1758
     switch (keyclass) {
2c1758
     case CKO_PUBLIC_KEY:
2c1758
@@ -4460,8 +4428,13 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
2c1758
             goto out;
2c1758
         }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         rc = fill_ec_key_from_pubkey(ec_key, attr->pValue, attr->ulValueLen,
2c1758
-                                     FALSE);
2c1758
+                                     FALSE, nid, &ec_pkey);
2c1758
+#else
2c1758
+        rc = fill_ec_key_from_pubkey(tmpl, attr->pValue, attr->ulValueLen,
2c1758
+                                     FALSE, nid, &ec_pkey);
2c1758
+#endif
2c1758
         if (rc != CKR_OK) {
2c1758
             TRACE_DEVEL("fill_ec_key_from_pubkey failed\n");
2c1758
             goto out;
2c1758
@@ -4475,7 +4448,14 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
2c1758
             goto out;
2c1758
         }
2c1758
 
2c1758
-        rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+        rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen,
2c1758
+                                      &ec_pkey);
2c1758
+#else
2c1758
+        rc = fill_ec_key_from_privkey(tmpl, attr->pValue, attr->ulValueLen,
2c1758
+                                      nid, &ec_pkey);
2c1758
+
2c1758
+#endif
2c1758
         if (rc != CKR_OK) {
2c1758
             TRACE_DEVEL("fill_ec_key_from_privkey failed\n");
2c1758
             goto out;
2c1758
@@ -4487,17 +4467,30 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    ec_key = NULL;
2c1758
+#endif
2c1758
+
2c1758
     rc = CKR_OK;
2c1758
 
2c1758
 out:
2c1758
+#if OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (tmpl != NULL)
2c1758
+        OSSL_PARAM_BLD_free(tmpl);
2c1758
+#endif
2c1758
+
2c1758
     if (rc != CKR_OK) {
2c1758
+        if (ec_pkey != NULL)
2c1758
+            EVP_PKEY_free(ec_pkey);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
         if (ec_key != NULL)
2c1758
             EC_KEY_free(ec_key);
2c1758
+#endif
2c1758
 
2c1758
         return rc;
2c1758
     }
2c1758
 
2c1758
-    *key = ec_key;
2c1758
+    *pkey = ec_pkey;
2c1758
 
2c1758
     return CKR_OK;
2c1758
 }
2c1758
@@ -4508,10 +4501,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
2c1758
 {
2c1758
 
2c1758
     CK_ATTRIBUTE *attr = NULL, *ec_point_attr, *value_attr, *parms_attr;
2c1758
-    EC_KEY *ec_key = NULL;
2c1758
-    BN_CTX *ctx = NULL;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    const EC_KEY *ec_key = NULL;
2c1758
+    BN_CTX *bnctx = NULL;
2c1758
+#else
2c1758
+    BIGNUM *bn_d = NULL;
2c1758
+#endif
2c1758
     CK_BYTE *ecpoint = NULL, *enc_ecpoint = NULL, *d = NULL;
2c1758
     CK_ULONG ecpoint_len, enc_ecpoint_len, d_len;
2c1758
+    EVP_PKEY_CTX *ctx = NULL;
2c1758
+    EVP_PKEY *ec_pkey = NULL;
2c1758
+    int nid;
2c1758
     CK_RV rc;
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
@@ -4520,29 +4520,83 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
2c1758
     if (rc != CKR_OK)
2c1758
         goto out;
2c1758
 
2c1758
-    rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key);
2c1758
-    if (rc != CKR_OK)
2c1758
+    nid = curve_nid_from_params(attr->pValue, attr->ulValueLen);
2c1758
+    if (nid == NID_undef) {
2c1758
+        TRACE_ERROR("curve not supported by OpenSSL.\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
         goto out;
2c1758
+    }
2c1758
 
2c1758
-    if (!EC_KEY_generate_key(ec_key)) {
2c1758
-        TRACE_ERROR("Failed to generate an EC key.\n");
2c1758
+    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
2c1758
+    if (ctx == NULL) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
-    ctx = BN_CTX_new();
2c1758
-    if (ctx == NULL) {
2c1758
+    if (EVP_PKEY_keygen_init(ctx) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_keygen_init failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_set_ec_paramgen_curve_nid failed\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_keygen(ctx, &ec_pkey) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_keygen failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    ec_key = EVP_PKEY_get0_EC_KEY(ec_pkey);
2c1758
+    if (ec_key == NULL) {
2c1758
+       TRACE_ERROR("EVP_PKEY_get0_EC_KEY failed\n");
2c1758
+       rc = CKR_FUNCTION_FAILED;
2c1758
+       goto out;
2c1758
+   }
2c1758
+
2c1758
+    bnctx = BN_CTX_new();
2c1758
+    if (bnctx == NULL) {
2c1758
         rc = CKR_HOST_MEMORY;
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
     ecpoint_len = EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED,
2c1758
-                                 &ecpoint, ctx);
2c1758
+                                 &ecpoint, bnctx);
2c1758
     if (ecpoint_len == 0) {
2c1758
         TRACE_ERROR("Failed to get the EC Point compressed.\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto out;
2c1758
     }
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_octet_string_param(ec_pkey,
2c1758
+                                         OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
2c1758
+                                         NULL, 0, &ecpoint_len)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    ecpoint = OPENSSL_zalloc(ecpoint_len);
2c1758
+    if (ecpoint == NULL) {
2c1758
+        TRACE_ERROR("OPENSSL_zalloc failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!EVP_PKEY_get_octet_string_param(ec_pkey,
2c1758
+                                         OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
2c1758
+                                         ecpoint, ecpoint_len, &ecpoint_len)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#endif
2c1758
 
2c1758
     rc = ber_encode_OCTET_STRING(FALSE, &enc_ecpoint, &enc_ecpoint_len,
2c1758
                                  ecpoint, ecpoint_len);
2c1758
@@ -4564,12 +4618,30 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
     d_len = EC_KEY_priv2buf(ec_key, &d);
2c1758
     if (d_len == 0) {
2c1758
         TRACE_ERROR("Failed to get the EC private key.\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto out;
2c1758
     }
2c1758
+#else
2c1758
+    if (!EVP_PKEY_get_bn_param(ec_pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn_d)) {
2c1758
+        TRACE_ERROR("EVP_PKEY_get_bn_param failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    d_len = ec_prime_len_from_nid(nid);
2c1758
+    d = OPENSSL_zalloc(d_len);
2c1758
+    if (d == NULL) {
2c1758
+        TRACE_ERROR("OPENSSL_zalloc failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    BN_bn2binpad(bn_d, d, d_len);
2c1758
+#endif
2c1758
 
2c1758
     rc = build_attribute(CKA_VALUE, d, d_len, &value_attr);
2c1758
     if (rc != CKR_OK) {
2c1758
@@ -4602,10 +4674,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
2c1758
     rc = CKR_OK;
2c1758
 
2c1758
 out:
2c1758
-    if (ctx)
2c1758
-        BN_CTX_free(ctx);
2c1758
-    if (ec_key != NULL)
2c1758
-        EC_KEY_free(ec_key);
2c1758
+    if (ctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(ctx);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (bnctx != NULL)
2c1758
+        BN_CTX_free(bnctx);
2c1758
+#else
2c1758
+    if (bn_d != NULL)
2c1758
+        BN_free(bn_d);
2c1758
+#endif
2c1758
+    if (ec_pkey != NULL)
2c1758
+        EVP_PKEY_free(ec_pkey);
2c1758
     if (ecpoint != NULL)
2c1758
         OPENSSL_free(ecpoint);
2c1758
     if (enc_ecpoint != NULL)
2c1758
@@ -4621,11 +4700,15 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata,  SESSION *sess,
2c1758
                              CK_BYTE *out_data, CK_ULONG *out_data_len,
2c1758
                              OBJECT *key_obj)
2c1758
 {
2c1758
-    EC_KEY *ec_key;
2c1758
-    ECDSA_SIG *sig;
2c1758
+    EVP_PKEY *ec_key;
2c1758
+    ECDSA_SIG *sig = NULL;
2c1758
     const BIGNUM *r, *s;
2c1758
     CK_ULONG privlen, n;
2c1758
     CK_RV rc = CKR_OK;
2c1758
+    EVP_PKEY_CTX *ctx = NULL;
2c1758
+    size_t siglen;
2c1758
+    CK_BYTE *sigbuf = NULL;
2c1758
+    const unsigned char *p;
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
     UNUSED(sess);
2c1758
@@ -4636,16 +4719,54 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata,  SESSION *sess,
2c1758
     if (rc != CKR_OK)
2c1758
         return rc;
2c1758
 
2c1758
-    sig = ECDSA_do_sign(in_data, in_data_len, ec_key);
2c1758
+    ctx = EVP_PKEY_CTX_new(ec_key, NULL);
2c1758
+    if (ctx == NULL) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_sign_init(ctx) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_sign_init failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_sign(ctx, NULL, &siglen, in_data, in_data_len) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_sign failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    sigbuf = malloc(siglen);
2c1758
+    if (sigbuf == NULL) {
2c1758
+        TRACE_ERROR("malloc failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_sign(ctx, sigbuf, &siglen, in_data, in_data_len) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_sign failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    p = sigbuf;
2c1758
+    sig = d2i_ECDSA_SIG(NULL, &p, siglen);
2c1758
     if (sig == NULL) {
2c1758
-        TRACE_ERROR("ECDSA_do_sign failed\n");
2c1758
+        TRACE_ERROR("d2i_ECDSA_SIG failed\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
     ECDSA_SIG_get0(sig, &r, &s);
2c1758
 
2c1758
-    privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
2c1758
+    privlen = ec_prime_len_from_pkey(ec_key);
2c1758
+    if (privlen <= 0) {
2c1758
+        TRACE_ERROR("ec_prime_len_from_pkey failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
 
2c1758
     /* Insert leading 0x00's if r or s shorter than privlen */
2c1758
     n = privlen - BN_num_bytes(r);
2c1758
@@ -4662,7 +4783,11 @@ out:
2c1758
     if (sig != NULL)
2c1758
         ECDSA_SIG_free(sig);
2c1758
     if (ec_key != NULL)
2c1758
-        EC_KEY_free(ec_key);
2c1758
+        EVP_PKEY_free(ec_key);
2c1758
+    if (sigbuf != NULL)
2c1758
+        free(sigbuf);
2c1758
+    if (ctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(ctx);
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
@@ -4674,11 +4799,14 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
2c1758
                                CK_BYTE *signature,
2c1758
                                CK_ULONG signature_len, OBJECT *key_obj)
2c1758
 {
2c1758
-    EC_KEY *ec_key;
2c1758
+    EVP_PKEY *ec_key;
2c1758
     CK_ULONG privlen;
2c1758
     ECDSA_SIG *sig = NULL;
2c1758
     BIGNUM *r = NULL, *s = NULL;
2c1758
     CK_RV rc = CKR_OK;
2c1758
+    size_t siglen;
2c1758
+    CK_BYTE *sigbuf = NULL;
2c1758
+    EVP_PKEY_CTX *ctx = NULL;
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
     UNUSED(sess);
2c1758
@@ -4687,7 +4815,12 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
2c1758
     if (rc != CKR_OK)
2c1758
         return rc;
2c1758
 
2c1758
-    privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
2c1758
+    privlen = ec_prime_len_from_pkey(ec_key);
2c1758
+    if (privlen <= 0) {
2c1758
+        TRACE_ERROR("ec_prime_len_from_pkey failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
 
2c1758
     if (signature_len < 2 * privlen) {
2c1758
         TRACE_ERROR("Signature is too short\n");
2c1758
@@ -4715,7 +4848,27 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
2c1758
         goto out;
2c1758
     }
2c1758
 
2c1758
-    rc = ECDSA_do_verify(in_data, in_data_len, sig, ec_key);
2c1758
+    siglen = i2d_ECDSA_SIG(sig, &sigbuf);
2c1758
+    if (siglen <= 0) {
2c1758
+        TRACE_ERROR("i2d_ECDSA_SIG failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    ctx = EVP_PKEY_CTX_new(ec_key, NULL);
2c1758
+    if (ctx == NULL) {
2c1758
+        TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (EVP_PKEY_verify_init(ctx) <= 0) {
2c1758
+        TRACE_ERROR("EVP_PKEY_verify_init failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    rc = EVP_PKEY_verify(ctx, sigbuf, siglen, in_data, in_data_len);
2c1758
     switch (rc) {
2c1758
     case 0:
2c1758
         rc = CKR_SIGNATURE_INVALID;
2c1758
@@ -4732,7 +4885,11 @@ out:
2c1758
     if (sig != NULL)
2c1758
         ECDSA_SIG_free(sig);
2c1758
     if (ec_key != NULL)
2c1758
-        EC_KEY_free(ec_key);
2c1758
+        EVP_PKEY_free(ec_key);
2c1758
+    if (sigbuf != NULL)
2c1758
+        OPENSSL_free(sigbuf);
2c1758
+    if (ctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(ctx);
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
@@ -4746,43 +4903,118 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata,
2c1758
                                       CK_ULONG *secret_value_len,
2c1758
                                       CK_BYTE *oid, CK_ULONG oid_length)
2c1758
 {
2c1758
-    EC_KEY *ec_pub = NULL, *ec_priv = NULL;
2c1758
-    CK_ULONG privlen;
2c1758
-    int secret_len;
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    EC_KEY *pub = NULL, *priv = NULL;
2c1758
+#else
2c1758
+    OSSL_PARAM_BLD *tmpl = NULL;
2c1758
+#endif
2c1758
+    EVP_PKEY *ec_pub = NULL, *ec_priv = NULL;
2c1758
+    EVP_PKEY_CTX *ctx = NULL;
2c1758
+    size_t secret_len;
2c1758
+    int nid;
2c1758
     CK_RV rc;
2c1758
 
2c1758
     UNUSED(tokdata);
2c1758
 
2c1758
-    rc = make_ec_key_from_params(oid, oid_length, &ec_priv);
2c1758
+    nid = curve_nid_from_params(oid, oid_length);
2c1758
+    if (nid == NID_undef) {
2c1758
+        TRACE_ERROR("curve not supported by OpenSSL.\n");
2c1758
+        rc = CKR_CURVE_NOT_SUPPORTED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    rc = make_ec_key_from_params(oid, oid_length, &priv;;
2c1758
     if (rc != CKR_OK) {
2c1758
         TRACE_DEVEL("make_ec_key_from_params failed\n");
2c1758
         goto out;
2c1758
     }
2c1758
+#else
2c1758
+    tmpl = OSSL_PARAM_BLD_new();
2c1758
+    if (tmpl == NULL) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
2c1758
+                                         OBJ_nid2sn(nid), 0)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#endif
2c1758
 
2c1758
-    rc = fill_ec_key_from_privkey(ec_priv, priv_bytes, priv_length);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    rc = fill_ec_key_from_privkey(priv, priv_bytes, priv_length, &ec_priv);
2c1758
+#else
2c1758
+    rc = fill_ec_key_from_privkey(tmpl, priv_bytes, priv_length, nid, &ec_priv);
2c1758
+#endif
2c1758
     if (rc != CKR_OK) {
2c1758
         TRACE_DEVEL("fill_ec_key_from_privkey failed\n");
2c1758
         goto out;
2c1758
     }
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    priv = NULL;
2c1758
+#else
2c1758
+    OSSL_PARAM_BLD_free(tmpl);
2c1758
+    tmpl = NULL;
2c1758
+#endif
2c1758
 
2c1758
-    rc = make_ec_key_from_params(oid, oid_length, &ec_pub);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    rc = make_ec_key_from_params(oid, oid_length, &pub;;
2c1758
     if (rc != CKR_OK) {
2c1758
         TRACE_DEVEL("make_ec_key_from_params failed\n");
2c1758
         goto out;
2c1758
     }
2c1758
+#else
2c1758
+    tmpl = OSSL_PARAM_BLD_new();
2c1758
+    if (tmpl == NULL) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
2c1758
+        rc = CKR_HOST_MEMORY;
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
2c1758
+                                         OBJ_nid2sn(nid), 0)) {
2c1758
+        TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
2c1758
+        rc = CKR_FUNCTION_FAILED;
2c1758
+        goto out;
2c1758
+    }
2c1758
+#endif
2c1758
 
2c1758
-    rc = fill_ec_key_from_pubkey(ec_pub, pub_bytes, pub_length, TRUE);
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    rc = fill_ec_key_from_pubkey(pub, pub_bytes, pub_length, TRUE, nid,
2c1758
+                                 &ec_pub);
2c1758
+#else
2c1758
+    rc = fill_ec_key_from_pubkey(tmpl, pub_bytes, pub_length, TRUE, nid,
2c1758
+                                 &ec_pub);
2c1758
+#endif
2c1758
     if (rc != CKR_OK) {
2c1758
         TRACE_DEVEL("fill_ec_key_from_pubkey failed\n");
2c1758
         goto out;
2c1758
     }
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    pub = NULL;
2c1758
+#else
2c1758
+    OSSL_PARAM_BLD_free(tmpl);
2c1758
+    tmpl = NULL;
2c1758
+#endif
2c1758
 
2c1758
-    privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_priv)) + 7) / 8;
2c1758
+    ctx = EVP_PKEY_CTX_new(ec_priv, NULL);
2c1758
+    if (ctx == NULL) {
2c1758
+        TRACE_DEVEL("EVP_PKEY_CTX_new failed\n");
2c1758
+        goto out;
2c1758
+    }
2c1758
 
2c1758
-    secret_len = ECDH_compute_key(secret_value, privlen,
2c1758
-                                  EC_KEY_get0_public_key(ec_pub), ec_priv,
2c1758
-                                  NULL);
2c1758
-    if (secret_len <= 0) {
2c1758
+    if (EVP_PKEY_derive_init(ctx) <= 0 ||
2c1758
+        EVP_PKEY_derive_set_peer(ctx, ec_pub) <= 0) {
2c1758
+        TRACE_DEVEL("EVP_PKEY_derive_init/EVP_PKEY_derive_set_peer failed\n");
2c1758
+        goto out;
2c1758
+    }
2c1758
+
2c1758
+    secret_len = ec_prime_len_from_nid(nid);
2c1758
+    if (EVP_PKEY_derive(ctx, secret_value, &secret_len) <= 0) {
2c1758
         TRACE_DEVEL("ECDH_compute_key failed\n");
2c1758
         rc = CKR_FUNCTION_FAILED;
2c1758
         *secret_value_len = 0;
2c1758
@@ -4792,10 +5024,21 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata,
2c1758
     *secret_value_len = secret_len;
2c1758
 
2c1758
 out:
2c1758
+#if !OPENSSL_VERSION_PREREQ(3, 0)
2c1758
+    if (priv != NULL)
2c1758
+        EC_KEY_free(priv);
2c1758
+    if (pub != NULL)
2c1758
+        EC_KEY_free(pub);
2c1758
+#else
2c1758
+    if (tmpl != NULL)
2c1758
+        OSSL_PARAM_BLD_free(tmpl);
2c1758
+#endif
2c1758
     if (ec_priv != NULL)
2c1758
-        EC_KEY_free(ec_priv);
2c1758
+        EVP_PKEY_free(ec_priv);
2c1758
     if (ec_pub != NULL)
2c1758
-        EC_KEY_free(ec_pub);
2c1758
+        EVP_PKEY_free(ec_pub);
2c1758
+    if (ctx != NULL)
2c1758
+        EVP_PKEY_CTX_free(ctx);
2c1758
 
2c1758
     return rc;
2c1758
 }
2c1758
@@ -4807,7 +5050,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
2c1758
 {
2c1758
     CK_KEY_TYPE keytype;
2c1758
 #ifndef NO_EC
2c1758
-    EC_KEY *ec_key = NULL;
2c1758
+    EVP_PKEY *ec_key = NULL;
2c1758
 #endif
2c1758
     CK_RV rc;
2c1758
 
2c1758
@@ -4824,7 +5067,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
2c1758
         /* Check if OpenSSL supports the curve */
2c1758
         rc = make_ec_key_from_template(obj->template, &ec_key);
2c1758
         if (ec_key != NULL)
2c1758
-                EC_KEY_free(ec_key);
2c1758
+                EVP_PKEY_free(ec_key);
2c1758
         return rc;
2c1758
 #endif
2c1758