diff --git a/oqsprov/oqs_kem.c b/oqsprov/oqs_kem.c
index 0ed3fbe4..22888f62 100644
--- a/oqsprov/oqs_kem.c
+++ b/oqsprov/oqs_kem.c
@@ -67,8 +67,10 @@ static void oqs_kem_freectx(void *vpkemctx) {
     PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
 
     OQS_KEM_PRINTF("OQS KEM provider called: freectx\n");
-    oqsx_key_free(pkemctx->kem);
-    OPENSSL_free(pkemctx);
+    if (pkemctx != NULL) {
+        oqsx_key_free(pkemctx->kem);
+        OPENSSL_free(pkemctx);
+    }
 }
 
 static int oqs_kem_decapsencaps_init(void *vpkemctx, void *vkem,
@@ -76,10 +78,12 @@ static int oqs_kem_decapsencaps_init(void *vpkemctx, void *vkem,
     PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
 
     OQS_KEM_PRINTF3("OQS KEM provider called: _init : New: %p; old: %p \n",
-                    vkem, pkemctx->kem);
+                    vkem, pkemctx ? pkemctx->kem : NULL);
     if (pkemctx == NULL || vkem == NULL || !oqsx_key_up_ref(vkem))
         return 0;
-    oqsx_key_free(pkemctx->kem);
+    if (pkemctx->kem != NULL) {
+        oqsx_key_free(pkemctx->kem);
+    }
     pkemctx->kem = vkem;
 
     return 1;
@@ -106,13 +110,13 @@ static int oqs_qs_kem_encaps_keyslot(void *vpkemctx, unsigned char *out,
     const OQS_KEM *kem_ctx = NULL;
 
     OQS_KEM_PRINTF("OQS KEM provider called: encaps\n");
-    if (pkemctx->kem == NULL) {
+    if (pkemctx == NULL || pkemctx->kem == NULL) {
         OQS_KEM_PRINTF("OQS Warning: OQS_KEM not initialized\n");
         return -1;
     }
 
     kem_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;
-    if (pkemctx->kem->comp_pubkey == NULL ||
+    if (kem_ctx == NULL || pkemctx->kem->comp_pubkey == NULL ||
         pkemctx->kem->comp_pubkey[keyslot] == NULL) {
         OQS_KEM_PRINTF("OQS Warning: public key is NULL\n");
         return -1;
@@ -156,12 +160,12 @@ static int oqs_qs_kem_decaps_keyslot(void *vpkemctx, unsigned char *out,
     const OQS_KEM *kem_ctx = NULL;
 
     OQS_KEM_PRINTF("OQS KEM provider called: decaps\n");
-    if (pkemctx->kem == NULL) {
+    if (pkemctx == NULL || pkemctx->kem == NULL) {
         OQS_KEM_PRINTF("OQS Warning: OQS_KEM not initialized\n");
         return -1;
     }
     kem_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;
-    if (pkemctx->kem->comp_privkey == NULL ||
+    if (kem_ctx == NULL || pkemctx->kem->comp_privkey == NULL ||
         pkemctx->kem->comp_privkey[keyslot] == NULL) {
         OQS_KEM_PRINTF("OQS Warning: private key is NULL\n");
         return -1;
diff --git a/oqsprov/oqs_kmgmt.c b/oqsprov/oqs_kmgmt.c
index 1480abbc..b8a29193 100644
--- a/oqsprov/oqs_kmgmt.c
+++ b/oqsprov/oqs_kmgmt.c
@@ -27,12 +27,16 @@ int oqsx_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
                                       const char *key,
                                       const unsigned char *data,
                                       size_t data_len) {
-    if (bld != NULL)
+    if (bld != NULL && key != NULL && data != NULL) {
         return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len);
+    }
 
-    p = OSSL_PARAM_locate(p, key);
-    if (p != NULL)
-        return OSSL_PARAM_set_octet_string(p, data, data_len);
+    if (p != NULL && key != NULL) {
+        p = OSSL_PARAM_locate(p, key);
+        if (p != NULL && data != NULL) {
+            return OSSL_PARAM_set_octet_string(p, data, data_len);
+        }
+    }
     return 1;
 }
 
@@ -93,17 +97,16 @@ static int oqsx_has(const void *keydata, int selection) {
         ok = 1;
 
         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
-            ok = ok && key->pubkey != NULL;
+            ok = ok && (key->pubkey != NULL);
 
         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
-            ok = ok && key->privkey != NULL;
+            ok = ok && (key->privkey != NULL);
     }
     if (!ok)
         OQS_KM_PRINTF2("OQSKM: has returning FALSE on selection %2x\n",
                        selection);
     return ok;
 }
-
 /*
  * Key matching has a problem in OQS world: OpenSSL assumes all keys to (also)
  * contain public key material
@@ -139,13 +142,6 @@ static int oqsx_match(const void *keydata1, const void *keydata2,
     }
 
 #ifdef NOPUBKEY_IN_PRIVKEY
-    /* Now this is a "leap of faith" logic: If a public-only PKEY and a
-     * private-only PKEY are tested for equality we cannot do anything other
-     * than saying OK (as per
-     * https://github.com/PQClean/PQClean/issues/415#issuecomment-910377682) if
-     * at least the key type name matches. Potential actual key mismatches will
-     * only be discovered later.
-     */
     if (((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) &&
         ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)) {
         if ((key1->privkey == NULL && key2->pubkey == NULL) ||
@@ -167,7 +163,7 @@ static int oqsx_match(const void *keydata1, const void *keydata2,
             ok = 0;
         } else {
             ok = ((key1->privkey == NULL && key2->privkey == NULL) ||
-                  ((key1->privkey != NULL) &&
+                  ((key1->privkey != NULL && key2->privkey != NULL) &&
                    CRYPTO_memcmp(key1->privkey, key2->privkey,
                                  key1->privkeylen) == 0));
         }
@@ -178,15 +174,13 @@ static int oqsx_match(const void *keydata1, const void *keydata2,
             (key1->pubkey != NULL && key2->pubkey == NULL) ||
             ((key1->tls_name != NULL && key2->tls_name != NULL) &&
              strcmp(key1->tls_name, key2->tls_name))) {
-            // special case now: If domain parameter matching
-            // requested, consider private key match sufficient:
             ok = ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) &&
                  (key1->privkey != NULL && key2->privkey != NULL) &&
                  (CRYPTO_memcmp(key1->privkey, key2->privkey,
                                 key1->privkeylen) == 0);
         } else {
             ok = ok && ((key1->pubkey == NULL && key2->pubkey == NULL) ||
-                        ((key1->pubkey != NULL) &&
+                        ((key1->pubkey != NULL && key2->pubkey != NULL) &&
                          CRYPTO_memcmp(key1->pubkey, key2->pubkey,
                                        key1->pubkeylen) == 0));
         }
@@ -202,7 +196,7 @@ static int oqsx_import(void *keydata, int selection,
     int ok = 0;
 
     OQS_KM_PRINTF("OQSKEYMGMT: import called \n");
-    if (key == NULL) {
+    if (key == NULL || params == NULL) {
         ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
         return ok;
     }
@@ -223,11 +217,11 @@ int oqsx_key_to_params(const OQSX_KEY *key, OSSL_PARAM_BLD *tmpl,
     if (key->pubkey != NULL) {
         OSSL_PARAM *p = NULL;
 
-        if (tmpl == NULL) {
+        if (params != NULL) {
             p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
         }
 
-        if (p != NULL || tmpl != NULL) {
+        if ((p != NULL && params != NULL) || tmpl != NULL) {
             if (key->pubkeylen == 0 || !oqsx_param_build_set_octet_string(
                                            tmpl, p, OSSL_PKEY_PARAM_PUB_KEY,
                                            key->pubkey, key->pubkeylen))
@@ -244,11 +238,11 @@ int oqsx_key_to_params(const OQSX_KEY *key, OSSL_PARAM_BLD *tmpl,
          *
          */
 
-        if (tmpl == NULL) {
+        if (params != NULL) {
             p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY);
         }
 
-        if (p != NULL || tmpl != NULL) {
+        if ((p != NULL && params != NULL) || tmpl != NULL) {
             if (key->privkeylen == 0 || !oqsx_param_build_set_octet_string(
                                             tmpl, p, OSSL_PKEY_PARAM_PRIV_KEY,
                                             key->privkey, key->privkeylen))
@@ -264,17 +258,12 @@ int oqsx_key_to_params(const OQSX_KEY *key, OSSL_PARAM_BLD *tmpl,
 static int oqsx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
                        void *cbarg) {
     OQSX_KEY *key = keydata;
-    OSSL_PARAM_BLD *tmpl;
+    OSSL_PARAM_BLD *tmpl = NULL;
     OSSL_PARAM *params = NULL;
-    OSSL_PARAM *p;
     int ok = 1;
 
     OQS_KM_PRINTF("OQSKEYMGMT: export called\n");
 
-    /*
-     * In this implementation, only public and private keys can be exported,
-     * nothing else
-     */
     if (key == NULL || param_cb == NULL) {
         ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
         return 0;
@@ -293,15 +282,18 @@ static int oqsx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
         ok = ok && oqsx_key_to_params(key, tmpl, NULL, include_private);
     }
 
-    params = OSSL_PARAM_BLD_to_param(tmpl);
-    if (params == NULL) {
-        ok = 0;
-        goto err;
+    if (ok) {
+        params = OSSL_PARAM_BLD_to_param(tmpl);
+        if (params == NULL) {
+            ok = 0;
+        }
+    }
+
+    if (ok && params != NULL) {
+        ok = param_cb(params, cbarg);
     }
 
-    ok = ok & param_cb(params, cbarg);
     OSSL_PARAM_free(params);
-err:
     OSSL_PARAM_BLD_free(tmpl);
     return ok;
 }
@@ -321,7 +313,7 @@ static int oqsx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
 static const OSSL_PARAM oqsx_key_types[] = {OQS_KEY_TYPES(), OSSL_PARAM_END};
 static const OSSL_PARAM *oqs_imexport_types(int selection) {
     OQS_KM_PRINTF("OQSKEYMGMT: imexport called\n");
-    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
+    if (selection != 0 && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
         return oqsx_key_types;
     return NULL;
 }
@@ -331,6 +323,11 @@ static const OSSL_PARAM *oqs_imexport_types(int selection) {
 //
 // Returns 1 if hybrid, else 0.
 static int oqsx_key_is_hybrid(const OQSX_KEY *oqsxk) {
+    if (oqsxk == NULL) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+        return 0;
+    }
+
     if ((oqsxk->keytype == KEY_TYPE_ECP_HYB_KEM ||
          oqsxk->keytype == KEY_TYPE_ECX_HYB_KEM ||
          oqsxk->keytype == KEY_TYPE_HYB_SIG) &&
@@ -357,6 +354,9 @@ static int oqsx_get_hybrid_params(OQSX_KEY *key, OSSL_PARAM params[]) {
     int pq_pubkey_len = 0;
     int pq_privkey_len = 0;
 
+    if (key == NULL || params == NULL)
+        return -1;
+
     if (oqsx_key_is_hybrid(key) != 1)
         return 0;
 
@@ -387,26 +387,34 @@ static int oqsx_get_hybrid_params(OQSX_KEY *key, OSSL_PARAM params[]) {
     }
 
     if ((p = OSSL_PARAM_locate(
-             params, OQS_HYBRID_PKEY_PARAM_CLASSICAL_PUB_KEY)) != NULL &&
-        !OSSL_PARAM_set_octet_string(p, classical_pubkey, classical_pubkey_len))
-        return -1;
+             params, OQS_HYBRID_PKEY_PARAM_CLASSICAL_PUB_KEY)) != NULL) {
+        if (!OSSL_PARAM_set_octet_string(p, classical_pubkey,
+                                         classical_pubkey_len)) {
+            return -1;
+        }
+    }
     if ((p = OSSL_PARAM_locate(
-             params, OQS_HYBRID_PKEY_PARAM_CLASSICAL_PRIV_KEY)) != NULL &&
-        !OSSL_PARAM_set_octet_string(p, classical_privkey,
-                                     classical_privkey_len))
-        return -1;
+             params, OQS_HYBRID_PKEY_PARAM_CLASSICAL_PRIV_KEY)) != NULL) {
+        if (!OSSL_PARAM_set_octet_string(p, classical_privkey,
+                                         classical_privkey_len)) {
+            return -1;
+        }
+    }
     if ((p = OSSL_PARAM_locate(params, OQS_HYBRID_PKEY_PARAM_PQ_PUB_KEY)) !=
-            NULL &&
-        !OSSL_PARAM_set_octet_string(p, pq_pubkey, pq_pubkey_len))
-        return -1;
+        NULL) {
+        if (!OSSL_PARAM_set_octet_string(p, pq_pubkey, pq_pubkey_len)) {
+            return -1;
+        }
+    }
     if ((p = OSSL_PARAM_locate(params, OQS_HYBRID_PKEY_PARAM_PQ_PRIV_KEY)) !=
-            NULL &&
-        !OSSL_PARAM_set_octet_string(p, pq_privkey, pq_privkey_len))
-        return -1;
+        NULL) {
+        if (!OSSL_PARAM_set_octet_string(p, pq_privkey, pq_privkey_len)) {
+            return -1;
+        }
+    }
 
     return 0;
 }
-
 // must handle param requests for KEM and SIG keys...
 static int oqsx_get_params(void *key, OSSL_PARAM params[]) {
     OQSX_KEY *oqsxk = key;
@@ -446,23 +454,41 @@ static int oqsx_get_params(void *key, OSSL_PARAM params[]) {
         // shall not be passed out:
         if (oqsxk->keytype == KEY_TYPE_ECP_HYB_KEM ||
             oqsxk->keytype == KEY_TYPE_ECX_HYB_KEM) {
-            if (!OSSL_PARAM_set_octet_string(
-                    p, (char *)oqsxk->pubkey + SIZE_OF_UINT32,
-                    oqsxk->pubkeylen - SIZE_OF_UINT32))
+            if (oqsxk->pubkey != NULL && oqsxk->pubkeylen > SIZE_OF_UINT32) {
+                if (!OSSL_PARAM_set_octet_string(
+                        p, (char *)oqsxk->pubkey + SIZE_OF_UINT32,
+                        oqsxk->pubkeylen - SIZE_OF_UINT32))
+                    return 0;
+            } else {
                 return 0;
+            }
         } else {
-            if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey,
-                                             oqsxk->pubkeylen))
+            if (oqsxk->pubkey != NULL && oqsxk->pubkeylen > 0) {
+                if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey,
+                                                 oqsxk->pubkeylen))
+                    return 0;
+            } else {
                 return 0;
+            }
         }
     }
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY)) != NULL) {
-        if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey, oqsxk->pubkeylen))
+        if (oqsxk->pubkey != NULL && oqsxk->pubkeylen > 0) {
+            if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey,
+                                             oqsxk->pubkeylen))
+                return 0;
+        } else {
             return 0;
+        }
     }
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL) {
-        if (!OSSL_PARAM_set_octet_string(p, oqsxk->privkey, oqsxk->privkeylen))
+        if (oqsxk->privkey != NULL && oqsxk->privkeylen > 0) {
+            if (!OSSL_PARAM_set_octet_string(p, oqsxk->privkey,
+                                             oqsxk->privkeylen))
+                return 0;
+        } else {
             return 0;
+        }
     }
 
     if (oqsx_get_hybrid_params(oqsxk, params))
@@ -486,16 +512,24 @@ static const OSSL_PARAM *oqs_gettable_params(void *provctx) {
 }
 
 static int set_property_query(OQSX_KEY *oqsxkey, const char *propq) {
-    OPENSSL_free(oqsxkey->propq);
-    oqsxkey->propq = NULL;
+    if (oqsxkey == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    char *new_propq = NULL;
     OQS_KM_PRINTF("OQSKEYMGMT: property_query called\n");
     if (propq != NULL) {
-        oqsxkey->propq = OPENSSL_strdup(propq);
-        if (oqsxkey->propq == NULL) {
+        new_propq = OPENSSL_strdup(propq);
+        if (new_propq == NULL) {
             ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
             return 0;
         }
     }
+
+    OPENSSL_free(oqsxkey->propq);
+    oqsxkey->propq = new_propq;
+
     return 1;
 }
 
@@ -504,7 +538,7 @@ static int oqsx_set_params(void *key, const OSSL_PARAM params[]) {
     const OSSL_PARAM *p;
 
     OQS_KM_PRINTF("OQSKEYMGMT: set_params called\n");
-    if (oqsxkey == NULL) {
+    if (oqsxkey == NULL || params == NULL) {
         ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
         return 0;
     }
@@ -529,8 +563,11 @@ static int oqsx_set_params(void *key, const OSSL_PARAM params[]) {
                 return 0;
             }
         }
-        OPENSSL_clear_free(oqsxkey->privkey, oqsxkey->privkeylen);
-        oqsxkey->privkey = NULL;
+        if (oqsxkey->privkey != NULL) {
+            OPENSSL_clear_free(oqsxkey->privkey, oqsxkey->privkeylen);
+            oqsxkey->privkey = NULL;
+            oqsxkey->privkeylen = 0;
+        }
     }
     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
     if (p != NULL) {
@@ -565,18 +602,23 @@ static void *oqsx_gen_init(void *provctx, int selection, char *oqs_name,
     if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
         gctx->libctx = libctx;
         gctx->cmp_name = NULL;
-        gctx->oqs_name = OPENSSL_strdup(oqs_name);
-        gctx->tls_name = OPENSSL_strdup(tls_name);
+        gctx->oqs_name = oqs_name ? OPENSSL_strdup(oqs_name) : NULL;
+        gctx->tls_name = tls_name ? OPENSSL_strdup(tls_name) : NULL;
         gctx->primitive = primitive;
         gctx->selection = selection;
         gctx->bit_security = bit_security;
         gctx->alg_idx = alg_idx;
+
+        if ((oqs_name && !gctx->oqs_name) || (tls_name && !gctx->tls_name)) {
+            oqsx_gen_cleanup(gctx);
+            return NULL;
+        }
     }
     return gctx;
 }
 
 static void *oqsx_genkey(struct oqsx_gen_ctx *gctx) {
-    OQSX_KEY *key;
+    OQSX_KEY *key = NULL;
 
     if (gctx == NULL)
         return NULL;
@@ -592,6 +634,7 @@ static void *oqsx_genkey(struct oqsx_gen_ctx *gctx) {
 
     if (oqsx_key_gen(key)) {
         ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+        oqsx_key_free(key);
         return NULL;
     }
     return key;
@@ -602,12 +645,20 @@ static void *oqsx_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) {
 
     OQS_KM_PRINTF("OQSKEYMGMT: gen called\n");
 
+    if (gctx == NULL) {
+        return NULL;
+    }
+
     return oqsx_genkey(gctx);
 }
 
 static void oqsx_gen_cleanup(void *genctx) {
     struct oqsx_gen_ctx *gctx = genctx;
 
+    if (gctx == NULL) {
+        return;
+    }
+
     OQS_KM_PRINTF("OQSKEYMGMT: gen_cleanup called\n");
     OPENSSL_free(gctx->oqs_name);
     OPENSSL_free(gctx->tls_name);
@@ -619,11 +670,18 @@ void *oqsx_load(const void *reference, size_t reference_sz) {
     OQSX_KEY *key = NULL;
 
     OQS_KM_PRINTF("OQSKEYMGMT: load called\n");
+
+    if (reference == NULL) {
+        return NULL;
+    }
+
     if (reference_sz == sizeof(key)) {
         /* The contents of the reference is the address to our object */
         key = *(OQSX_KEY **)reference;
-        /* We grabbed, so we detach it */
-        *(OQSX_KEY **)reference = NULL;
+        if (key != NULL) {
+            /* We grabbed, so we detach it */
+            *(OQSX_KEY **)reference = NULL;
+        }
         return key;
     }
     return NULL;
@@ -642,27 +700,30 @@ static int oqsx_gen_set_params(void *genctx, const OSSL_PARAM params[]) {
     const OSSL_PARAM *p;
 
     OQS_KM_PRINTF("OQSKEYMGMT: gen_set_params called\n");
-    if (gctx == NULL)
+    if (gctx == NULL || params == NULL)
         return 0;
 
     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
-    if (p != NULL) {
+    if (p != NULL && p->data != NULL) {
         const char *algname = (char *)p->data;
-
+        char *new_tls_name = OPENSSL_strdup(algname);
+        if (new_tls_name == NULL)
+            return 0;
         OPENSSL_free(gctx->tls_name);
-        gctx->tls_name = OPENSSL_strdup(algname);
+        gctx->tls_name = new_tls_name;
     }
+
     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
-    if (p != NULL) {
+    if (p != NULL && p->data != NULL) {
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
-        OPENSSL_free(gctx->propq);
-        gctx->propq = OPENSSL_strdup(p->data);
-        if (gctx->propq == NULL)
+        char *new_propq = OPENSSL_strdup(p->data);
+        if (new_propq == NULL)
             return 0;
+        OPENSSL_free(gctx->propq);
+        gctx->propq = new_propq;
     }
-    // not passing in params is no error; subsequent operations may fail,
-    // though
+
     return 1;
 }
 
diff --git a/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c
index 173a3120..1eafd04b 100644
--- a/oqsprov/oqsprov_keys.c
+++ b/oqsprov/oqsprov_keys.c
@@ -200,6 +200,9 @@ static oqs_nid_name_t nid_names[NID_TABLE_LEN] = {
 
 int oqs_set_nid(char *tlsname, int nid) {
     int i;
+    if (tlsname == NULL) {
+        return 0;
+    }
     for (i = 0; i < NID_TABLE_LEN; i++) {
         if (!strcmp(nid_names[i].tlsname, tlsname)) {
             nid_names[i].nid = nid;
@@ -229,6 +232,9 @@ static int get_keytype(int nid) {
 
 char *get_oqsname_fromtls(char *tlsname) {
     int i;
+    if (tlsname == NULL) {
+        return NULL;
+    }
     for (i = 0; i < NID_TABLE_LEN; i++) {
         if (nid_names[i].keytype == KEY_TYPE_SIG) {
             if (!strcmp(nid_names[i].oqsname, tlsname) ||
@@ -236,7 +242,7 @@ char *get_oqsname_fromtls(char *tlsname) {
                 return nid_names[i].oqsname;
         }
     }
-    return 0; // classical
+    return NULL; // classical
 }
 
 char *get_oqsname(int nid) {
@@ -245,15 +251,18 @@ char *get_oqsname(int nid) {
         if (nid_names[i].nid == nid)
             return nid_names[i].oqsname;
     }
-    return 0;
+    return NULL;
 }
 
 char *get_cmpname(int nid, int index) {
     int i, len;
-    char *name, *s;
+    char *name = NULL, *s;
     if ((i = get_oqsalg_idx(nid)) == -1)
         return NULL;
     s = nid_names[i].tlsname;
+    if (s == NULL) {
+        return NULL;
+    }
     len = strlen(s);
     for (i = 0; i < len; i++) {
         if (s[i] == '_') {
@@ -269,7 +278,7 @@ char *get_cmpname(int nid, int index) {
         name = OPENSSL_strndup(s + i, len - i);
         break;
     default:
-        name = NULL;
+        break;
     }
 
     return name;
@@ -288,6 +297,11 @@ int get_oqsalg_idx(int nid) {
 static int oqsx_key_set_composites(OQSX_KEY *key) {
     int ret = 1;
 
+    if (key == NULL) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY);
+        return 0;
+    }
+
     OQS_KEY_PRINTF2("Setting composites with evp_info %p\n", key->evp_info);
 
     if (key->numkeys == 1) {
@@ -345,8 +359,10 @@ static int oqsx_key_set_composites(OQSX_KEY *key) {
             }
         }
     }
-err:
     return ret;
+
+err:
+    return 0;
 }
 
 PROV_OQS_CTX *oqsx_newprovctx(OSSL_LIB_CTX *libctx,
@@ -361,13 +377,17 @@ PROV_OQS_CTX *oqsx_newprovctx(OSSL_LIB_CTX *libctx,
 }
 
 void oqsx_freeprovctx(PROV_OQS_CTX *ctx) {
-    OSSL_LIB_CTX_free(ctx->libctx);
-    BIO_meth_free(ctx->corebiometh);
-    OPENSSL_free(ctx);
+    if (ctx) {
+        OSSL_LIB_CTX_free(ctx->libctx);
+        BIO_meth_free(ctx->corebiometh);
+        OPENSSL_free(ctx);
+    }
 }
 
 void oqsx_key_set0_libctx(OQSX_KEY *key, OSSL_LIB_CTX *libctx) {
-    key->libctx = libctx;
+    if (key) {
+        key->libctx = libctx;
+    }
 }
 
 /* convenience function creating OQSX keys from nids (only for sigs) */
@@ -375,7 +395,7 @@ static OQSX_KEY *oqsx_key_new_from_nid(OSSL_LIB_CTX *libctx, const char *propq,
                                        int nid) {
     OQS_KEY_PRINTF2("Generating OQSX key for nid %d\n", nid);
 
-    char *tls_algname = (char *)OBJ_nid2sn(nid);
+    const char *tls_algname = OBJ_nid2sn(nid);
     OQS_KEY_PRINTF2("                    for tls_name %s\n", tls_algname);
 
     if (!tls_algname) {
@@ -403,27 +423,44 @@ EVP_PKEY *setECParams(EVP_PKEY *eck, int nid) {
                                          0x02, 0x08, 0x01, 0x01, 0x0b};
 
     const unsigned char *params;
+    size_t params_len;
+    EVP_PKEY *result = NULL;
+
+    if (eck == NULL) {
+        return NULL;
+    }
+
     switch (nid) {
     case NID_X9_62_prime256v1:
         params = p256params;
-        return d2i_KeyParams(EVP_PKEY_EC, &eck, &params, sizeof(p256params));
+        params_len = sizeof(p256params);
+        break;
     case NID_secp384r1:
         params = p384params;
-        return d2i_KeyParams(EVP_PKEY_EC, &eck, &params, sizeof(p384params));
+        params_len = sizeof(p384params);
+        break;
     case NID_secp521r1:
         params = p521params;
-        return d2i_KeyParams(EVP_PKEY_EC, &eck, &params, sizeof(p521params));
+        params_len = sizeof(p521params);
+        break;
     case NID_brainpoolP256r1:
         params = bp256params;
-        return d2i_KeyParams(EVP_PKEY_EC, &eck, &params, sizeof(bp256params));
+        params_len = sizeof(bp256params);
+        break;
     case NID_brainpoolP384r1:
         params = bp384params;
-        return d2i_KeyParams(EVP_PKEY_EC, &eck, &params, sizeof(bp384params));
+        params_len = sizeof(bp384params);
+        break;
     default:
         return NULL;
     }
-}
 
+    result = d2i_KeyParams(EVP_PKEY_EC, &eck, &params, params_len);
+    if (result == NULL) {
+        EVP_PKEY_free(eck);
+    }
+    return result;
+}
 /* Key codes */
 
 static const OQSX_EVP_INFO nids_sig[] = {
@@ -460,6 +497,11 @@ static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx,
                             char *algname) {
     int ret = 1;
     int idx = (bit_security - 128) / 64;
+
+    if (evp_ctx == NULL || algname == NULL) {
+        return 0;
+    }
+
     ON_ERR_GOTO(idx < 0 || idx > 5, err_init);
 
     if (!strncmp(algname, "rsa", 3) || !strncmp(algname, "pss", 3)) {
@@ -487,10 +529,10 @@ static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx,
         ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err_init);
 
         ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype);
-        ON_ERR_SET_GOTO(ret <= 0, ret, -1, err_init);
+        ON_ERR_SET_GOTO(ret <= 0, ret, -1, free_key_param);
 
         evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL);
-        ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err_init);
+        ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, free_key_param);
     } else {
         evp_ctx->evp_info = &nids_sig[idx];
 
@@ -499,7 +541,7 @@ static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx,
 
         if (idx < 5) { // EC
             ret = EVP_PKEY_paramgen_init(evp_ctx->ctx);
-            ON_ERR_GOTO(ret <= 0, err_init);
+            ON_ERR_GOTO(ret <= 0, free_evp_ctx);
 
             ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(
                 evp_ctx->ctx, evp_ctx->evp_info->nid);
@@ -516,6 +558,12 @@ static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx,
     EVP_PKEY_CTX_free(evp_ctx->ctx);
     evp_ctx->ctx = NULL;
 
+free_key_param:
+    if (evp_ctx->keyParam) {
+        EVP_PKEY_free(evp_ctx->keyParam);
+        evp_ctx->keyParam = NULL;
+    }
+
 err_init:
     return ret;
 }
@@ -523,6 +571,11 @@ static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx,
 static const int oqshybkem_init_ecp(char *tls_name, OQSX_EVP_CTX *evp_ctx) {
     int ret = 1;
     int idx = 0;
+
+    if (tls_name == NULL || evp_ctx == NULL) {
+        return 0;
+    }
+
     while (idx < OSSL_NELEM(OQSX_ECP_NAMES)) {
         if (!strncmp(tls_name, OQSX_ECP_NAMES[idx], 4))
             break;
@@ -536,14 +589,20 @@ static const int oqshybkem_init_ecp(char *tls_name, OQSX_EVP_CTX *evp_ctx) {
     ON_ERR_GOTO(!evp_ctx->ctx, err_init_ecp);
 
     ret = EVP_PKEY_paramgen_init(evp_ctx->ctx);
-    ON_ERR_GOTO(ret <= 0, err_init_ecp);
+    ON_ERR_GOTO(ret <= 0, free_ctx);
 
     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx,
                                                  evp_ctx->evp_info->nid);
-    ON_ERR_GOTO(ret <= 0, err_init_ecp);
+    ON_ERR_GOTO(ret <= 0, free_ctx);
 
     ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam);
-    ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, err_init_ecp);
+    ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, free_ctx);
+
+    return ret;
+
+free_ctx:
+    EVP_PKEY_CTX_free(evp_ctx->ctx);
+    evp_ctx->ctx = NULL;
 
 err_init_ecp:
     return ret;
@@ -553,6 +612,10 @@ static const int oqshybkem_init_ecx(char *tls_name, OQSX_EVP_CTX *evp_ctx) {
     int ret = 1;
     int idx = 0;
 
+    if (tls_name == NULL || evp_ctx == NULL) {
+        return 0;
+    }
+
     while (idx < OSSL_NELEM(OQSX_ECX_NAMES)) {
         if (!strncmp(tls_name, OQSX_ECX_NAMES[idx], 4))
             break;
@@ -566,269 +629,334 @@ static const int oqshybkem_init_ecx(char *tls_name, OQSX_EVP_CTX *evp_ctx) {
     ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err_init_ecx);
 
     ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype);
-    ON_ERR_SET_GOTO(ret <= 0, ret, -1, err_init_ecx);
+    ON_ERR_SET_GOTO(ret <= 0, ret, -1, free_key_param);
 
     evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL);
-    ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err_init_ecx);
+    ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, free_key_param);
+
+    return ret;
+
+free_key_param:
+    EVP_PKEY_free(evp_ctx->keyParam);
+    evp_ctx->keyParam = NULL;
 
 err_init_ecx:
     return ret;
 }
 
-/* Re-create OQSX_KEY from encoding(s): Same end-state as after ken-gen */
-static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p,
-                             int plen, oqsx_key_op_t op, OSSL_LIB_CTX *libctx,
-                             const char *propq) {
-    OQSX_KEY *key = NULL;
-    void **privkey, **pubkey;
-    int nid = NID_undef;
-    int ret = 0;
+static int oqsx_key_process_composite_keys(OQSX_KEY *key,
+                                           const unsigned char *p, int plen) {
+    uint32_t privlen = 0;
+    size_t publen = 0, previous_privlen = 0, previous_publen = 0;
+    size_t temp_pub_len, temp_priv_len;
+    char *temp_priv = NULL, *temp_pub = NULL;
+    int pqc_pub_enc = 0, i;
 
-    OQS_KEY_PRINTF2("OQSX KEY: key_op called with data of len %d\n", plen);
-    if (palg != NULL) {
-        int ptype;
+    if (key == NULL || p == NULL || plen <= 0) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
 
-        /* Algorithm parameters must be absent */
-        X509_ALGOR_get0(NULL, &ptype, NULL, palg);
-        if (ptype != V_ASN1_UNDEF || !palg || !palg->algorithm) {
+    for (i = 0; i < key->numkeys; i++) {
+        char *name = get_cmpname(OBJ_sn2nid(key->tls_name), i);
+        if (name == NULL) {
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             return 0;
         }
-        nid = OBJ_obj2nid(palg->algorithm);
+        privlen = key->privkeylen_cmp[i];
+        publen = (get_oqsname_fromtls(name) == 0) ? 0 : key->pubkeylen_cmp[i];
+        previous_privlen += privlen;
+        previous_publen += publen;
+        OPENSSL_free(name);
     }
 
-    if (p == NULL || nid == EVP_PKEY_NONE || nid == NID_undef) {
-        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+    if (previous_privlen != plen) {
+        pqc_pub_enc = 1;
+        if (previous_privlen + previous_publen != plen) {
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+            return 0;
+        }
+        if (oqsx_key_allocate_keymaterial(key, 0)) {
+            ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    if (oqsx_key_allocate_keymaterial(key, 1)) {
+        ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
-    key = oqsx_key_new_from_nid(libctx, propq, nid);
-    if (key == NULL) {
+    temp_priv_len = previous_privlen;
+    temp_pub_len = previous_publen;
+    temp_priv = OPENSSL_secure_zalloc(temp_priv_len);
+    temp_pub = OPENSSL_secure_zalloc(temp_pub_len);
+    if (!temp_priv || !temp_pub) {
+        OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
+        OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
         ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
         return 0;
     }
-    OQS_KEY_PRINTF2("OQSX KEY: Recreated OQSX key %s\n", key->tls_name);
 
-    if (op == KEY_OP_PUBLIC) {
-        if (key->pubkeylen != plen) {
+    previous_privlen = previous_publen = 0;
+    for (i = 0; i < key->numkeys; i++) {
+        char *name = get_cmpname(OBJ_sn2nid(key->tls_name), i);
+        if (name == NULL) {
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-            goto err_key_op;
-        }
-        if (oqsx_key_allocate_keymaterial(key, 0)) {
-            ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
-            goto err_key_op;
+            OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
+            OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
+            return 0;
         }
-        memcpy(key->pubkey, p, plen);
-    } else {
-        uint32_t classical_privatekey_len = 0;
-        // for plain OQS keys, we expect OQS priv||OQS pub key
-        size_t actualprivkeylen = key->privkeylen;
-        // for hybrid keys, we expect classic priv key||OQS priv key||OQS
-        // pub key classic pub key must/can be re-created from classic
-        // private key
-        if (key->keytype == KEY_TYPE_CMP_SIG) {
-            uint32_t privlen = 0;
-            size_t publen = 0;
-            size_t previous_privlen = 0;
-            size_t previous_publen = 0;
-            size_t temp_pub_len, temp_priv_len;
-            char *temp_priv, *temp_pub;
-            int pqc_pub_enc = 0;
-            int i;
 
-            // check if key is the right size
-            for (i = 0; i < key->numkeys; i++) {
-                char *name;
-                if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) ==
-                    NULL) {
-                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                    goto err_key_op;
-                }
-                privlen = key->privkeylen_cmp[i];
-                if (get_oqsname_fromtls(name) == 0) { // classical key
-                    publen = 0;
-                } else {                            // PQC key
-                    publen = key->pubkeylen_cmp[i]; // pubkey in
-                                                    // PQC privkey
-                                                    // is OPTIONAL
-                }
-                previous_privlen += privlen;
-                previous_publen += publen;
-                OPENSSL_free(name);
-            }
-            if (previous_privlen != plen) {
-                // is ok, PQC pubkey might be in privkey
-                pqc_pub_enc = 1;
-                if (previous_privlen + previous_publen != plen) {
+        if (get_oqsname_fromtls(name) == 0) {
+            publen = 0;
+            if (key->oqsx_provider_ctx.oqsx_evp_ctx != NULL &&
+                key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info != NULL &&
+                key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->keytype ==
+                    EVP_PKEY_RSA) {
+                if (previous_privlen + previous_publen + 4 > plen) {
+                    OPENSSL_free(name);
+                    OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
+                    OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
                     ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                    goto err_key_op;
+                    return 0;
                 }
-                if (oqsx_key_allocate_keymaterial(key, 0)) {
-                    ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
-                    goto err_key_op;
-                }
-            }
-            if (oqsx_key_allocate_keymaterial(key, 1)) {
-                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
-                goto err_key_op;
-            }
-            temp_priv_len = previous_privlen;
-            temp_pub_len = previous_publen;
-            temp_priv = OPENSSL_secure_zalloc(temp_priv_len);
-            temp_pub = OPENSSL_secure_zalloc(temp_pub_len);
-            previous_privlen = 0;
-            previous_publen = 0;
-            for (i = 0; i < key->numkeys; i++) {
-                size_t classic_publen = 0;
-                char *name;
-                if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) ==
-                    NULL) {
-                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                unsigned char *enc_len = (unsigned char *)OPENSSL_strndup(
+                    (const char *)(p + previous_privlen + previous_publen), 4);
+                if (enc_len == NULL) {
+                    OPENSSL_free(name);
                     OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
                     OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
-                    goto err_key_op;
-                }
-                if (get_oqsname_fromtls(name) == 0) { // classical key
-                    publen = 0; // no pubkey encoded with privkey
-                                // on classical keys. will
-                                // recreate the pubkey later
-                    if (key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
-                            ->keytype ==
-                        EVP_PKEY_RSA) { // get the RSA real key size
-                        if (previous_privlen + previous_publen + 4 > plen) {
-                            OPENSSL_free(name);
-                            OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
-                            OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
-                            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                            goto err_key_op;
-                        }
-                        unsigned char *enc_len =
-                            (unsigned char *)OPENSSL_strndup(
-                                (const char *)(p + previous_privlen +
-                                               previous_publen),
-                                4);
-                        OPENSSL_cleanse(enc_len, 2);
-                        DECODE_UINT32(privlen, enc_len);
-                        privlen += 4;
-                        OPENSSL_free(enc_len);
-                        if (privlen > key->privkeylen_cmp[i]) {
-                            OPENSSL_free(name);
-                            OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
-                            OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
-                            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                            goto err_key_op;
-                        }
-                        key->privkeylen_cmp[i] = privlen;
-                    } else
-                        privlen = key->privkeylen_cmp[i];
-                } else { // PQC key
-                    privlen = key->privkeylen_cmp[i];
-                    if (pqc_pub_enc)
-                        publen = key->pubkeylen_cmp[i];
-                    else
-                        publen = 0;
+                    ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                    return 0;
                 }
-                if (previous_privlen + previous_publen + privlen > plen) {
+                OPENSSL_cleanse(enc_len, 2);
+                DECODE_UINT32(privlen, enc_len);
+                privlen += 4;
+                OPENSSL_free(enc_len);
+                if (privlen > key->privkeylen_cmp[i]) {
                     OPENSSL_free(name);
                     OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
                     OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
                     ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                    goto err_key_op;
+                    return 0;
                 }
-                memcpy(temp_priv + previous_privlen,
-                       p + previous_privlen + previous_publen, privlen);
-                memcpy(temp_pub + previous_publen,
-                       p + privlen + previous_privlen + previous_publen,
-                       publen);
-                previous_privlen += privlen;
-                previous_publen += publen;
-                OPENSSL_free(name);
+                key->privkeylen_cmp[i] = privlen;
+            } else {
+                privlen = key->privkeylen_cmp[i];
             }
-            memcpy(key->privkey, temp_priv, previous_privlen);
-            memcpy(key->pubkey, temp_pub, previous_publen);
+        } else {
+            privlen = key->privkeylen_cmp[i];
+            publen = pqc_pub_enc ? key->pubkeylen_cmp[i] : 0;
+        }
+
+        if (previous_privlen + previous_publen + privlen > plen) {
+            OPENSSL_free(name);
             OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
             OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
-        } else {
-            if (key->numkeys == 2) {
-                size_t expected_pq_privkey_len =
-                    key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_secret_key;
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+            return 0;
+        }
+
+        memcpy(temp_priv + previous_privlen,
+               p + previous_privlen + previous_publen, privlen);
+        memcpy(temp_pub + previous_publen,
+               p + privlen + previous_privlen + previous_publen, publen);
+        previous_privlen += privlen;
+        previous_publen += publen;
+        OPENSSL_free(name);
+    }
+
+    memcpy(key->privkey, temp_priv, previous_privlen);
+    memcpy(key->pubkey, temp_pub, previous_publen);
+    OPENSSL_secure_clear_free(temp_priv, temp_priv_len);
+    OPENSSL_secure_clear_free(temp_pub, temp_pub_len);
+
+    return 1;
+}
+
+/* Re-create OQSX_KEY from encoding(s): Same end-state as after ken-gen */
+static int allocate_and_copy_keymaterial(OQSX_KEY *key, const unsigned char *p,
+                                         int plen, int is_private) {
+    if (key == NULL || p == NULL || plen <= 0) {
+        ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (oqsx_key_allocate_keymaterial(key, is_private)) {
+        ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    unsigned char *dest = is_private ? key->privkey : key->pubkey;
+    if (dest == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    memcpy(dest, p, plen);
+    return 1;
+}
+
+static int process_hybrid_key(OQSX_KEY *key, const unsigned char *p, int plen,
+                              uint32_t *classical_privatekey_len) {
+    if (key == NULL || p == NULL || classical_privatekey_len == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    size_t expected_pq_privkey_len =
+        key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_secret_key;
 #ifndef NOPUBKEY_IN_PRIVKEY
-                expected_pq_privkey_len +=
-                    key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key;
+    expected_pq_privkey_len +=
+        key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key;
 #endif
-                if (plen > (SIZE_OF_UINT32 + expected_pq_privkey_len)) {
-                    size_t max_classical_privkey_len =
-                        key->evp_info->length_private_key;
-                    size_t space_for_classical_privkey =
-                        plen - expected_pq_privkey_len - SIZE_OF_UINT32;
-                    if (space_for_classical_privkey >
-                        max_classical_privkey_len) {
-                        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                        goto err_key_op;
-                    }
-                    DECODE_UINT32(classical_privatekey_len,
-                                  p); // actual classic key len
-                    if (classical_privatekey_len !=
-                        space_for_classical_privkey) {
-                        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                        goto err_key_op;
-                    }
-                } else {
-                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                    goto err_key_op;
-                }
-                actualprivkeylen -= (key->evp_info->length_private_key -
-                                     classical_privatekey_len);
-            }
+    if (plen <= (SIZE_OF_UINT32 + expected_pq_privkey_len)) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (key->evp_info == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    size_t max_classical_privkey_len = key->evp_info->length_private_key;
+    size_t space_for_classical_privkey =
+        plen - expected_pq_privkey_len - SIZE_OF_UINT32;
+    if (space_for_classical_privkey > max_classical_privkey_len) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    DECODE_UINT32(*classical_privatekey_len, p);
+    if (*classical_privatekey_len != space_for_classical_privkey) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int process_private_key(OQSX_KEY *key, const unsigned char *p,
+                               int plen) {
+    if (key == NULL || p == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    size_t actualprivkeylen = key->privkeylen;
+    uint32_t classical_privatekey_len = 0;
+
+    if (key->numkeys == 2) {
+        if (!process_hybrid_key(key, p, plen, &classical_privatekey_len)) {
+            return 0;
+        }
+        actualprivkeylen -=
+            (key->evp_info->length_private_key - classical_privatekey_len);
+    }
+
 #ifdef NOPUBKEY_IN_PRIVKEY
-            if (actualprivkeylen != plen) {
-                OQS_KEY_PRINTF3("OQSX KEY: private key with "
-                                "unexpected length %d vs %d\n",
-                                plen, (int)(actualprivkeylen));
+    if (actualprivkeylen != plen) {
+        OQS_KEY_PRINTF3(
+            "OQSX KEY: private key with unexpected length %d vs %d\n", plen,
+            (int)(actualprivkeylen));
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
 #else
-            if (actualprivkeylen + oqsx_key_get_oqs_public_key_len(key) !=
-                plen) {
-                OQS_KEY_PRINTF3("OQSX KEY: private key with unexpected length "
-                                "%d vs %d\n",
-                                plen,
-                                (int)(actualprivkeylen +
-                                      oqsx_key_get_oqs_public_key_len(key)));
+    if (actualprivkeylen + oqsx_key_get_oqs_public_key_len(key) != plen) {
+        OQS_KEY_PRINTF3(
+            "OQSX KEY: private key with unexpected length %d vs %d\n", plen,
+            (int)(actualprivkeylen + oqsx_key_get_oqs_public_key_len(key)));
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
 #endif
-                ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
-                goto err_key_op;
-            }
-            if (oqsx_key_allocate_keymaterial(key, 1)
+
+    if (!allocate_and_copy_keymaterial(key, p, actualprivkeylen, 1)) {
+        return 0;
+    }
+
 #ifndef NOPUBKEY_IN_PRIVKEY
-                || oqsx_key_allocate_keymaterial(key, 0)
+    if (oqsx_key_get_oqs_public_key_len(key) != plen - actualprivkeylen) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (!allocate_and_copy_keymaterial(key, p + actualprivkeylen,
+                                       plen - actualprivkeylen, 0)) {
+        OPENSSL_clear_free(key->privkey, actualprivkeylen);
+        key->privkey = NULL;
+        return 0;
+    }
+
+    if (key->numkeys == 2) {
+        unsigned char *pubkey = (unsigned char *)key->pubkey;
+        if (pubkey != NULL) {
+            ENCODE_UINT32(pubkey, key->evp_info->length_public_key);
+            memcpy(pubkey + SIZE_OF_UINT32 + key->evp_info->length_public_key,
+                   p + actualprivkeylen, plen - actualprivkeylen);
+        }
+    }
 #endif
-            ) {
-                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+
+    return 1;
+}
+
+static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p,
+                             int plen, oqsx_key_op_t op, OSSL_LIB_CTX *libctx,
+                             const char *propq) {
+    OQSX_KEY *key = NULL;
+    int nid = NID_undef;
+
+    OQS_KEY_PRINTF2("OQSX KEY: key_op called with data of len %d\n", plen);
+    if (palg != NULL) {
+        int ptype;
+
+        X509_ALGOR_get0(NULL, &ptype, NULL, palg);
+        if (ptype != V_ASN1_UNDEF || !palg->algorithm) {
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+            return NULL;
+        }
+        nid = OBJ_obj2nid(palg->algorithm);
+    }
+
+    if (p == NULL || nid == EVP_PKEY_NONE || nid == NID_undef) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return NULL;
+    }
+
+    key = oqsx_key_new_from_nid(libctx, propq, nid);
+    if (key == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    OQS_KEY_PRINTF2("OQSX KEY: Recreated OQSX key %s\n", key->tls_name);
+
+    if (op == KEY_OP_PUBLIC) {
+        if (key->pubkeylen != plen) {
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+            goto err_key_op;
+        }
+        if (!allocate_and_copy_keymaterial(key, p, plen, 0)) {
+            goto err_key_op;
+        }
+    } else {
+        if (key->keytype == KEY_TYPE_CMP_SIG) {
+            if (!oqsx_key_process_composite_keys(key, p, plen)) {
                 goto err_key_op;
             }
-            // first populate private key data
-            memcpy(key->privkey, p, actualprivkeylen);
-#ifndef NOPUBKEY_IN_PRIVKEY
-            // only enough data to fill public OQS key component
-            if (oqsx_key_get_oqs_public_key_len(key) !=
-                plen - actualprivkeylen) {
-                ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        } else {
+            if (!process_private_key(key, p, plen)) {
                 goto err_key_op;
             }
-            // populate OQS public key structure
-            if (key->numkeys == 2) {
-                unsigned char *pubkey = (unsigned char *)key->pubkey;
-                ENCODE_UINT32(pubkey, key->evp_info->length_public_key);
-                memcpy(pubkey + SIZE_OF_UINT32 +
-                           key->evp_info->length_public_key,
-                       p + actualprivkeylen, plen - actualprivkeylen);
-            } else
-                memcpy(key->pubkey, p + key->privkeylen,
-                       plen - key->privkeylen);
-#endif
         }
     }
-    if (!oqsx_key_set_composites(key) || !oqsx_key_recreate_classickey(key, op))
+
+    if (!oqsx_key_set_composites(key) ||
+        !oqsx_key_recreate_classickey(key, op)) {
         goto err_key_op;
+    }
 
     return key;
 
@@ -839,11 +967,16 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p,
 
 /* Recreate EVP data structure after import. RetVal 0 is error. */
 static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
+    if (key == NULL || key->tls_name == NULL) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return 0;
+    }
+
     if (key->keytype == KEY_TYPE_CMP_SIG) {
         int i;
         if (op == KEY_OP_PUBLIC) {
             for (i = 0; i < key->numkeys; i++) {
-                char *name;
+                char *name = NULL;
                 if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) ==
                     NULL) {
                     ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
@@ -852,24 +985,44 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
                 const unsigned char *enc_pubkey = key->comp_pubkey[i];
 
                 if (get_oqsname_fromtls(name) == 0) {
+                    if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL ||
+                        key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info == NULL) {
+                        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                        OPENSSL_free(name);
+                        goto rec_err;
+                    }
                     if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                              ->raw_key_support) {
                         EVP_PKEY *npk = EVP_PKEY_new();
+                        if (npk == NULL) {
+                            ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                            OPENSSL_free(name);
+                            goto rec_err;
+                        }
                         if (key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                                 ->keytype != EVP_PKEY_RSA) {
                             npk = setECParams(npk,
                                               key->oqsx_provider_ctx
                                                   .oqsx_evp_ctx->evp_info->nid);
+                            if (npk == NULL) {
+                                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                                OPENSSL_free(name);
+                                goto rec_err;
+                            }
                         }
                         key->classical_pkey = d2i_PublicKey(
                             key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                                 ->keytype,
                             &npk, &enc_pubkey, key->pubkeylen_cmp[i]);
-                    } else
+                        if (key->classical_pkey == NULL) {
+                            EVP_PKEY_free(npk);
+                        }
+                    } else {
                         key->classical_pkey = EVP_PKEY_new_raw_public_key(
                             key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                                 ->keytype,
                             NULL, enc_pubkey, key->pubkeylen_cmp[i]);
+                    }
                     if (!key->classical_pkey) {
                         ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
                         OPENSSL_free(name);
@@ -882,7 +1035,7 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
 
         if (op == KEY_OP_PRIVATE) {
             for (i = 0; i < key->numkeys; i++) {
-                char *name;
+                char *name = NULL;
                 if ((name = get_cmpname(OBJ_sn2nid(key->tls_name), i)) ==
                     NULL) {
                     ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
@@ -890,9 +1043,14 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
                 }
                 if (get_oqsname_fromtls(name) == 0) {
                     const unsigned char *enc_privkey = key->comp_privkey[i];
+                    if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL ||
+                        key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info == NULL) {
+                        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                        OPENSSL_free(name);
+                        goto rec_err;
+                    }
                     if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                              ->raw_key_support) {
-                        EVP_PKEY *npk;
                         key->classical_pkey = d2i_PrivateKey(
                             key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                                 ->keytype,
@@ -959,8 +1117,16 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
                     }
                 } else {
                     EVP_PKEY *npk = EVP_PKEY_new();
+                    if (npk == NULL) {
+                        ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                        goto rec_err;
+                    }
                     if (key->evp_info->keytype != EVP_PKEY_RSA) {
                         npk = setECParams(npk, key->evp_info->nid);
+                        if (npk == NULL) {
+                            ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                            goto rec_err;
+                        }
                     }
                     key->classical_pkey =
                         d2i_PublicKey(key->evp_info->keytype, &npk, &enc_pubkey,
@@ -989,10 +1155,8 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
                         goto rec_err;
                     }
 #ifndef NOPUBKEY_IN_PRIVKEY
-                    // re-create classic public key part from
-                    // private key:
+                    // re-create classic public key part from private key:
                     size_t pubkeylen;
-
                     EVP_PKEY_get_raw_public_key(key->classical_pkey, NULL,
                                                 &pubkeylen);
                     if (pubkeylen != key->evp_info->length_public_key ||
@@ -1011,8 +1175,7 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
                         goto rec_err;
                     }
 #ifndef NOPUBKEY_IN_PRIVKEY
-                    // re-create classic public key part from
-                    // private key:
+                    // re-create classic public key part from private key:
                     int pubkeylen =
                         i2d_PublicKey(key->classical_pkey, &enc_pubkey);
                     if (pubkeylen != key->evp_info->length_public_key) {
@@ -1028,54 +1191,72 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
     return 1;
 
 rec_err:
+    if (key->classical_pkey) {
+        EVP_PKEY_free(key->classical_pkey);
+        key->classical_pkey = NULL;
+    }
     return 0;
 }
 
 OQSX_KEY *oqsx_key_from_x509pubkey(const X509_PUBKEY *xpk, OSSL_LIB_CTX *libctx,
                                    const char *propq) {
-    const unsigned char *p;
+    const unsigned char *p = NULL;
     int plen;
-    X509_ALGOR *palg;
+    X509_ALGOR *palg = NULL;
     OQSX_KEY *oqsx = NULL;
     STACK_OF(ASN1_TYPE) *sk = NULL;
     ASN1_TYPE *aType = NULL;
     ASN1_OCTET_STRING *oct = NULL;
     const unsigned char *buf;
-    unsigned char *concat_key;
+    unsigned char *concat_key = NULL;
     int count, aux, i, buflen;
 
     if (!xpk || (!X509_PUBKEY_get0_param(NULL, &p, &plen, &palg, xpk))) {
         return NULL;
     }
+    if (palg == NULL || palg->algorithm == NULL) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+        return NULL;
+    }
     if (get_keytype(OBJ_obj2nid(palg->algorithm)) == KEY_TYPE_CMP_SIG) {
         sk = d2i_ASN1_SEQUENCE_ANY(NULL, &p, plen);
         if (sk == NULL) {
-            sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free);
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             return NULL;
         } else {
             count = sk_ASN1_TYPE_num(sk);
-            concat_key =
-                OPENSSL_zalloc(plen); // concat_key is allocated with plen,
-                                      // which is the max value for pubkey
+            concat_key = OPENSSL_zalloc(plen);
+            if (concat_key == NULL) {
+                sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                return NULL;
+            }
 
             aux = 0;
             for (i = 0; i < count; i++) {
-                aType =
-                    sk_ASN1_TYPE_pop(sk); // this remove in FILO order, but we
-                                          // need this in the opposite order
+                aType = sk_ASN1_TYPE_pop(sk);
+                if (aType == NULL || aType->value.sequence == NULL) {
+                    OPENSSL_clear_free(concat_key, plen);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                    return NULL;
+                }
                 buf = aType->value.sequence->data;
                 buflen = aType->value.sequence->length;
                 aux += buflen;
-                memcpy(concat_key + plen - 1 - aux, buf,
-                       buflen); // fill concat_key starting at the end
+                memcpy(concat_key + plen - 1 - aux, buf, buflen);
                 ASN1_TYPE_free(aType);
             }
 
-            p = OPENSSL_memdup(concat_key + plen - 1 - aux,
-                               aux); // copy used memory on concat_key to p
+            p = OPENSSL_memdup(concat_key + plen - 1 - aux, aux);
+            if (p == NULL) {
+                OPENSSL_clear_free(concat_key, plen);
+                sk_ASN1_TYPE_free(sk);
+                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                return NULL;
+            }
             OPENSSL_clear_free(concat_key, plen);
-            plen = aux; // update plen value
+            plen = aux;
             sk_ASN1_TYPE_free(sk);
         }
     }
@@ -1088,18 +1269,21 @@ OQSX_KEY *oqsx_key_from_x509pubkey(const X509_PUBKEY *xpk, OSSL_LIB_CTX *libctx,
 OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                               OSSL_LIB_CTX *libctx, const char *propq) {
     OQSX_KEY *oqsx = NULL;
-    const unsigned char *p;
+    const unsigned char *p = NULL;
     int plen;
     ASN1_OCTET_STRING *oct = NULL;
-    const X509_ALGOR *palg;
+    const X509_ALGOR *palg = NULL;
     STACK_OF(ASN1_TYPE) *sk = NULL;
     ASN1_TYPE *aType = NULL;
-    unsigned char *concat_key;
+    unsigned char *concat_key = NULL;
     const unsigned char *buf;
     int count, aux, i, buflen, key_diff = 0;
 
     if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf))
-        return 0;
+        return NULL;
+
+    if (palg == NULL)
+        return NULL;
 
     if (get_keytype(OBJ_obj2nid(palg->algorithm)) != KEY_TYPE_CMP_SIG) {
         oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
@@ -1113,23 +1297,38 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
     } else {
         sk = d2i_ASN1_SEQUENCE_ANY(NULL, &p, plen);
         if (sk == NULL) {
-            sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free);
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             return NULL;
         } else {
             count = sk_ASN1_TYPE_num(sk);
             plen = 2 * plen; // get more than necessary in case its needed
             concat_key = OPENSSL_zalloc(plen);
+            if (concat_key == NULL) {
+                sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                return NULL;
+            }
             PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL;
             const X509_ALGOR *palg_internal;
             int keytype, nid;
 
             aux = 0;
             for (i = 0; i < count; i++) {
-                aType =
-                    sk_ASN1_TYPE_pop(sk); // this remove in FILO order, but we
-                                          // need this in the opposite order
+                aType = sk_ASN1_TYPE_pop(sk);
+                if (aType == NULL) {
+                    OPENSSL_clear_free(concat_key, plen);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                    return NULL;
+                }
                 p8inf_internal = PKCS8_PRIV_KEY_INFO_new();
+                if (p8inf_internal == NULL) {
+                    ASN1_TYPE_free(aType);
+                    OPENSSL_clear_free(concat_key, plen);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                    ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                    return NULL;
+                }
                 nid = 0;
                 char *name;
                 if ((name = get_cmpname(OBJ_obj2nid(palg->algorithm),
@@ -1137,7 +1336,16 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                     ASN1_TYPE_free(aType);
                     OPENSSL_clear_free(concat_key, plen);
                     PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
-                    sk_ASN1_TYPE_free(sk);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                    return NULL;
+                }
+                if (aType->value.sequence == NULL) {
+                    OPENSSL_free(name);
+                    ASN1_TYPE_free(aType);
+                    OPENSSL_clear_free(concat_key, plen);
+                    PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
                     ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
                     return NULL;
                 }
@@ -1152,7 +1360,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                     ASN1_TYPE_free(aType);
                     PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
                     OPENSSL_clear_free(concat_key, plen);
-                    sk_ASN1_TYPE_free(sk);
+                    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
                     return NULL;
                 }
 
@@ -1161,75 +1369,74 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                 // Checking OPTIONAL params on EC
                 if (keytype == EVP_PKEY_EC) {
                     int j;
+                    if (palg_internal->parameter == NULL ||
+                        palg_internal->parameter->value.object == NULL) {
+                        OPENSSL_free(name);
+                        ASN1_TYPE_free(aType);
+                        PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
+                        OPENSSL_clear_free(concat_key, plen);
+                        sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                        return NULL;
+                    }
                     nid = OBJ_obj2nid(palg_internal->parameter->value.object);
                     for (j = 0; j < OSSL_NELEM(nids_sig); j++) {
                         if ((nids_sig[j].nid == nid) &&
-                            (nids_sig[j].length_private_key >
-                             buflen)) { // check if the curve is the
-                                        // same and if the key len is
-                                        // smaller than the max key
-                                        // size
-                            EVP_PKEY *ec_pkey;
+                            (nids_sig[j].length_private_key > buflen)) {
+                            EVP_PKEY *ec_pkey = NULL;
                             OSSL_PARAM params[3];
                             int include_pub = 1;
                             const unsigned char *buf3 =
                                 aType->value.sequence->data;
-                            unsigned char *buf4, *buf5;
+                            unsigned char *buf4 = NULL, *buf5 = NULL;
 
-                            if (buflen != nids_sig[j].kex_length_secret +
-                                              7) { // no OPTIONAL
-                                                   // ECParameter and no
-                                                   // OPTIONAL Pubkey
+                            if (buflen != nids_sig[j].kex_length_secret + 7) {
                                 OPENSSL_free(name);
                                 ASN1_TYPE_free(aType);
                                 PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
                                 OPENSSL_clear_free(concat_key, plen);
-                                sk_ASN1_TYPE_free(sk);
+                                sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
                                 return NULL;
                             }
                             ec_pkey = EVP_PKEY_new();
-                            d2i_PrivateKey(
-                                EVP_PKEY_EC, &ec_pkey, &buf3,
-                                aType->value.sequence->length); // create
-                                                                // a new
-                                                                // EVP_PKEY
-                                                                // using
-                                                                // ec
-                                                                // priv
-                                                                // key
-
-                            // set parameters for the
-                            // new priv key format
+                            if (ec_pkey == NULL) {
+                                OPENSSL_free(name);
+                                ASN1_TYPE_free(aType);
+                                PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
+                                OPENSSL_clear_free(concat_key, plen);
+                                sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                                return NULL;
+                            }
+                            d2i_PrivateKey(EVP_PKEY_EC, &ec_pkey, &buf3,
+                                           aType->value.sequence->length);
+
                             params[0] = OSSL_PARAM_construct_int(
                                 OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC,
-                                &include_pub); // add
-                                               // pubkey
-                                               // to
-                                               // priv
-                                               // key
+                                &include_pub);
                             params[1] = OSSL_PARAM_construct_utf8_string(
                                 OSSL_PKEY_PARAM_EC_ENCODING,
-                                OSSL_PKEY_EC_ENCODING_GROUP,
-                                0); // add ECParam to
-                                    // the priv key
+                                OSSL_PKEY_EC_ENCODING_GROUP, 0);
                             params[2] = OSSL_PARAM_construct_end();
                             EVP_PKEY_set_params(ec_pkey, params);
 
                             buf4 =
                                 OPENSSL_malloc(nids_sig[j].length_private_key);
+                            if (buf4 == NULL) {
+                                EVP_PKEY_free(ec_pkey);
+                                OPENSSL_free(name);
+                                ASN1_TYPE_free(aType);
+                                PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
+                                OPENSSL_clear_free(concat_key, plen);
+                                sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+                                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                                return NULL;
+                            }
                             buf5 = buf4;
-                            buflen = i2d_PrivateKey(ec_pkey,
-                                                    &buf5); // encode priv
-                                                            // key
-                                                            // including
-                                                            // parameters
+                            buflen = i2d_PrivateKey(ec_pkey, &buf5);
 
                             aux += buflen;
-                            memcpy(concat_key + plen - 1 - aux, buf4,
-                                   buflen); // fill
-                                            // concat_key
-                                            // starting at
-                                            // the end
+                            memcpy(concat_key + plen - 1 - aux, buf4, buflen);
 
                             EVP_PKEY_free(ec_pkey);
                             OPENSSL_clear_free(buf4, buflen);
@@ -1237,27 +1444,19 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                         }
                     }
                     if (j == OSSL_NELEM(nids_sig))
-                        nid = 0; // buflen is already with the
-                                 // correct size, changing nid
-                                 // to memcpy at the end
+                        nid = 0;
                 }
 
-                // if is a RSA key the actual encoding size might
-                // be different from max size we calculate that
-                // difference for to facilitate the key
-                // reconstruction
                 if (keytype == EVP_PKEY_RSA) {
-                    if (name[3] == '3') // 3072
+                    if (name[3] == '3')
                         key_diff = nids_sig[5].length_private_key - buflen;
-                    else // 2048
+                    else
                         key_diff = nids_sig[6].length_private_key - buflen;
                 }
 
                 if (!nid) {
                     aux += buflen;
-                    memcpy(concat_key + plen - 1 - aux, buf,
-                           buflen); // fill concat_key
-                                    // starting at the end
+                    memcpy(concat_key + plen - 1 - aux, buf, buflen);
                 }
 
                 OPENSSL_free(name);
@@ -1266,8 +1465,14 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
             }
 
             p = OPENSSL_memdup(concat_key + plen - 1 - aux, aux);
+            if (p == NULL) {
+                OPENSSL_clear_free(concat_key, plen);
+                sk_ASN1_TYPE_free(sk);
+                ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+                return NULL;
+            }
             OPENSSL_clear_free(concat_key, plen);
-            plen = aux; // update plen to correct size
+            plen = aux;
             sk_ASN1_TYPE_free(sk);
         }
     }
@@ -1276,8 +1481,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
     if (get_keytype(OBJ_obj2nid(palg->algorithm)) != KEY_TYPE_CMP_SIG) {
         ASN1_OCTET_STRING_free(oct);
     } else {
-        OPENSSL_clear_free((unsigned char *)p,
-                           plen); // for COMPOSITE p include both privkey
+        OPENSSL_clear_free((unsigned char *)p, plen);
     }
     return oqsx;
 }
@@ -1302,13 +1506,8 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
     ON_ERR_GOTO(!ret->lock, err);
 #endif
 
-    if (oqs_name == NULL) {
-        OQS_KEY_PRINTF("OQSX_KEY: Fatal error: No OQS key name provided:\n");
-        goto err;
-    }
-
-    if (tls_name == NULL) {
-        OQS_KEY_PRINTF("OQSX_KEY: Fatal error: No TLS key name provided:\n");
+    if (oqs_name == NULL || tls_name == NULL) {
+        ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
         goto err;
     }
 
@@ -1321,11 +1520,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
         ret->oqsx_provider_ctx.oqsx_evp_ctx = NULL;
         ret->oqsx_provider_ctx.oqsx_qs_ctx.sig = OQS_SIG_new(oqs_name);
         if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
-            fprintf(stderr,
-                    "Could not create OQS signature algorithm %s. "
-                    "Enabled in "
-                    "liboqs?\n",
-                    oqs_name);
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             goto err;
         }
 
@@ -1343,10 +1538,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
         ret->oqsx_provider_ctx.oqsx_evp_ctx = NULL;
         ret->oqsx_provider_ctx.oqsx_qs_ctx.kem = OQS_KEM_new(oqs_name);
         if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.kem) {
-            fprintf(stderr,
-                    "Could not create OQS KEM algorithm %s. Enabled "
-                    "in liboqs?\n",
-                    oqs_name);
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             goto err;
         }
         ret->privkeylen =
@@ -1359,10 +1551,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
     case KEY_TYPE_ECP_HYB_KEM:
         ret->oqsx_provider_ctx.oqsx_qs_ctx.kem = OQS_KEM_new(oqs_name);
         if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.kem) {
-            fprintf(stderr,
-                    "Could not create OQS KEM algorithm %s. Enabled "
-                    "in liboqs?\n",
-                    oqs_name);
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             goto err;
         }
         evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX));
@@ -1391,11 +1580,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
     case KEY_TYPE_HYB_SIG:
         ret->oqsx_provider_ctx.oqsx_qs_ctx.sig = OQS_SIG_new(oqs_name);
         if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
-            fprintf(stderr,
-                    "Could not create OQS signature algorithm %s. "
-                    "Enabled in "
-                    "liboqs?\n",
-                    oqs_name);
+            ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
             goto err;
         }
         evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX));
@@ -1428,6 +1613,9 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
         ret->pubkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(size_t));
         ret->comp_privkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
         ret->comp_pubkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
+        ON_ERR_GOTO(!ret->privkeylen_cmp || !ret->pubkeylen_cmp ||
+                        !ret->comp_privkey || !ret->comp_pubkey,
+                    err);
 
         for (i = 0; i < ret->numkeys; i++) {
             char *name;
@@ -1439,12 +1627,8 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
                 ret->oqsx_provider_ctx.oqsx_qs_ctx.sig =
                     OQS_SIG_new(get_oqsname_fromtls(name));
                 if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
-                    fprintf(stderr,
-                            "Could not create OQS signature "
-                            "algorithm %s. "
-                            "Enabled in "
-                            "liboqs?A\n",
-                            name);
+                    ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+                    OPENSSL_free(name);
                     goto err;
                 }
                 ret->privkeylen_cmp[i] =
@@ -1453,10 +1637,17 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
                     ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key;
             } else {
                 evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX));
-                ON_ERR_GOTO(!evp_ctx, err);
+                if (!evp_ctx) {
+                    OPENSSL_free(name);
+                    goto err;
+                }
 
                 ret2 = oqsx_hybsig_init(bit_security, evp_ctx, name);
-                ON_ERR_GOTO(ret2 <= 0 || !evp_ctx->ctx, err);
+                if (ret2 <= 0 || !evp_ctx->ctx) {
+                    OPENSSL_free(name);
+                    OPENSSL_free(evp_ctx);
+                    goto err;
+                }
                 ret->oqsx_provider_ctx.oqsx_evp_ctx = evp_ctx;
                 ret->privkeylen_cmp[i] = ret->oqsx_provider_ctx.oqsx_evp_ctx
                                              ->evp_info->length_private_key;
@@ -1471,8 +1662,7 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
 
         break;
     default:
-        OQS_KEY_PRINTF2("OQSX_KEY: Unknown key type encountered: %d\n",
-                        primitive);
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
         goto err;
     }
 
@@ -1487,21 +1677,30 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name,
         ON_ERR_GOTO(!ret->propq, err);
     }
 
-    OQS_KEY_PRINTF2("OQSX_KEY: new key created: %s\n", ret->tls_name);
-    OQS_KEY_PRINTF3("OQSX_KEY: new key created: %p (type: %d)\n", ret,
-                    ret->keytype);
     return ret;
 err:
-    ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
-#ifdef OQS_PROVIDER_NOATOMIC
-    if (ret->lock)
-        CRYPTO_THREAD_lock_free(ret->lock);
-#endif
     if (ret) {
         OPENSSL_free(ret->tls_name);
         OPENSSL_free(ret->propq);
         OPENSSL_free(ret->comp_privkey);
         OPENSSL_free(ret->comp_pubkey);
+        OPENSSL_free(ret->privkeylen_cmp);
+        OPENSSL_free(ret->pubkeylen_cmp);
+        if (ret->oqsx_provider_ctx.oqsx_qs_ctx.sig)
+            OQS_SIG_free(ret->oqsx_provider_ctx.oqsx_qs_ctx.sig);
+        if (ret->oqsx_provider_ctx.oqsx_qs_ctx.kem)
+            OQS_KEM_free(ret->oqsx_provider_ctx.oqsx_qs_ctx.kem);
+        if (ret->oqsx_provider_ctx.oqsx_evp_ctx) {
+            if (ret->oqsx_provider_ctx.oqsx_evp_ctx->ctx)
+                EVP_PKEY_CTX_free(ret->oqsx_provider_ctx.oqsx_evp_ctx->ctx);
+            if (ret->oqsx_provider_ctx.oqsx_evp_ctx->keyParam)
+                EVP_PKEY_free(ret->oqsx_provider_ctx.oqsx_evp_ctx->keyParam);
+            OPENSSL_free(ret->oqsx_provider_ctx.oqsx_evp_ctx);
+        }
+#ifdef OQS_PROVIDER_NOATOMIC
+        if (ret->lock)
+            CRYPTO_THREAD_lock_free(ret->lock);
+#endif
     }
     OPENSSL_free(ret);
     return NULL;
@@ -1529,32 +1728,47 @@ void oqsx_key_free(OQSX_KEY *key) {
     assert(refcnt == 0);
 #endif
 
-    OPENSSL_free(key->propq);
-    OPENSSL_free(key->tls_name);
-    OPENSSL_secure_clear_free(key->privkey, key->privkeylen);
-    OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen);
-    OPENSSL_free(key->comp_pubkey);
-    OPENSSL_free(key->comp_privkey);
+    if (key->propq)
+        OPENSSL_free(key->propq);
+    if (key->tls_name)
+        OPENSSL_free(key->tls_name);
+    if (key->privkey)
+        OPENSSL_secure_clear_free(key->privkey, key->privkeylen);
+    if (key->pubkey)
+        OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen);
+    if (key->comp_pubkey)
+        OPENSSL_free(key->comp_pubkey);
+    if (key->comp_privkey)
+        OPENSSL_free(key->comp_privkey);
     if (key->keytype == KEY_TYPE_CMP_SIG) {
-        OPENSSL_free(key->privkeylen_cmp);
-        OPENSSL_free(key->pubkeylen_cmp);
-    }
-    if (key->keytype == KEY_TYPE_KEM)
-        OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
-    else if (key->keytype == KEY_TYPE_ECP_HYB_KEM ||
-             key->keytype == KEY_TYPE_ECX_HYB_KEM) {
-        OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
-    } else
+        if (key->privkeylen_cmp)
+            OPENSSL_free(key->privkeylen_cmp);
+        if (key->pubkeylen_cmp)
+            OPENSSL_free(key->pubkeylen_cmp);
+    }
+    if (key->keytype == KEY_TYPE_KEM) {
+        if (key->oqsx_provider_ctx.oqsx_qs_ctx.kem)
+            OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
+    } else if (key->keytype == KEY_TYPE_ECP_HYB_KEM ||
+               key->keytype == KEY_TYPE_ECX_HYB_KEM) {
+        if (key->oqsx_provider_ctx.oqsx_qs_ctx.kem)
+            OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
+    } else if (key->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
         OQS_SIG_free(key->oqsx_provider_ctx.oqsx_qs_ctx.sig);
-    EVP_PKEY_free(key->classical_pkey);
+    }
+    if (key->classical_pkey)
+        EVP_PKEY_free(key->classical_pkey);
     if (key->oqsx_provider_ctx.oqsx_evp_ctx) {
-        EVP_PKEY_CTX_free(key->oqsx_provider_ctx.oqsx_evp_ctx->ctx);
-        EVP_PKEY_free(key->oqsx_provider_ctx.oqsx_evp_ctx->keyParam);
+        if (key->oqsx_provider_ctx.oqsx_evp_ctx->ctx)
+            EVP_PKEY_CTX_free(key->oqsx_provider_ctx.oqsx_evp_ctx->ctx);
+        if (key->oqsx_provider_ctx.oqsx_evp_ctx->keyParam)
+            EVP_PKEY_free(key->oqsx_provider_ctx.oqsx_evp_ctx->keyParam);
         OPENSSL_free(key->oqsx_provider_ctx.oqsx_evp_ctx);
     }
 
 #ifdef OQS_PROVIDER_NOATOMIC
-    CRYPTO_THREAD_lock_free(key->lock);
+    if (key->lock)
+        CRYPTO_THREAD_lock_free(key->lock);
 #endif
     OPENSSL_free(key);
 }
@@ -1562,6 +1776,10 @@ void oqsx_key_free(OQSX_KEY *key) {
 int oqsx_key_up_ref(OQSX_KEY *key) {
     int refcnt;
 
+    if (key == NULL) {
+        return 0;
+    }
+
 #ifndef OQS_PROVIDER_NOATOMIC
     refcnt =
         atomic_fetch_add_explicit(&key->references, 1, memory_order_relaxed) +
@@ -1580,18 +1798,32 @@ int oqsx_key_up_ref(OQSX_KEY *key) {
 int oqsx_key_allocate_keymaterial(OQSX_KEY *key, int include_private) {
     int ret = 0, aux = 0;
 
+    if (key == NULL) {
+        return 1;
+    }
+
     if (key->keytype != KEY_TYPE_CMP_SIG)
         aux = SIZE_OF_UINT32;
 
     if (!key->privkey && include_private) {
         key->privkey = OPENSSL_secure_zalloc(key->privkeylen + aux);
-        ON_ERR_SET_GOTO(!key->privkey, ret, 1, err_alloc);
+        if (!key->privkey) {
+            ret = 1;
+            goto err_alloc;
+        }
     }
     if (!key->pubkey && !include_private) {
         key->pubkey = OPENSSL_secure_zalloc(key->pubkeylen);
-        ON_ERR_SET_GOTO(!key->pubkey, ret, 1, err_alloc);
+        if (!key->pubkey) {
+            ret = 1;
+            goto err_alloc;
+        }
     }
 err_alloc:
+    if (ret && key->privkey) {
+        OPENSSL_secure_clear_free(key->privkey, key->privkeylen + aux);
+        key->privkey = NULL;
+    }
     return ret;
 }
 
@@ -1599,6 +1831,11 @@ int oqsx_key_fromdata(OQSX_KEY *key, const OSSL_PARAM params[],
                       int include_private) {
     const OSSL_PARAM *pp1, *pp2;
 
+    if (key == NULL || params == NULL) {
+        ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
+        return 0;
+    }
+
     OQS_KEY_PRINTF("OQSX Key from data called\n");
     pp1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
     pp2 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
@@ -1616,13 +1853,14 @@ int oqsx_key_fromdata(OQSX_KEY *key, const OSSL_PARAM params[],
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_SIZE);
             return 0;
         }
-        OPENSSL_secure_clear_free(key->privkey, pp1->data_size);
-        key->privkey = OPENSSL_secure_malloc(pp1->data_size);
-        if (key->privkey == NULL) {
+        unsigned char *new_privkey = OPENSSL_secure_malloc(pp1->data_size);
+        if (new_privkey == NULL) {
             ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
             return 0;
         }
-        memcpy(key->privkey, pp1->data, pp1->data_size);
+        memcpy(new_privkey, pp1->data, pp1->data_size);
+        OPENSSL_secure_clear_free(key->privkey, key->privkeylen);
+        key->privkey = new_privkey;
     }
     if (pp2 != NULL) {
         if (pp2->data_type != OSSL_PARAM_OCTET_STRING) {
@@ -1633,18 +1871,24 @@ int oqsx_key_fromdata(OQSX_KEY *key, const OSSL_PARAM params[],
             ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_SIZE);
             return 0;
         }
-        OPENSSL_secure_clear_free(key->pubkey, pp2->data_size);
-        key->pubkey = OPENSSL_secure_malloc(pp2->data_size);
-        if (key->pubkey == NULL) {
+        unsigned char *new_pubkey = OPENSSL_secure_malloc(pp2->data_size);
+        if (new_pubkey == NULL) {
             ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
             return 0;
         }
-        memcpy(key->pubkey, pp2->data, pp2->data_size);
+        memcpy(new_pubkey, pp2->data, pp2->data_size);
+        OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen);
+        key->pubkey = new_pubkey;
     }
     if (!oqsx_key_set_composites(key) ||
         !oqsx_key_recreate_classickey(
-            key, key->privkey != NULL ? KEY_OP_PRIVATE : KEY_OP_PUBLIC))
+            key, key->privkey != NULL ? KEY_OP_PRIVATE : KEY_OP_PUBLIC)) {
+        OPENSSL_secure_clear_free(key->privkey, key->privkeylen);
+        OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen);
+        key->privkey = NULL;
+        key->pubkey = NULL;
         return 0;
+    }
     return 1;
 }
 
@@ -1675,19 +1919,25 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey,
 
     size_t pubkeylen = 0, privkeylen = 0;
 
+    if (ctx == NULL || pubkey == NULL || privkey == NULL) {
+        return NULL;
+    }
+
     if (encode) { // hybrid
         aux = SIZE_OF_UINT32;
     }
 
     if (ctx->keyParam)
         kgctx = EVP_PKEY_CTX_new(ctx->keyParam, NULL);
-    else
+    else if (ctx->evp_info)
         kgctx = EVP_PKEY_CTX_new_id(ctx->evp_info->nid, NULL);
+    else
+        goto errhyb;
     ON_ERR_SET_GOTO(!kgctx, ret, -1, errhyb);
 
     ret2 = EVP_PKEY_keygen_init(kgctx);
     ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, errhyb);
-    if (ctx->evp_info->keytype == EVP_PKEY_RSA) {
+    if (ctx->evp_info && ctx->evp_info->keytype == EVP_PKEY_RSA) {
         if (ctx->evp_info->length_public_key > 270) {
             ret2 = EVP_PKEY_CTX_set_rsa_keygen_bits(kgctx, 3072);
         } else {
@@ -1699,8 +1949,7 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey,
     ret2 = EVP_PKEY_keygen(kgctx, &pkey);
     ON_ERR_SET_GOTO(ret2 <= 0, ret, -2, errhyb);
 
-    if (ctx->evp_info->raw_key_support) {
-        // TODO: If available, use preallocated memory
+    if (ctx->evp_info && ctx->evp_info->raw_key_support) {
         if (ctx->evp_info->nid != NID_ED25519 &&
             ctx->evp_info->nid != NID_ED448) {
             pubkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &pubkey_encoded);
@@ -1720,7 +1969,7 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey,
         ON_ERR_SET_GOTO(ret2 <= 0 ||
                             privkeylen != ctx->evp_info->length_private_key,
                         ret, -4, errhyb);
-    } else {
+    } else if (ctx->evp_info) {
         unsigned char *pubkey_enc = pubkey + aux;
         const unsigned char *pubkey_enc2 = pubkey + aux;
         pubkeylen = i2d_PublicKey(pkey, &pubkey_enc);
@@ -1738,6 +1987,8 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey,
                                        &privkey_enc2, privkeylen);
         ON_ERR_SET_GOTO(!ck2, ret, -14, errhyb);
         EVP_PKEY_free(ck2);
+    } else {
+        goto errhyb;
     }
     if (encode) {
         ENCODE_UINT32(pubkey, pubkeylen);
@@ -1757,12 +2008,15 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey,
     OPENSSL_free(pubkey_encoded);
     return NULL;
 }
-
 /* allocates OQS and classical keys */
 int oqsx_key_gen(OQSX_KEY *key) {
     int ret = 0;
     EVP_PKEY *pkey = NULL;
 
+    if (key == NULL) {
+        return 1;
+    }
+
     if (key->privkey == NULL || key->pubkey == NULL) {
         ret = oqsx_key_allocate_keymaterial(key, 0) ||
               oqsx_key_allocate_keymaterial(key, 1);
@@ -1776,6 +2030,10 @@ int oqsx_key_gen(OQSX_KEY *key) {
     } else if (key->keytype == KEY_TYPE_ECP_HYB_KEM ||
                key->keytype == KEY_TYPE_ECX_HYB_KEM ||
                key->keytype == KEY_TYPE_HYB_SIG) {
+        if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL) {
+            ret = 1;
+            goto err_gen;
+        }
         pkey = oqsx_key_gen_evp_key(key->oqsx_provider_ctx.oqsx_evp_ctx,
                                     key->pubkey, key->privkey, 1);
         ON_ERR_GOTO(pkey == NULL, err_gen);
@@ -1795,13 +2053,24 @@ int oqsx_key_gen(OQSX_KEY *key) {
                 ON_ERR_GOTO(ret, err_gen);
             }
             if (get_oqsname_fromtls(name) == 0) {
+                if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL) {
+                    OPENSSL_free(name);
+                    ret = 1;
+                    goto err_gen;
+                }
                 pkey = oqsx_key_gen_evp_key(key->oqsx_provider_ctx.oqsx_evp_ctx,
                                             key->comp_pubkey[i],
                                             key->comp_privkey[i], 0);
                 OPENSSL_free(name);
                 ON_ERR_GOTO(pkey == NULL, err_gen);
+                EVP_PKEY_free(key->classical_pkey);
                 key->classical_pkey = pkey;
             } else {
+                if (key->oqsx_provider_ctx.oqsx_qs_ctx.sig == NULL) {
+                    OPENSSL_free(name);
+                    ret = 1;
+                    goto err_gen;
+                }
                 ret =
                     OQS_SIG_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.sig,
                                     key->comp_pubkey[i], key->comp_privkey[i]);
@@ -1824,24 +2093,54 @@ int oqsx_key_gen(OQSX_KEY *key) {
     return ret;
 }
 
-int oqsx_key_secbits(OQSX_KEY *key) { return key->bit_security; }
+int oqsx_key_secbits(OQSX_KEY *key) {
+    if (key == NULL) {
+        return 0;
+    }
+    return key->bit_security;
+}
 
 int oqsx_key_maxsize(OQSX_KEY *key) {
+    if (key == NULL) {
+        return 0;
+    }
+
     switch (key->keytype) {
     case KEY_TYPE_KEM:
+        if (key->oqsx_provider_ctx.oqsx_qs_ctx.kem == NULL) {
+            return 0;
+        }
         return key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_shared_secret;
     case KEY_TYPE_ECP_HYB_KEM:
     case KEY_TYPE_ECX_HYB_KEM:
+        if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL ||
+            key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info == NULL ||
+            key->oqsx_provider_ctx.oqsx_qs_ctx.kem == NULL) {
+            return 0;
+        }
         return key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
                    ->kex_length_secret +
                key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_shared_secret;
     case KEY_TYPE_SIG:
+        if (key->oqsx_provider_ctx.oqsx_qs_ctx.sig == NULL) {
+            return 0;
+        }
         return key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature;
     case KEY_TYPE_HYB_SIG:
+        if (key->oqsx_provider_ctx.oqsx_qs_ctx.sig == NULL ||
+            key->oqsx_provider_ctx.oqsx_evp_ctx == NULL ||
+            key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info == NULL) {
+            return 0;
+        }
         return key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature +
                key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->length_signature +
                SIZE_OF_UINT32;
     case KEY_TYPE_CMP_SIG:
+        if (key->oqsx_provider_ctx.oqsx_evp_ctx == NULL ||
+            key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info == NULL ||
+            key->oqsx_provider_ctx.oqsx_qs_ctx.sig == NULL) {
+            return 0;
+        }
         return sizeof(CompositeSignature) +
                key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->length_signature +
                key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature;
@@ -1853,14 +2152,24 @@ int oqsx_key_maxsize(OQSX_KEY *key) {
 }
 
 int oqsx_key_get_oqs_public_key_len(OQSX_KEY *k) {
+    if (k == NULL) {
+        return -1;
+    }
+
     switch (k->keytype) {
     case KEY_TYPE_SIG:
     case KEY_TYPE_KEM:
         return k->pubkeylen;
     case KEY_TYPE_HYB_SIG:
+        if (k->oqsx_provider_ctx.oqsx_qs_ctx.sig == NULL) {
+            return -1;
+        }
         return k->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key;
     case KEY_TYPE_ECX_HYB_KEM:
     case KEY_TYPE_ECP_HYB_KEM:
+        if (k->oqsx_provider_ctx.oqsx_qs_ctx.kem == NULL) {
+            return -1;
+        }
         return k->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key;
     default:
         OQS_KEY_PRINTF2("OQSX_KEY: Unknown key type encountered: %d\n",