# HG changeset patch
# User Pawel Randzio <pawel.randzio@intel.com>
# Date 1639146463 -3600
#      Fri Dec 10 15:27:43 2021 +0100
# Node ID 1d7d6d196bb17546a74cd51f3fadf246f4054722
# Parent  5bf5c12411d3a4a7e0a552203b40bfe59d5c7789
Add OpenSSL 3.0.0 support in lcptools-v2

diff -r 5bf5c12411d3 -r 1d7d6d196bb1 lcptools-v2/lcputils.c
--- a/lcptools-v2/lcputils.c	Wed Sep 15 16:53:34 2021 +0200
+++ b/lcptools-v2/lcputils.c	Fri Dec 10 15:27:43 2021 +0100
@@ -50,6 +50,12 @@
 #include <openssl/ecdsa.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+    #include <openssl/core.h>
+    #include <openssl/decoder.h>
+    #include <openssl/crypto.h>
+    #include <openssl/param_build.h>
+#endif
 #include <safe_lib.h>
 #include <snprintf_s.h>
 #define PRINT   printf
@@ -512,77 +518,164 @@
     int status;
     EVP_PKEY_CTX *evp_context = NULL;
     EVP_PKEY *evp_key = NULL;
-    RSA *rsa_pubkey = NULL;
     BIGNUM *modulus = NULL;
     BIGNUM *exponent = NULL;
     tb_hash_t *digest = NULL;
     unsigned char exp_arr[] = {0x01, 0x00, 0x01};
+    unsigned char *decrypted_sig = NULL;
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        size_t dcpt_sig_len;
+    #else
+        RSA *rsa_pubkey = NULL;
+    #endif
 
     LOG("[verify_rsa_signature]\n");
     if (data == NULL || pubkey == NULL || signature == NULL) {
         ERROR("Error: list data, pubkey or signature buffer not defined.\n");
         return false;
     }
-    uint8_t decrypted_sig[pubkey->size];
-
-    //1. Create public key
-    rsa_pubkey = RSA_new();
-    if ( rsa_pubkey == NULL ) {
-        ERROR("Error: failed to allocate key\n");
-        status = 0;
-        goto EXIT;
-    }
-
+    
     modulus = BN_bin2bn(pubkey->data, pubkey->size, NULL);
     exponent = BN_bin2bn(exp_arr, 3, NULL);
-    if (modulus == NULL) {
-        goto OPENSSL_ERROR;
-    }
-    if (exponent == NULL) {
+    if ( modulus == NULL || exponent == NULL ) {
+        ERROR("Error: failed to convert modulus and/or exponent.\n");
         goto OPENSSL_ERROR;
     }
 
-    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
-        RSA_set0_key(rsa_pubkey, modulus, exponent, NULL);
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        evp_context = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+        if ( evp_context == NULL) {
+            ERROR("Error: failed to initialize CTX from name.\n");
+            goto OPENSSL_ERROR;
+        }    
+
+        OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new();
+        if ( params_build == NULL ) {
+            ERROR("Error: failed to set up parameter builder.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_PARAM_BLD_push_BN(params_build, "n", modulus) ) {
+            ERROR("Error: failed to push modulus into param build.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_PARAM_BLD_push_BN(params_build, "e", exponent) ) {
+            ERROR("Error: failed to push exponent into param build.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_PARAM_BLD_push_BN(params_build, "d", NULL) ) {
+            ERROR("Error: failed to push NULL into param build.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(params_build);
+        if ( params == NULL ) {
+            ERROR("Error: failed to construct parameters from builder.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        if ( EVP_PKEY_fromdata_init(evp_context) <= 0 ) {
+            ERROR("Error: failed to initialize key creation.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        if ( EVP_PKEY_fromdata(evp_context, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0 ) {
+            ERROR("Error: failed to create key.\n");
+            goto OPENSSL_ERROR;
+        }
+        OSSL_PARAM_free(params);
+        OSSL_PARAM_BLD_free(params_build);
+        EVP_PKEY_CTX_free(evp_context);
+        evp_context = NULL;
     #else
-        rsa_pubkey->n = modulus;
-        rsa_pubkey->e = exponent;
-        rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL;
+        rsa_pubkey = RSA_new();
+        if ( rsa_pubkey == NULL ) {
+            ERROR("Error: failed to allocate key\n");
+            status = 0;
+            goto EXIT;
+        }
+
+        #if OPENSSL_VERSION_NUMBER >= 0x10100000L
+        RSA_set0_key(rsa_pubkey, modulus, exponent, NULL);
+        #else
+            rsa_pubkey->n = modulus;
+            rsa_pubkey->e = exponent;
+            rsa_pubkey->d = rsa_pubkey->p = rsa_pubkey->q = NULL;
+        #endif
     #endif
 
     if (MAJOR_VER(list_ver) != MAJOR_VER(LCP_TPM20_POLICY_LIST2_1_VERSION_300)) {
-        //Decrypt signature - we will need to to find hashalg
-        status = RSA_public_decrypt(pubkey->size, signature->data, decrypted_sig, 
-                            rsa_pubkey, RSA_NO_PADDING);
-        if (status <= 0) {
-            ERROR("Error: failed to decrypt signature.\n");
+        #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+            evp_context = EVP_PKEY_CTX_new(evp_key, NULL);
+            if ( evp_context == NULL ) {
+                ERROR("Error: failed to instatiate CTX.\n");
+                goto OPENSSL_ERROR;
+            }
+            if ( EVP_PKEY_encrypt_init(evp_context) <= 0 ) {
+                ERROR("Error: failed to initialize signature decryption.\n");
+                goto OPENSSL_ERROR;
+            }
+            if ( EVP_PKEY_CTX_set_rsa_padding(evp_context, RSA_NO_PADDING) <= 0 ) {
+                ERROR("Error: failed to set RSA padding.\n");
+                goto OPENSSL_ERROR;
+            }
+            if ( EVP_PKEY_encrypt(evp_context, NULL, &dcpt_sig_len, signature->data, pubkey->size) <= 0 ) {
+                ERROR("Error: failed to retrieve decrypted signature length.\n");
+                goto OPENSSL_ERROR;
+            }
+            decrypted_sig = OPENSSL_malloc(dcpt_sig_len);
+            if ( decrypted_sig == NULL ) {
+                ERROR("Error: failed to allocate memory for decrypted signature.\n");
+                status = 0;
+                goto EXIT;
+            }
+            if ( EVP_PKEY_encrypt(evp_context, decrypted_sig, &dcpt_sig_len, signature->data, pubkey->size) <= 0 ) {
+                ERROR("Error: failed to decrypt signature.\n");
+                goto OPENSSL_ERROR;
+            }
+            if ( verbose ) {
+                LOG("Decrypted signature: \n");
+                print_hex("", decrypted_sig, dcpt_sig_len);
+            }
+            EVP_PKEY_CTX_free(evp_context);
+            evp_context = NULL;
+        #else
+            decrypted_sig = OPENSSL_malloc(pubkey->size);
+            status = RSA_public_decrypt(pubkey->size, signature->data, decrypted_sig, rsa_pubkey, RSA_NO_PADDING);
+            if (status <= 0) {
+                ERROR("Error: failed to decrypt signature.\n");
+                goto OPENSSL_ERROR;
+            }
+            if ( verbose ) {
+                LOG("Decrypted signature: \n");
+                print_hex("", decrypted_sig, pubkey->size);
+            }
+        #endif
+        //In older lists we need to get hashAlg from signature data.
+        hashAlg = pkcs_get_hashalg((const unsigned char *) decrypted_sig);
+        OPENSSL_free((void *) decrypted_sig);
+    }
+
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        evp_key = EVP_PKEY_new();
+        if ( evp_key == NULL) {
             goto OPENSSL_ERROR;
         }
-        if (verbose) {
-            LOG("Decrypted signature: \n");
-            print_hex("", decrypted_sig, pubkey->size);
+
+        status = EVP_PKEY_set1_RSA(evp_key, rsa_pubkey);
+        if (status <= 0) {
+            goto OPENSSL_ERROR;
         }
-        //In older lists we need to get hashAlg from signature data.
-        hashAlg = pkcs_get_hashalg((const unsigned char *) decrypted_sig);
-    }
+    #endif
 
-    evp_key = EVP_PKEY_new();
-    if ( evp_key == NULL) {
+    evp_context = EVP_PKEY_CTX_new(evp_key, NULL);
+    if ( evp_context == NULL ) {
+        ERROR("Error: failed to initialize CTX from pkey.\n");
         goto OPENSSL_ERROR;
     }
 
-    status = EVP_PKEY_set1_RSA(evp_key, rsa_pubkey);
-    if (status <= 0) {
-        goto OPENSSL_ERROR;
-    }
-
-    evp_context = EVP_PKEY_CTX_new(evp_key, NULL);
-    if ( evp_context == NULL) {
-        goto OPENSSL_ERROR;
-    }
-
-    status = EVP_PKEY_verify_init(evp_context);
-    if ( status <= 0) {
+    if ( EVP_PKEY_verify_init(evp_context) <= 0) {
+        ERROR("Error: failed to initialize verification.");
         goto OPENSSL_ERROR;
     }
 
@@ -596,44 +689,38 @@
         goto EXIT;
     }
     if ( status <= 0) {
+        ERROR("Error: failed to set rsa padding.\n");
         goto OPENSSL_ERROR;
     }
 
-    switch ( hashAlg) {
-        case TPM_ALG_SHA1:
-        if ( EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha1()) <= 0 ) {
-            goto OPENSSL_ERROR;
-        }
-        break;
-        case TPM_ALG_SHA256:
-        if ( EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha256()) <= 0 ) {
-            goto OPENSSL_ERROR;
-        }
-        break;
-        case TPM_ALG_SHA384:
-        if ( EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha384()) <= 0 ) {
-            goto OPENSSL_ERROR;
-        }
-        break;
-        default:
+    if ( hashAlg == TPM_ALG_SHA1 ) {
+        status = EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha1());
+    } else if ( hashAlg == TPM_ALG_SHA256 ) {
+        status = EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha256());
+    } else if ( hashAlg == TPM_ALG_SHA384 ) {
+        status = EVP_PKEY_CTX_set_signature_md(evp_context, EVP_sha384());
+    } else {
         ERROR("Error: Unknown hash alg.\n");
         status = 0;
         goto EXIT;
     }
+    if ( status <= 0 ) {
+        ERROR("Error: failed to set signature message digest.\n");
+        goto OPENSSL_ERROR;
+    }
+    
     digest = malloc(get_lcp_hash_size(hashAlg));
     if (digest == NULL) {
         ERROR("Error: failed to allocate digest");
         status = 0;
         goto EXIT;
     }
-    status = hash_buffer((const unsigned char *) data->data, data->size, digest,
-                                                                        hashAlg);
-    if (!status) {
+    if ( !hash_buffer((const unsigned char *) data->data, data->size, digest, hashAlg) ) {
         ERROR("Error: failed to hash list contents.\n");
+        status = 0;
         goto EXIT;
     }
-    status = EVP_PKEY_verify(evp_context, signature->data, pubkey->size,
-                     (const unsigned char *) digest, get_lcp_hash_size(hashAlg));
+    status = EVP_PKEY_verify(evp_context, signature->data, pubkey->size, (const unsigned char *) digest, get_lcp_hash_size(hashAlg));
     if (status < 0) { //Error occurred
         goto OPENSSL_ERROR;
     }
@@ -646,12 +733,14 @@
         ERR_free_strings();
         status = 0;
     EXIT:
+        #if OPENSSL_VERSION_NUMBER < 0x30000000L
+            if (rsa_pubkey != NULL)
+                OPENSSL_free((void *) rsa_pubkey);
+        #endif
         if (evp_context != NULL)
             OPENSSL_free((void *) evp_context);
         if (evp_key != NULL)
             OPENSSL_free((void *) evp_key);
-        if (rsa_pubkey != NULL)
-            OPENSSL_free((void *) rsa_pubkey);
         if (modulus != NULL)
             OPENSSL_free((void *) modulus);
         if (exponent != NULL)
@@ -686,102 +775,183 @@
 
     Out: true/false on verification success or failure
 */
-    //Stuff to make key with:
+    int result;
     BIGNUM *x = NULL;
     BIGNUM *y = NULL;
-    EC_KEY *ec_key = NULL;
-    EC_GROUP *ec_group = NULL;
     EVP_PKEY *evp_key = NULL;
-    const EVP_MD *mdtype; //Is freed when context is freed
-
-    //Der encoded signature:
+    const EVP_MD *mdtype;
     const unsigned char *der_encoded_sig = NULL;
     int encoded_len;
     int curveId = 0;
-
-    //Contexts:
-    EVP_MD_CTX *mctx = NULL; //Message Digest Context
-    EVP_PKEY_CTX *pctx = NULL; //Key context   
-
-    //Other:
-    int result;
-
+    EVP_MD_CTX *mctx = NULL;
+    EVP_PKEY_CTX *pctx = NULL;
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L  
+        const EC_GROUP *ec_group = NULL;
+        EC_POINT *ec_point = NULL;
+        unsigned char *point_buffer = NULL;
+        size_t pt_buf_len;
+        BN_CTX *bctx = NULL;
+        const char *curveName = NULL;
+    #else
+        EC_KEY *ec_key = NULL;
+        EC_GROUP *ec_group = NULL;
+    #endif
+    
     LOG("[verify_ec_signature]\n");
-    if (data == NULL || pubkey_x == NULL || pubkey_y == NULL ||
-        sig_r == NULL || sig_s == NULL) {
-            ERROR("Error: one or more buffers are not defined.\n");
-            return false;
-        }
-    ec_key = EC_KEY_new();
-    if (ec_key == NULL) {
-        ERROR("Error: failed to generate EC_KEY.\n");
-        result = 0;
-        goto EXIT;
+    if ( data == NULL || pubkey_x == NULL || pubkey_y == NULL || sig_r == NULL || sig_s == NULL ) {
+        ERROR("Error: one or more buffers are not defined.\n");
+        return false;
     }
-    evp_key = EVP_PKEY_new();
-    if (evp_key == NULL) {
-        ERROR("Error: failed to generate EC_KEY.\n");
-        result = 0;
-        goto EXIT;
-    }
-    switch (hashalg)
-    {
-    case TPM_ALG_SM3_256:
+    
+    if ( hashalg == TPM_ALG_SM3_256 ) {
         curveId = NID_sm2;
         mdtype = EVP_sm3();
-        break;
-    case TPM_ALG_SHA256:
+        #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+            curveName = SN_sm2;
+        #endif
+    } else if ( hashalg == TPM_ALG_SHA256 ) {
         curveId = NID_secp256k1;
         mdtype = EVP_sha256();
-        break;
-    case TPM_ALG_SHA384:
+        #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+            curveName = SN_secp256k1;
+        #endif
+    } else if ( hashalg == TPM_ALG_SHA384 ) {
         curveId = NID_secp384r1;
         mdtype = EVP_sha384();
-        break;
-    default:
+        #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+            curveName = SN_secp384r1;
+        #endif
+    } else {
         ERROR("Error: unsupported hashalg.\n");
         result = 0;
         goto EXIT;
     }
+
     ec_group = EC_GROUP_new_by_curve_name(curveId);
-    if (ec_group == NULL) {
-        ERROR("Error: failed to generate new EC_GROUP.\n");
+    if ( ec_group == NULL ) {
+        ERROR("Error: failed to create new EC group.\n");
         goto OPENSSL_ERROR;
     }
-    result = EC_KEY_set_group(ec_key, ec_group);
-    if ( result <= 0) {
-        ERROR("Failed to set EC Key group.\n");
-        goto OPENSSL_ERROR;
-    }
+
     x = BN_bin2bn(pubkey_x->data, pubkey_x->size, NULL);
     y = BN_bin2bn(pubkey_y->data, pubkey_y->size, NULL);
     if ( x == NULL || y == NULL ) {
-        ERROR("Failed to convert buffer to OpenSSL BN.\n");
+        ERROR("Error: Failed to convert binary pubkey to BIGNUM x and/or y.\n");
         goto OPENSSL_ERROR;
     }
-    result = EC_KEY_set_public_key_affine_coordinates(ec_key, x, y);
-    if ( result <= 0) {
-        ERROR("Failed to set key coordinates.\n");
-        goto OPENSSL_ERROR;
-    }
-    result = EVP_PKEY_assign_EC_KEY(evp_key, ec_key);
-    if (result <= 0) {
-        ERROR("Error: failed to assign EC KEY to EVP structure.\n");
-        goto OPENSSL_ERROR;
-    }
+
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        ec_point = EC_POINT_new(ec_group);
+        if ( ec_point == NULL ) {
+            ERROR("Error: failed to create new EC point.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        bctx = BN_CTX_new();
+        if ( bctx == NULL ) {
+            ERROR("Error: Failed to create BIGNUM context.\n");
+            goto OPENSSL_ERROR;
+        }
+        
+        if ( EC_POINT_set_affine_coordinates(ec_group, ec_point, x, y, bctx) <= 0 ) {
+            ERROR("Error: failed to set affine coordinates.\n");
+            goto OPENSSL_ERROR;
+        }
+        
+        BN_CTX_free(bctx);
+        bctx = NULL;
+        bctx = BN_CTX_new();
+
+        pt_buf_len = EC_POINT_point2oct(ec_group, ec_point, POINT_CONVERSION_COMPRESSED, NULL, 0, bctx);
+        point_buffer = OPENSSL_malloc(pt_buf_len);
+        if ( point_buffer == NULL ) {
+            ERROR("Error: failed to allocate point buffer.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        if ( EC_POINT_point2oct(ec_group, ec_point, POINT_CONVERSION_COMPRESSED, point_buffer, pt_buf_len, bctx) <= 0 ) {
+            ERROR("Error: failed to convert EC point into octal string.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
+        if ( ctx == NULL ) {
+            ERROR("Error: failed to initialize key creation CTX.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new();
+        if ( params_build == NULL ) {
+            ERROR("Error: failed to set up parameter builder.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_PARAM_BLD_push_utf8_string(params_build, "group", curveName, 0) ) {
+            ERROR("Error: failed to push group into param build.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_PARAM_BLD_push_octet_string(params_build, "pub", point_buffer, pt_buf_len) ) {
+            ERROR("Error: failed to push pubkey into param build.\n");
+            goto OPENSSL_ERROR;
+        }
+        OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(params_build);
+        if ( params == NULL ) {
+            ERROR("Error: failed to construct params from build.\n");
+            goto OPENSSL_ERROR;
+        }
+
+        if ( EVP_PKEY_fromdata_init(ctx) <= 0 ) {
+            ERROR("ERROR: failed to initialize key creation from data.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
+            ERROR("Error: failed to create EC_KEY.\n");
+            result = 0;
+            goto EXIT;
+        }
+        OSSL_PARAM_BLD_free(params_build);
+        OSSL_PARAM_free(params);
+        EVP_PKEY_CTX_free(ctx);
+        BN_CTX_free(bctx);
+    #else
+        ec_key = EC_KEY_new();
+        if (ec_key == NULL) {
+            ERROR("Error: failed to generate EC_KEY.\n");
+            result = 0;
+            goto EXIT;
+        }
+        evp_key = EVP_PKEY_new();
+        if (evp_key == NULL) {
+            ERROR("Error: failed to generate EC_KEY.\n");
+            result = 0;
+            goto EXIT;
+        }
+        if ( EC_KEY_set_group(ec_key, ec_group) <= 0) {
+            ERROR("Failed to set EC Key group.\n");
+            goto OPENSSL_ERROR;
+        }
+        if ( EC_KEY_set_public_key_affine_coordinates(ec_key, x, y) <= 0) {
+            ERROR("Failed to set key coordinates.\n");
+            goto OPENSSL_ERROR;
+        }
+        
+        if ( EVP_PKEY_assign_EC_KEY(evp_key, ec_key) <= 0) {
+            ERROR("Error: failed to assign EC KEY to EVP structure.\n");
+            goto OPENSSL_ERROR;
+        }
+        if (sigalg == TPM_ALG_SM2) {
+            if ( EVP_PKEY_set_alias_type(evp_key, EVP_PKEY_SM2) <= 0 ) {
+                ERROR("Error: failed to set EVP KEY alias to SM2.\n");
+                goto OPENSSL_ERROR;
+            }
+        }
+    #endif
+
     mctx = EVP_MD_CTX_new();
     if (mctx == NULL) {
         ERROR("Error: failed to generate message digest context.\n");
         result = 0;
         goto EXIT;
     }
-    if (sigalg == TPM_ALG_SM2) {
-        result = EVP_PKEY_set_alias_type(evp_key, EVP_PKEY_SM2);
-        if (result <= 0) {
-            ERROR("Error: failed to set EVP KEY alias to SM2.\n");
-            goto OPENSSL_ERROR;
-        }
-    }
     pctx = EVP_PKEY_CTX_new(evp_key, NULL);
     if (pctx == NULL) {
         ERROR("Error: failed to generate key context.\n");
@@ -789,8 +959,7 @@
         goto EXIT;
     }
     if (sigalg == TPM_ALG_SM2) {
-        result = EVP_PKEY_CTX_set1_id(pctx, SM2_ID, SM2_ID_LEN);
-        if (result <= 0) {
+        if ( EVP_PKEY_CTX_set1_id(pctx, SM2_ID, SM2_ID_LEN) <= 0 ) {
             ERROR("Error: failed to set sm2 id.\n");
             goto OPENSSL_ERROR;
         }
@@ -802,26 +971,24 @@
         result = 0;
         goto EXIT;
     }
-    result = EVP_DigestVerifyInit(mctx, NULL, mdtype, NULL, evp_key);
-    if (result <= 0) {
-        ERROR("Error: error while verifying.\n");
+    if ( EVP_DigestVerifyInit(mctx, NULL, mdtype, NULL, evp_key) <= 0 ) {
+        ERROR("Error: error while verifying (init).\n");
         goto OPENSSL_ERROR;
     }
-    if (verbose) {
+    if ( verbose ) {
         LOG("Data that was signed:\n");
         print_hex("    ", data->data, data->size);
     }
-    result = EVP_DigestVerifyUpdate(mctx, data->data, data->size);
-    if (result <= 0) {
-        ERROR("Error: error while verifying.\n");
+    if ( EVP_DigestVerifyUpdate(mctx, data->data, data->size) <= 0) {
+        ERROR("Error: error while verifying (update).\n");
         goto OPENSSL_ERROR;
     }
     result = EVP_DigestVerifyFinal(mctx, der_encoded_sig, encoded_len);
     if (result < 0) {
-        ERROR("Error: error while verifying.\n");
+        ERROR("Error: error while verifying (final)\tError code = %d.\n", result);
         goto OPENSSL_ERROR;
     }
-    goto EXIT; 
+    goto EXIT;
     OPENSSL_ERROR:
         ERR_load_crypto_strings();
         ERROR("OpenSSL error: %s\n",ERR_error_string(ERR_get_error(), NULL));
@@ -829,8 +996,23 @@
         result = 0;
     EXIT:
     //cleanup:
-        if (ec_key != NULL) {
-            OPENSSL_free((void *) ec_key);
+        #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+            if (ec_point != NULL) {
+                OPENSSL_free((void *) ec_point);
+            }
+            if (point_buffer != NULL) {
+                OPENSSL_free((void *) point_buffer);
+            }
+            if (curveName != NULL) {
+                OPENSSL_free((void *) curveName);
+            }
+        #else
+            if (ec_key != NULL) {
+                OPENSSL_free((void *) ec_key);
+            }
+        #endif
+        if (ec_group != NULL) {
+            OPENSSL_free((void *) ec_group);
         }
         if (evp_key != NULL) {
             OPENSSL_free((void *) evp_key);
@@ -841,11 +1023,8 @@
         if (y != NULL) {
             OPENSSL_free((void *) y);
         }
-        if (ec_group != NULL) {
-            OPENSSL_free((void *) ec_group);
-        }
         if (der_encoded_sig != NULL) {
-            OPENSSL_free((void *)der_encoded_sig);
+            OPENSSL_free((void *) der_encoded_sig);
         }
         if (mctx != NULL) {
             OPENSSL_free(mctx);
@@ -871,7 +1050,6 @@
     */
     int result;
     size_t sig_length;
-    EC_KEY *ec_key = NULL;
     EVP_PKEY *evp_key = NULL;
     EVP_MD_CTX *mctx = NULL;
     EVP_PKEY_CTX *pctx = NULL;
@@ -880,6 +1058,9 @@
     const BIGNUM *sig_r = NULL; //Is freed when ECDSA_SIG is freed
     const BIGNUM *sig_s = NULL; //Is freed when ECDSA_SIG is freed
     const unsigned char *signature_block = NULL;
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        EC_KEY *ec_key = NULL;
+    #endif
 
     LOG("[ec_sign_data]\n");
     if (data == NULL || r == NULL || s == NULL) {
@@ -891,37 +1072,49 @@
         ERROR("Error: failed to allocate message digest context.\n");
         goto OPENSSL_ERROR;
     }
-    fp = fopen(privkey_file, "r");
+    fp = fopen(privkey_file, "rb");
     if ( fp == NULL ) {
         ERROR("Error: failed to open file %s: %s\n", privkey_file, strerror(errno));
         result = 0;
         goto EXIT;
     }
-    ec_key = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
-    if (ec_key == NULL) {
-        ERROR("Error: failed to allocate EC key.\n");
-        goto OPENSSL_ERROR;
-    }
+
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        OSSL_DECODER_CTX *dctx;
+        dctx = OSSL_DECODER_CTX_new_for_pkey(&evp_key, "PEM", NULL, "EC", OSSL_KEYMGMT_SELECT_PRIVATE_KEY, NULL, NULL);
+        if ( dctx == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_DECODER_from_fp(dctx, fp) ) {
+            goto OPENSSL_ERROR;
+        }
+        OSSL_DECODER_CTX_free(dctx);
+    #else
+        ec_key = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
+        if (ec_key == NULL) {
+            ERROR("Error: failed to allocate EC key.\n");
+            goto OPENSSL_ERROR;
+        }
+        evp_key = EVP_PKEY_new();
+        if (evp_key == NULL) {
+            ERROR("Error: failed to allocate EVP key.\n");
+            goto OPENSSL_ERROR;
+        }
+        result = EVP_PKEY_assign_EC_KEY(evp_key, ec_key);
+        if (result <= 0) {
+            ERROR("Error: failed to assign EC key to EVP structure.\n");
+            goto OPENSSL_ERROR;
+        }
+        if (sigalg == TPM_ALG_SM2) {
+            result = EVP_PKEY_set_alias_type(evp_key, EVP_PKEY_SM2);
+            if (result <= 0) {
+                ERROR("Error: failed to assign SM2 alias to EVP key.\n");
+                goto OPENSSL_ERROR;
+            }
+        }
+    #endif
     fclose(fp);
     fp = NULL;
-    evp_key = EVP_PKEY_new();
-    if (evp_key == NULL) {
-        ERROR("Error: failed to allocate EVP key.\n");
-        goto OPENSSL_ERROR;
-    }
-    result = EVP_PKEY_assign_EC_KEY(evp_key, ec_key);
-    if (result <= 0) {
-        ERROR("Error: failed to assign EC key to EVP structure.\n");
-        goto OPENSSL_ERROR;
-    }
-
-    if (sigalg == TPM_ALG_SM2) {
-        result = EVP_PKEY_set_alias_type(evp_key, EVP_PKEY_SM2);
-        if (result <= 0) {
-            ERROR("Error: failed to assign SM2 alias to EVP key.\n");
-            goto OPENSSL_ERROR;
-        }
-    }
     
     pctx = EVP_PKEY_CTX_new(evp_key, NULL);
     if (pctx == NULL) {
@@ -999,9 +1192,11 @@
         ERR_free_strings();
         result = 0;
     EXIT:
-        if (ec_key != NULL) {
-            OPENSSL_free((void *) ec_key);
-        }
+        #if OPENSSL_VERSION_NUMBER < 0x30000000L
+            if (ec_key != NULL) {
+                OPENSSL_free((void *) ec_key);
+            }
+        #endif
         if (evp_key != NULL) {
             OPENSSL_free((void *) evp_key);
         }
@@ -1185,8 +1380,9 @@
     uint8_t der_oid = 0x06;
     size_t oid_size;
 
-    if (data == NULL)
+    if (data == NULL) {
         return TPM_ALG_NULL;
+    }
 
     data += 2; //Skip 00 01
     //Skip 0xFFs padding and 00 after it
@@ -1195,8 +1391,9 @@
     } while (*data == 0xFF);
     //Then move to der_oid
     data += 5;
-    if (*data != der_oid)
+    if (*data != der_oid) {
         return TPM_ALG_NULL;
+    }
     data += 1;
     //Read oid size:
     oid_size = *data;
diff -r 5bf5c12411d3 -r 1d7d6d196bb1 lcptools-v2/pollist2.c
--- a/lcptools-v2/pollist2.c	Wed Sep 15 16:53:34 2021 +0200
+++ b/lcptools-v2/pollist2.c	Fri Dec 10 15:27:43 2021 +0100
@@ -45,6 +45,10 @@
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/bn.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+    #include <openssl/decoder.h>
+    #include <openssl/core.h>
+#endif
 #define PRINT   printf
 #include "../include/config.h"
 #include "../include/hash.h"
@@ -93,8 +97,7 @@
     if ( MAJOR_VER(version) == 1 ){
         LOG("read_policy_list_file: version=0x0100\n");
         bool no_sigblock;
-        if ( !verify_tpm12_policy_list(&(pollist->tpm12_policy_list),
-                      len, &no_sigblock, true) ) {
+        if ( !verify_tpm12_policy_list(&(pollist->tpm12_policy_list), len, &no_sigblock, true) ) {
             free(pollist);
             return NULL;
         }
@@ -815,14 +818,31 @@
 lcp_signature_t2 *read_rsa_pubkey_file(const char *file)
 {
     LOG("read_rsa_pubkey_file\n");
-    FILE *fp = fopen(file, "r");
+    FILE *fp = fopen(file, "rb");
     if ( fp == NULL ) {
         ERROR("Error: failed to open .pem file %s: %s\n", file,
                 strerror(errno));
         return NULL;
     }
 
-    RSA *pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        EVP_PKEY *pubkey = NULL;
+        OSSL_DECODER_CTX *dctx = OSSL_DECODER_CTX_new_for_pkey(&pubkey, "PEM", NULL, "RSA", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, NULL, NULL);
+        if ( dctx == NULL ) {
+            ERROR("Error: no suitable potential decoders found\n");
+            fclose(fp);
+            return NULL;
+        }
+        if ( !OSSL_DECODER_from_fp(dctx, fp) ) {
+            ERROR("Error: decoding failure\n");
+            fclose(fp);
+            return NULL;
+        }
+        OSSL_DECODER_CTX_free(dctx);
+    #else
+        RSA *pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
+    #endif
+
     if ( pubkey == NULL ) {
         ERR_load_crypto_strings();
         ERROR("Error: failed to read .pem file %s: %s\n", file,
@@ -832,10 +852,14 @@
         return NULL;
     }
 
-    unsigned int keysize = RSA_size(pubkey);
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        unsigned int keysize = EVP_PKEY_get_size(pubkey);
+    #else
+        unsigned int keysize = RSA_size(pubkey);
+    #endif
     if ( keysize == 0 ) {
         ERROR("Error: public key size is 0\n");
-        RSA_free(pubkey);
+        OPENSSL_free((void *) pubkey);
         fclose(fp);
         return NULL;
     }
@@ -843,17 +867,21 @@
     lcp_signature_t2 *sig = malloc(sizeof(lcp_rsa_signature_t) + 2*keysize);
     if ( sig == NULL ) {
         ERROR("Error: failed to allocate sig\n");
-        RSA_free(pubkey);
+        OPENSSL_free((void *) pubkey);
         fclose(fp);
         return NULL;
     }
-    const BIGNUM *modulus = NULL;
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        BIGNUM *modulus = NULL;
+    #else
+        const BIGNUM *modulus = NULL;
+    #endif
     memset_s(sig, sizeof(lcp_rsa_signature_t) + 2*keysize, 0);
     sig->rsa_signature.pubkey_size = keysize;
 
-    /* OpenSSL Version 1.1.0 and later don't allow direct access to RSA 
-       stuct */
-    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        EVP_PKEY_get_bn_param(pubkey, "n", &modulus);
+    #elif OPENSSL_VERSION_NUMBER >= 0x10100000L
         RSA_get0_key(pubkey, &modulus, NULL, NULL);
     #else
         modulus = pubkey->n;
@@ -872,7 +900,7 @@
     }
 
     LOG("read rsa pubkey succeed!\n");
-    RSA_free(pubkey);
+    OPENSSL_free((void *) pubkey);
     fclose(fp);
     return sig;
 }
@@ -881,52 +909,83 @@
 {
     lcp_signature_t2 *sig = NULL;
     FILE *fp = NULL;
-    const EC_KEY *pubkey = NULL;
-    const EC_POINT *pubpoint = NULL;
-    const EC_GROUP *pubgroup = NULL;
     BIGNUM *x = NULL;
     BIGNUM *y = NULL;
-    BN_CTX *ctx = NULL;
     uint8_t *qx = NULL;
     uint8_t *qy = NULL;
-
     uint16_t keySize;
     uint16_t keySizeBytes;
     int result;
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        const EC_KEY *pubkey = NULL;
+        const EC_POINT *pubpoint = NULL;
+        const EC_GROUP *pubgroup = NULL;
+        BN_CTX *ctx = NULL;
+    #else
+        EVP_PKEY *pubkey;
+    #endif
 
     LOG("read ecdsa pubkey file for list signature.\n");
-    fp = fopen(pubkey_file, "r");
+    fp = fopen(pubkey_file, "rb");
     if ( fp == NULL) {
         ERROR("ERROR: cannot open file.\n");
         goto ERROR;
     }
-    pubkey = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
-    if ( pubkey == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-    //Close the file
-    fclose(fp);
-    fp = NULL;
+    
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        OSSL_DECODER_CTX *dctx;
+        dctx = OSSL_DECODER_CTX_new_for_pkey(&pubkey, "PEM", NULL, "EC", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, NULL, NULL);
+        if ( dctx == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_DECODER_from_fp(dctx, fp) ) {
+            goto OPENSSL_ERROR;
+        }
+        OSSL_DECODER_CTX_free(dctx);
+
+        if ( pubkey == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        fclose(fp);
+        fp = NULL;
 
-    pubpoint = EC_KEY_get0_public_key(pubkey);
-    if ( pubpoint == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-    pubgroup = EC_KEY_get0_group(pubkey);
-    if ( pubgroup == NULL ) {
-        goto OPENSSL_ERROR;
-    }
+        EVP_PKEY_get_bn_param(pubkey, "qx", &x);
+        EVP_PKEY_get_bn_param(pubkey, "qy", &y);
+        if ( x == NULL || y == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+    #else
+        pubkey = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
+        if ( pubkey == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        fclose(fp);
+        fp = NULL;
 
-    x = BN_new();
-    y = BN_new();
-    ctx = BN_CTX_new();
-    if ( x == NULL|| y == NULL || ctx == NULL) {
-        goto OPENSSL_ERROR;
-    }
-    result = EC_POINT_get_affine_coordinates_GFp(pubgroup, pubpoint, x, y, ctx);
-    if (result <= 0) {
-        goto OPENSSL_ERROR;
-    }
+        pubpoint = EC_KEY_get0_public_key(pubkey);
+        if ( pubpoint == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        pubgroup = EC_KEY_get0_group(pubkey);
+        if ( pubgroup == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        x = BN_new();
+        y = BN_new();
+        ctx = BN_CTX_new();
+        if ( x == NULL|| y == NULL || ctx == NULL) {
+            goto OPENSSL_ERROR;
+        }
+
+        result = EC_POINT_get_affine_coordinates_GFp(pubgroup, pubpoint, x, y, ctx);
+        if (result <= 0) {
+            goto OPENSSL_ERROR;
+        }
+    #endif
+
     keySize = BN_num_bytes(x)*8;
     if (BN_num_bytes(x) != BN_num_bytes(y)) {
         ERROR("ERROR: key coordinates are not the same length.");
@@ -951,12 +1010,6 @@
         goto ERROR;
     }
 
-    if ( keySize/8 != BN_num_bytes(x) || keySize/8 != BN_num_bytes(y) ) {
-        ERROR("ERROR: keySize 0x%X is not 0x%X or 0x%X.\n", keySizeBytes,
-                                            MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE);
-        goto ERROR;
-    }
-
     sig = calloc(1, sizeof(lcp_ecc_signature_t)+(4*keySizeBytes)); //qx, qy, r and s
     if (sig == NULL) {
         ERROR("Error: failed to allocate signature.\n");
@@ -996,11 +1049,13 @@
     free(qx);
     free(qy);
     OPENSSL_free((void *) pubkey);
-    OPENSSL_free((void *) pubpoint);
-    OPENSSL_free((void *) pubgroup);
-    OPENSSL_free((void *) ctx);
     OPENSSL_free((void *) x);
     OPENSSL_free((void *) y);
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        OPENSSL_free((void *) pubpoint);
+        OPENSSL_free((void *) pubgroup);
+        OPENSSL_free((void *) ctx);
+    #endif
     return sig;
 
     //Errors:
@@ -1020,16 +1075,18 @@
             free(qy);
         if (pubkey != NULL)
             OPENSSL_free((void *) pubkey);
-        if (pubpoint != NULL)
-            OPENSSL_free((void *) pubpoint);
-        if (pubgroup != NULL)
-            OPENSSL_free((void *) pubgroup);
-        if (ctx != NULL)
-            OPENSSL_free((void *) ctx);
         if (x != NULL)
             OPENSSL_free((void *) x);
         if (y != NULL)
             OPENSSL_free((void *) y);
+        #if OPENSSL_VERSION_NUMBER < 0x30000000L
+            if (pubpoint != NULL)
+            OPENSSL_free((void *) pubpoint);
+            if (pubgroup != NULL)
+                OPENSSL_free((void *) pubgroup);
+            if (ctx != NULL)
+                OPENSSL_free((void *) ctx);
+        #endif
         return NULL;
 }
 bool ec_sign_list2_data(lcp_policy_list_t2 *pollist, const char *privkey) 
diff -r 5bf5c12411d3 -r 1d7d6d196bb1 lcptools-v2/pollist2_1.c
--- a/lcptools-v2/pollist2_1.c	Wed Sep 15 16:53:34 2021 +0200
+++ b/lcptools-v2/pollist2_1.c	Fri Dec 10 15:27:43 2021 +0100
@@ -48,6 +48,10 @@
 #include <openssl/ecdsa.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+    #include <openssl/decoder.h>
+    #include <openssl/core.h>
+#endif
 #include "../include/hash.h"
 #include "../include/uuid.h"
 #include "../include/lcp3.h"
@@ -1527,9 +1531,13 @@
 Out: Pointer to signature structure.
 */
 {
-    const BIGNUM *modulus = NULL;
     FILE *fp = NULL;
-    RSA *pubkey = NULL;
+    BIGNUM *modulus = NULL;
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        EVP_PKEY *pubkey = NULL;
+    #else
+        RSA *pubkey = NULL;
+    #endif
     lcp_signature_2_1 *sig = NULL;
     unsigned char *key = NULL;
 
@@ -1537,14 +1545,26 @@
     int result = 0;
 
     LOG("read_rsa_pubkey_file_2_1\n");
-    fp = fopen(file, "r");
+    fp = fopen(file, "rb");
     if ( fp == NULL ) {
         ERROR("Error: failed to open .pem file %s: %s\n", file,
                 strerror(errno));
         return NULL;
     }
 
-    pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        OSSL_DECODER_CTX *dctx;
+        dctx = OSSL_DECODER_CTX_new_for_pkey(&pubkey, "PEM", NULL, "RSA", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, NULL, NULL);
+        if ( dctx == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_DECODER_from_fp(dctx, fp) ) {
+            goto OPENSSL_ERROR;
+        }
+        OSSL_DECODER_CTX_free(dctx);
+    #else
+        pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
+    #endif
     if ( pubkey == NULL ) {
         goto OPENSSL_ERROR;
     }
@@ -1552,7 +1572,11 @@
     fclose(fp);
     fp = NULL;
 
-    keysize = RSA_size(pubkey);
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        keysize = EVP_PKEY_get_size(pubkey);
+    #else
+        keysize = RSA_size(pubkey);
+    #endif
     if ( keysize != 256 && keysize != 384 ) {
         ERROR("Error: public key size %d is not supported\n", keysize);
         goto ERROR;
@@ -1564,14 +1588,17 @@
         goto ERROR;
     }
 
-    #if OPENSSL_VERSION_NUMBER >= 0x10100000L
-        RSA_get0_key(pubkey, &modulus, NULL, NULL);
-        if (modulus == NULL) {
-            goto OPENSSL_ERROR;
-        }
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        EVP_PKEY_get_bn_param(pubkey, "n", &modulus);
+    #elif OPENSSL_VERSION_NUMBER >= 0x10100000L
+        RSA_get0_key(pubkey, (const BIGNUM **) &modulus, NULL, NULL);
     #else
         modulus = pubkey->n;
     #endif
+    if (modulus == NULL) {
+        goto OPENSSL_ERROR;
+    }
+
     //Allocate for the key
     key = malloc(keysize);
     if (key == NULL) {
@@ -1609,9 +1636,7 @@
         free(key);
         return sig;
     OPENSSL_ERROR:
-        ERR_load_CRYPTO_strings();
         ERROR("OpenSSL error: %s\n", ERR_error_string(ERR_get_error(), NULL));
-        ERR_free_strings();
         goto ERROR;
     ERROR:
         if (fp != NULL)
@@ -1744,12 +1769,8 @@
     int result;
     lcp_signature_2_1 *sig = NULL;
     FILE *fp = NULL;
-    const EC_KEY *pubkey = NULL;
-    const EC_POINT *pubpoint = NULL;
-    const EC_GROUP *pubgroup = NULL;
     BIGNUM *x = NULL;
     BIGNUM *y = NULL;
-    BN_CTX *ctx = NULL;
     uint16_t bytes_in_x;
     uint16_t bytes_in_y;
     uint16_t keySize;
@@ -1758,43 +1779,74 @@
     uint8_t qy[MAX_ECC_KEY_SIZE];
     uint8_t qx_le[MAX_ECC_KEY_SIZE];
     uint8_t qy_le[MAX_ECC_KEY_SIZE];
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        const EC_KEY *pubkey = NULL;
+        const EC_POINT *pubpoint = NULL;
+        const EC_GROUP *pubgroup = NULL;
+        BN_CTX *ctx = NULL;
+    #else
+        EVP_PKEY *pubkey = NULL;
+    #endif
 
-    LOG("read ecdsa pubkey file for signature 2.1.\n");
-    fp = fopen(pubkey_file, "r");
+    fp = fopen(pubkey_file, "rb");
     if ( fp == NULL) {
         ERROR("ERROR: cannot open file.\n");
         goto ERROR;
     }
-    pubkey = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
-    if ( pubkey == NULL ) {
-        goto OPENSSL_ERROR;
-    }
+
+    #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+        OSSL_DECODER_CTX *dctx;
+        dctx = OSSL_DECODER_CTX_new_for_pkey(&pubkey, "PEM", NULL, "EC", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, NULL, NULL);
+        if ( dctx == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        if ( !OSSL_DECODER_from_fp(dctx, fp) ) {
+            goto OPENSSL_ERROR;
+        }
+        OSSL_DECODER_CTX_free(dctx);
+
+        if ( pubkey == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        EVP_PKEY_get_bn_param(pubkey, "qx", &x);
+        EVP_PKEY_get_bn_param(pubkey, "qy", &y);
+        if ( x == NULL|| y == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+    #else
+        pubkey = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
+        if ( pubkey == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        pubpoint = EC_KEY_get0_public_key(pubkey);
+        if ( pubpoint == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        pubgroup = EC_KEY_get0_group(pubkey);
+        if ( pubgroup == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+
+        x = BN_new();
+        y = BN_new();
+        if ( x == NULL|| y == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        ctx = BN_CTX_new();
+        if ( ctx == NULL ) {
+            goto OPENSSL_ERROR;
+        }
+        result = EC_POINT_get_affine_coordinates_GFp(pubgroup, pubpoint, x, y, ctx);
+        if (result <= 0) {
+            goto OPENSSL_ERROR;
+        }
+    #endif    
     //Close the file
     fclose(fp);
     fp = NULL;
 
-    pubpoint = EC_KEY_get0_public_key(pubkey);
-    if ( pubpoint == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-    pubgroup = EC_KEY_get0_group(pubkey);
-    if ( pubgroup == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-
-    x = BN_new();
-    y = BN_new();
-    if ( x == NULL|| y == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-    ctx = BN_CTX_new();
-    if ( ctx == NULL ) {
-        goto OPENSSL_ERROR;
-    }
-    result = EC_POINT_get_affine_coordinates_GFp(pubgroup, pubpoint, x, y, ctx);
-    if (result <= 0) {
-        goto OPENSSL_ERROR;
-    }
     bytes_in_x = BN_num_bytes(x);
     bytes_in_y = BN_num_bytes(y);
 
@@ -1865,11 +1917,13 @@
     }
 //Free resources:
     OPENSSL_free((void *) pubkey);
-    OPENSSL_free((void *) pubpoint);
-    OPENSSL_free((void *) pubgroup);
-    OPENSSL_free((void *) ctx);
     OPENSSL_free((void *) x);
     OPENSSL_free((void *) y);
+    #if OPENSSL_VERSION_NUMBER < 0x30000000L
+        OPENSSL_free((void *) pubpoint);
+        OPENSSL_free((void *) pubgroup);
+        OPENSSL_free((void *) ctx);
+    #endif
     return sig;
 //ERROR handling:
     OPENSSL_ERROR:
@@ -1884,16 +1938,18 @@
             free(sig);
         if (pubkey != NULL)
             OPENSSL_free((void *) pubkey);
-        if (pubpoint != NULL)
-            OPENSSL_free((void *) pubpoint);
-        if (pubgroup != NULL)
-            OPENSSL_free((void *) pubgroup);
-        if (ctx != NULL)
-            OPENSSL_free((void *) ctx);
         if (x != NULL)
             OPENSSL_free((void *) x);
         if (y != NULL)
             OPENSSL_free((void *) y);
+        #if OPENSSL_VERSION_NUMBER < 0x30000000L
+            if (pubpoint != NULL)
+                OPENSSL_free((void *) pubpoint);
+            if (pubgroup != NULL)
+                OPENSSL_free((void *) pubgroup);
+            if (ctx != NULL)
+                OPENSSL_free((void *) ctx);
+        #endif
         return NULL;
 }
 
