int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
                       const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
{
    int ret;
    (void)privKeySz;
    (void)pubKeySz;
    (void)ks;

    if (privKey == NULL || pubKey == NULL) {
        return BAD_FUNC_ARG;
    }

    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
    /* test if RSA key */
    if (ks == RSAk) {
    #ifdef WOLFSSL_SMALL_STACK
        RsaKey* a;
        RsaKey* b = NULL;
    #else
        RsaKey a[1], b[1];
    #endif
        word32 keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
        if (a == NULL)
            return MEMORY_E;
        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
        if (b == NULL) {
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
            return MEMORY_E;
        }
    #endif

        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
            return ret;
        }
        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
            wc_FreeRsaKey(a);
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
            return ret;
        }
        if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
            WOLFSSL_MSG("Checking RSA key pair");
            keyIdx = 0; /* reset to 0 for parsing public key */

            if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
                    pubKeySz)) == 0) {
                /* limit for user RSA crypto because of RsaKey
                 * dereference. */
            #if defined(HAVE_USER_RSA)
                WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
                ret = 1; /* return first RSA cert as match */
            #else
                /* both keys extracted successfully now check n and e
                 * values are the same. This is dereferencing RsaKey */
                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
                    ret = MP_CMP_E;
                }
                else
                    ret = 1;
            #endif
            }
        }
        wc_FreeRsaKey(b);
        wc_FreeRsaKey(a);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
    }
    else
    #endif /* !NO_RSA && !NO_ASN_CRYPT */

    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    if (ks == ECDSAk) {
    #ifdef WOLFSSL_SMALL_STACK
        ecc_key* key_pair;
        byte*    privDer;
    #else
        ecc_key  key_pair[1];
        byte     privDer[MAX_ECC_BYTES];
    #endif
        word32   privSz = MAX_ECC_BYTES;
        word32   keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
        if (key_pair == NULL)
            return MEMORY_E;
        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (privDer == NULL) {
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
            return MEMORY_E;
        }
    #endif

        if ((ret = wc_ecc_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
    #endif
            return ret;
        }

        if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ECC key pair");

            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
                                                                         == 0) {
                wc_ecc_free(key_pair);
                ret = wc_ecc_init(key_pair);
                if (ret == 0) {
                    ret = wc_ecc_import_private_key(privDer,
                                            privSz, pubKey,
                                            pubKeySz, key_pair);
                }

                /* public and private extracted successfully now check if is
                 * a pair and also do sanity checks on key. wc_ecc_check_key
                 * checks that private * base generator equals pubkey */
                if (ret == 0) {
                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
                        ret = 1;
                    }
                }
                ForceZero(privDer, privSz);
            }
        }
        wc_ecc_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
    #endif
    }
    else
    #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */

    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    if (ks == ED25519k) {
    #ifdef WOLFSSL_SMALL_STACK
        ed25519_key* key_pair;
    #else
        ed25519_key  key_pair[1];
    #endif
        word32       keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
                                                          DYNAMIC_TYPE_ED25519);
        if (key_pair == NULL)
            return MEMORY_E;
    #endif

        if ((ret = wc_ed25519_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
    #endif
            return ret;
        }
        if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ED25519 key pair");
            keyIdx = 0;
            if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
                    key_pair)) == 0) {
                /* public and private extracted successfully no check if is
                 * a pair and also do sanity checks on key. wc_ecc_check_key
                 * checks that private * base generator equals pubkey */
                if ((ret = wc_ed25519_check_key(key_pair)) == 0)
                    ret = 1;
            }
        }
        wc_ed25519_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
    #endif
    }
    else
    #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */

    #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
    if (ks == ED448k) {
    #ifdef WOLFSSL_SMALL_STACK
        ed448_key* key_pair = NULL;
    #else
        ed448_key  key_pair[1];
    #endif
        word32     keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
                                                            DYNAMIC_TYPE_ED448);
        if (key_pair == NULL)
            return MEMORY_E;
    #endif

        if ((ret = wc_ed448_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
    #endif
            return ret;
        }
        if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ED448 key pair");
            keyIdx = 0;
            if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
                    key_pair)) == 0) {
                /* public and private extracted successfully no check if is
                 * a pair and also do sanity checks on key. wc_ecc_check_key
                 * checks that private * base generator equals pubkey */
                if ((ret = wc_ed448_check_key(key_pair)) == 0)
                    ret = 1;
            }
        }
        wc_ed448_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
    #endif
    }
    else
    #endif /* HAVE_ED448 && !NO_ASN_CRYPT */
    {
        ret = 0;
    }
    (void)ks;

    return ret;
}
int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
                       const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
{
    int ret;
    (void)privKeySz;
    (void)pubKeySz;
    (void)ks;

    if (privKey == NULL || pubKey == NULL) {
        return BAD_FUNC_ARG;
    }

    #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
     
    if (ks == RSAk) {
    #ifdef WOLFSSL_SMALL_STACK
        RsaKey* a;
        RsaKey* b = NULL;
    #else
        RsaKey a[1], b[1];
    #endif
        word32 keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
        if (a == NULL)
            return MEMORY_E;
        b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
        if (b == NULL) {
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
            return MEMORY_E;
        }
    #endif

        if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
            return ret;
        }
        if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
            wc_FreeRsaKey(a);
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(b, NULL, DYNAMIC_TYPE_RSA);
            XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
            return ret;
        }
        if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
            WOLFSSL_MSG("Checking RSA key pair");
            keyIdx = 0;  

            if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
                    pubKeySz)) == 0) {
                 
            #if defined(HAVE_USER_RSA)
                WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
                ret = 1;  
            #else
                 
                if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
                    mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
                    ret = MP_CMP_E;
                }
                else
                    ret = 1;
            #endif
            }
        }
        wc_FreeRsaKey(b);
        wc_FreeRsaKey(a);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(b, NULL, DYNAMIC_TYPE_RSA);
        XFREE(a, NULL, DYNAMIC_TYPE_RSA);
    #endif
    }
    else
    #endif  

    #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
    if (ks == ECDSAk) {
    #ifdef WOLFSSL_SMALL_STACK
        ecc_key* key_pair;
        byte*    privDer;
    #else
        ecc_key  key_pair[1];
        byte     privDer[MAX_ECC_BYTES];
    #endif
        word32   privSz = MAX_ECC_BYTES;
        word32   keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
        if (key_pair == NULL)
            return MEMORY_E;
        privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (privDer == NULL) {
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
            return MEMORY_E;
        }
    #endif

        if ((ret = wc_ecc_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
    #endif
            return ret;
        }

        if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ECC key pair");

            if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
                                                                         == 0) {
                wc_ecc_free(key_pair);
                ret = wc_ecc_init(key_pair);
                if (ret == 0) {
                    ret = wc_ecc_import_private_key(privDer,
                                            privSz, pubKey,
                                            pubKeySz, key_pair);
                }

                 
                if (ret == 0) {
                    if ((ret = wc_ecc_check_key(key_pair)) == 0) {
                        ret = 1;
                    }
                }
                ForceZero(privDer, privSz);
            }
        }
        wc_ecc_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
    #endif
    }
    else
    #endif  

    #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
    if (ks == ED25519k) {
    #ifdef WOLFSSL_SMALL_STACK
        ed25519_key* key_pair;
    #else
        ed25519_key  key_pair[1];
    #endif
        word32       keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
                                                          DYNAMIC_TYPE_ED25519);
        if (key_pair == NULL)
            return MEMORY_E;
    #endif

        if ((ret = wc_ed25519_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
    #endif
            return ret;
        }
        if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ED25519 key pair");
            keyIdx = 0;
            if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
                    key_pair)) == 0) {
                 
                if ((ret = wc_ed25519_check_key(key_pair)) == 0)
                    ret = 1;
            }
        }
        wc_ed25519_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
    #endif
    }
    else
    #endif  

    #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
    if (ks == ED448k) {
    #ifdef WOLFSSL_SMALL_STACK
        ed448_key* key_pair = NULL;
    #else
        ed448_key  key_pair[1];
    #endif
        word32     keyIdx = 0;

    #ifdef WOLFSSL_SMALL_STACK
        key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL,
                                                            DYNAMIC_TYPE_ED448);
        if (key_pair == NULL)
            return MEMORY_E;
    #endif

        if ((ret = wc_ed448_init(key_pair)) < 0) {
    #ifdef WOLFSSL_SMALL_STACK
            XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
    #endif
            return ret;
        }
        if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
                privKeySz)) == 0) {
            WOLFSSL_MSG("Checking ED448 key pair");
            keyIdx = 0;
            if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
                    key_pair)) == 0) {
                 
                if ((ret = wc_ed448_check_key(key_pair)) == 0)
                    ret = 1;
            }
        }
        wc_ed448_free(key_pair);
    #ifdef WOLFSSL_SMALL_STACK
        XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448);
    #endif
    }
    else
    #endif  
    {
        ret = 0;
    }
    (void)ks;

    return ret;
}